UNPKG

igniteui-angular

Version:

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

536 lines • 44.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { CommonModule } from '@angular/common'; import { Component, ContentChildren, ChangeDetectorRef, EventEmitter, HostBinding, Input, NgModule, Output, QueryList, Renderer2, ViewChildren } 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'; /** @enum {number} */ const ButtonGroupAlignment = { horizontal: 0, vertical: 1, }; export { ButtonGroupAlignment }; ButtonGroupAlignment[ButtonGroupAlignment.horizontal] = 'horizontal'; ButtonGroupAlignment[ButtonGroupAlignment.vertical] = 'vertical'; /** @type {?} */ let 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 }]; * ``` */ export class IgxButtonGroupComponent { /** * @param {?} _cdr * @param {?} _renderer */ constructor(_cdr, _renderer) { this._cdr = _cdr; this._renderer = _renderer; 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++}`; /** * 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(); } /** * A collection containing all buttons inside the button group. * @return {?} */ get buttons() { return [...this.viewButtons.toArray(), ...this.templateButtons.toArray()]; } /** * 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"> * ``` * @param {?} value * @return {?} */ set itemContentCssClass(value) { this._itemContentCssClass = value || this._itemContentCssClass; } /** * Returns the CSS class of the item content of the `IgxButtonGroup`. * ```typescript * \@ViewChild("MyChild") * public buttonG: IgxButtonGroupComponent; * ngAfterViewInit(){ * let buttonSelect = this.buttonG.itemContentCssClass; * } * ``` * @return {?} */ get itemContentCssClass() { return this._itemContentCssClass; } /** * 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> * ``` * @return {?} */ get disabled() { return this._disabled; } /** * @param {?} value * @return {?} */ set disabled(value) { if (this._disabled !== value) { this._disabled = value; if (this.viewButtons && this.templateButtons) { this.buttons.forEach((b) => b.disabled = this._disabled); } } } /** * 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> * ``` * @param {?} value * @return {?} */ set alignment(value) { this._isVertical = value === ButtonGroupAlignment.vertical; } /** * Returns the alignment of the `igx-buttongroup`. * ```typescript * \@ViewChild("MyChild") * public buttonG: IgxButtonGroupComponent; * ngAfterViewInit(){ * let buttonAlignment = this.buttonG.alignment; * } * ``` * @return {?} */ get alignment() { return this._isVertical ? ButtonGroupAlignment.vertical : ButtonGroupAlignment.horizontal; } /** * 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; * } * ``` * @return {?} */ get isVertical() { return this._isVertical; } /** * Gets the selected button/buttons. * ```typescript * \@ViewChild("MyChild") * private buttonG: IgxButtonGroupComponent; * ngAfterViewInit(){ * let selectedButton = this.buttonG.selectedButtons; * } * ``` * @return {?} */ get selectedButtons() { return this.buttons.filter((b, i) => { return this.selectedIndexes.indexOf(i) !== -1; }); } /** * Selects a button by its index. * \@memberOf {\@link IgxButtonGroupComponent} * ```typescript * \@ViewChild("MyChild") * private buttonG: IgxButtonGroupComponent; * ngAfterViewInit(){ * this.buttonG.selectButton(2); * this.cdr.detectChanges(); * } * ``` * @param {?} index * @return {?} */ selectButton(index) { if (index >= this.buttons.length || index < 0) { return; } /** @type {?} */ const button = this.buttons[index]; /** @type {?} */ const buttonElement = button.nativeElement; if (buttonElement.classList.contains('igx-button--disabled')) { return; } 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 }); /** @type {?} */ const 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((b, i) => { if (i !== index && this.selectedIndexes.indexOf(i) !== -1) { this.deselectButton(i); } }); } } /** * Deselects a button by its index. * \@memberOf {\@link IgxButtonGroupComponent} * ```typescript * \@ViewChild("MyChild") * private buttonG: IgxButtonGroupComponent; * ngAfterViewInit(){ * this.buttonG.deselectButton(2); * this.cdr.detectChanges(); * } * ``` * @param {?} index * @return {?} */ deselectButton(index) { if (index >= this.buttons.length || index < 0) { return; } /** @type {?} */ const button = this.buttons[index]; /** @type {?} */ const buttonElement = button.nativeElement; if (buttonElement.classList.contains('igx-button--disabled')) { return; } 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 }); /** @type {?} */ const indexInViewButtons = this.viewButtons.toArray().indexOf(button); if (indexInViewButtons !== -1) { this.values[indexInViewButtons].selected = false; } } /** * @hidden * @return {?} */ ngAfterViewInit() { /** @type {?} */ const initButtons = () => { // Cancel any existing buttonClick subscriptions this.buttonClickNotifier$.next(); this.selectedIndexes.splice(0, this.selectedIndexes.length); // initial configuration this.buttons.forEach((button, index) => { /** @type {?} */ const buttonElement = button.nativeElement; if (this.disabled) { button.disabled = true; } if (!button.disabled && button.selected) { this.selectButton(index); } button.buttonClick.pipe(takeUntil(this.buttonClickNotifier$)).subscribe((ev) => this._clickHandler(ev, index)); this._renderer.addClass(buttonElement, 'igx-button-group__item'); }); }; this.viewButtons.changes.pipe(takeUntil(this.queryListNotifier$)).subscribe(() => initButtons()); this.templateButtons.changes.pipe(takeUntil(this.queryListNotifier$)).subscribe(() => initButtons()); initButtons(); this._cdr.detectChanges(); } /** * @hidden * @return {?} */ ngOnDestroy() { this.buttonClickNotifier$.next(); this.buttonClickNotifier$.complete(); this.queryListNotifier$.next(); this.queryListNotifier$.complete(); } /** * @hidden * @param {?} event * @param {?} i * @return {?} */ _clickHandler(event, i) { if (this.selectedIndexes.indexOf(i) !== -1) { this.deselectButton(i); } else { this.selectButton(i); } } } IgxButtonGroupComponent.decorators = [ { type: Component, args: [{ selector: 'igx-buttongroup', template: "<div class=\"igx-button-group\" role=\"group\" [class.igx-button-group--vertical]=\"isVertical\">\n <span *ngFor=\"let button of values; let i = 'index'\" type=\"button\" igxButton=\"flat\" [selected]=\"button.selected\"\n [attr.data-togglable]=\"button.togglable\" [disabled]=\"disabled || button.disabled\" [igxButtonColor]=\"button.color\"\n [igxButtonBackground]=\"button.bgcolor\" [igxLabel]=\"button.label\" [igxRipple]=\"button.ripple\">\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 </span>\n <ng-content></ng-content>\n</div>\n" }] } ]; /** @nocollapse */ IgxButtonGroupComponent.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: Renderer2 } ]; IgxButtonGroupComponent.propDecorators = { viewButtons: [{ type: ViewChildren, args: [IgxButtonDirective,] }], templateButtons: [{ type: ContentChildren, args: [IgxButtonDirective,] }], id: [{ type: HostBinding, args: ['attr.id',] }, { type: Input }], itemContentCssClass: [{ type: Input }], multiSelection: [{ type: Input }], values: [{ type: Input }], disabled: [{ type: Input }], alignment: [{ type: Input }], onSelect: [{ type: Output }], onUnselect: [{ type: Output }] }; if (false) { /** * @type {?} * @private */ IgxButtonGroupComponent.prototype._disabled; /** * @type {?} * @protected */ IgxButtonGroupComponent.prototype.buttonClickNotifier$; /** * @type {?} * @protected */ IgxButtonGroupComponent.prototype.queryListNotifier$; /** * @type {?} * @private */ IgxButtonGroupComponent.prototype.viewButtons; /** * @type {?} * @private */ IgxButtonGroupComponent.prototype.templateButtons; /** * 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"> * ``` * @type {?} */ IgxButtonGroupComponent.prototype.id; /** * An \@Input property that enables selecting multiple buttons. By default, multi-selection is false. * ```html * <igx-buttongroup [multiSelection]="false" [alignment]="alignment"></igx-buttongroup> * ``` * @type {?} */ IgxButtonGroupComponent.prototype.multiSelection; /** * An \@Input property that allows setting the buttons in the button group. * ```typescript * public ngOnInit() { * this.cities = [ * new Button({ * label: "Sofia" * }), * new Button({ * label: "London" * }), * new Button({ * label: "New York", * selected: true * }), * new Button({ * label: "Tokyo" * }) * ]; * } * //.. * ``` * ```html * <igx-buttongroup [multiSelection]="false" [values]="cities"></igx-buttongroup> * ``` * @type {?} */ IgxButtonGroupComponent.prototype.values; /** * @hidden * @type {?} */ IgxButtonGroupComponent.prototype.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> * ``` * @type {?} */ IgxButtonGroupComponent.prototype.onSelect; /** * 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> * ``` * @type {?} */ IgxButtonGroupComponent.prototype.onUnselect; /** * @type {?} * @private */ IgxButtonGroupComponent.prototype._isVertical; /** * @type {?} * @private */ IgxButtonGroupComponent.prototype._itemContentCssClass; /** * @type {?} * @private */ IgxButtonGroupComponent.prototype._cdr; /** * @type {?} * @private */ IgxButtonGroupComponent.prototype._renderer; } /** * @record */ export function IButtonGroupEventArgs() { } if (false) { /** @type {?} */ IButtonGroupEventArgs.prototype.button; /** @type {?} */ IButtonGroupEventArgs.prototype.index; } /** * @hidden */ export class IgxButtonGroupModule { } IgxButtonGroupModule.decorators = [ { type: NgModule, args: [{ declarations: [IgxButtonGroupComponent], exports: [IgxButtonGroupComponent], imports: [IgxButtonModule, CommonModule, IgxRippleModule, IgxIconModule] },] } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uR3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9idXR0b25Hcm91cC9idXR0b25Hcm91cC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBRUgsU0FBUyxFQUNULGVBQWUsRUFDZixpQkFBaUIsRUFDakIsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFFZixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxlQUFlLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM1RixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztJQUVSLGFBQVUsRUFBRSxXQUFROzs7Ozs7SUFDbkQsT0FBTyxHQUFHLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJCZixNQUFNLE9BQU8sdUJBQXVCOzs7OztJQW9NaEMsWUFBb0IsSUFBdUIsRUFBVSxTQUFvQjtRQUFyRCxTQUFJLEdBQUosSUFBSSxDQUFtQjtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFuTWpFLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDaEIseUJBQW9CLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUM5Qyx1QkFBa0IsR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDOzs7Ozs7O1FBb0IvQyxPQUFFLEdBQUcsbUJBQW1CLE9BQU8sRUFBRSxFQUFF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TmhDLFFBQVEsU0FBQztnQkFDTixZQUFZLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQztnQkFDdkMsT0FBTyxFQUFFLENBQUMsdUJBQXVCLENBQUM7Z0JBQ2xDLE9BQU8sRUFBRSxDQUFDLGVBQWUsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLGFBQWEsQ0FBQzthQUMzRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSW5wdXQsXG4gICAgTmdNb2R1bGUsXG4gICAgT3V0cHV0LFxuICAgIFF1ZXJ5TGlzdCxcbiAgICBSZW5kZXJlcjIsXG4gICAgVmlld0NoaWxkcmVuLFxuICAgIE9uRGVzdHJveVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IElneEJ1dHRvbkRpcmVjdGl2ZSwgSWd4QnV0dG9uTW9kdWxlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9idXR0b24vYnV0dG9uLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJZ3hSaXBwbGVNb2R1bGUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3JpcHBsZS9yaXBwbGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEljb25Nb2R1bGUgfSBmcm9tICcuLi9pY29uL2luZGV4JztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuZXhwb3J0IGVudW0gQnV0dG9uR3JvdXBBbGlnbm1lbnQgeyBob3Jpem9udGFsLCB2ZXJ0aWNhbCB9XG5sZXQgTkVYVF9JRCA9IDA7XG5cbi8qKlxuICogKipJZ25pdGUgVUkgZm9yIEFuZ3VsYXIgQnV0dG9uIEdyb3VwKiogLVxuICogW0RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LmluZnJhZ2lzdGljcy5jb20vcHJvZHVjdHMvaWduaXRlLXVpLWFuZ3VsYXIvYW5ndWxhci9jb21wb25lbnRzL2J1dHRvbmdyb3VwLmh0bWwpXG4gKlxuICogVGhlIElnbml0ZSBVSSBCdXR0b24gR3JvdXAgZGlzcGxheXMgYSBncm91cCBvZiBidXR0b25zIGVpdGhlciB2ZXJ0aWNhbGx5IG9yIGhvcml6b250YWxseS4gIFRoZSBncm91cCBzdXBwb3J0c1xuICogc2luZ2xlLCBtdWx0aXBsZSBhbmQgdG9nZ2xlIHNlbGVjdGlvbi5cbiAqXG4gKiBFeGFtcGxlOlxuICogYGBgaHRtbFxuICogPGlneC1idXR0b25ncm91cCBtdWx0aVNlbGVjdGlvbj1cInRydWVcIiBbdmFsdWVzXT1cImZvbnRPcHRpb25zXCI+XG4gKiA8L2lneC1idXR0b25ncm91cD5cbiAqIGBgYFxuICogVGhlIGBmb250T3B0aW9uc2AgdmFsdWUgc2hvd24gYWJvdmUgaXMgZGVmaW5lZCBhczpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRoaXMuZm9udE9wdGlvbnMgPSBbXG4gKiAgIHsgaWNvbjogJ2Zvcm1hdF9ib2xkJywgc2VsZWN0ZWQ6IGZhbHNlIH0sXG4gKiAgIHsgaWNvbjogJ2Zvcm1hdF9pdGFsaWMnLCBzZWxlY3RlZDogZmFsc2UgfSxcbiAqICAgeyBpY29uOiAnZm9ybWF0X3VuZGVybGluZWQnLCBzZWxlY3RlZDogZmFsc2UgfV07XG4gKiBgYGBcbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdpZ3gtYnV0dG9uZ3JvdXAnLFxuICAgIHRlbXBsYXRlVXJsOiAnYnV0dG9uZ3JvdXAtY29udGVudC5jb21wb25lbnQuaHRtbCdcbn0pXG5cbmV4cG9ydCBjbGFzcyBJZ3hCdXR0b25Hcm91cENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gICAgcHJpdmF0ZSBfZGlzYWJsZWQgPSBmYWxzZTtcbiAgICBwcm90ZWN0ZWQgYnV0dG9uQ2xpY2tOb3RpZmllciQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgIHByb3RlY3RlZCBxdWVyeUxpc3ROb3RpZmllciQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgQFZpZXdDaGlsZHJlbihJZ3hCdXR0b25EaXJlY3RpdmUpIHByaXZhdGUgdmlld0J1dHRvbnM6IFF1ZXJ5TGlzdDxJZ3hCdXR0b25EaXJlY3RpdmU+O1xuICAgIEBDb250ZW50Q2hpbGRyZW4oSWd4QnV0dG9uRGlyZWN0aXZlKSBwcml2YXRlIHRlbXBsYXRlQnV0dG9uczogUXVlcnlMaXN0PElneEJ1dHRvbkRpcmVjdGl2ZT47XG5cbiAgICAvKipcbiAgICAgKiBBIGNvbGxlY3Rpb24gY29udGFpbmluZyBhbGwgYnV0dG9ucyBpbnNpZGUgdGhlIGJ1dHRvbiBncm91cC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGJ1dHRvbnMoKTogSWd4QnV0dG9uRGlyZWN0aXZlW10ge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMudmlld0J1dHRvbnMudG9BcnJheSgpLCAuLi50aGlzLnRlbXBsYXRlQnV0dG9ucy50b0FycmF5KCldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgdGhlIHZhbHVlIG9mIHRoZSBgaWRgIGF0dHJpYnV0ZS4gSWYgbm90IHNldCBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiAgPGlneC1idXR0b25ncm91cCBbaWRdPVwiJ2lneC1kaWFsb2ctNTYnXCIgW211bHRpU2VsZWN0aW9uXT1cIiFtdWx0aVwiIFt2YWx1ZXNdPVwiYWxpZ25PcHRpb25zXCI+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmlkJylcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpZCA9IGBpZ3gtYnV0dG9uZ3JvdXAtJHtORVhUX0lEKyt9YDtcblxuICAgIC8qKlxuICAgICAqIEFsbG93cyB5b3UgdG8gc2V0IGEgc3R5bGUgdXNpbmcgdGhlIGBpdGVtQ29udGVudENzc0NsYXNzYCBpbnB1dC5cbiAgICAgKiBUaGUgdmFsdWUgc2hvdWxkIGJlIHRoZSBDU1MgY2xhc3MgbmFtZSB0aGF0IHdpbGwgYmUgYXBwbGllZCB0byB0aGUgYnV0dG9uIGdyb3VwLlxuICAgICAqYGBgdHlwZXNjcmlwdFxuICAgICAqcHVibGljIHN0eWxlMSA9IFwic3R5bGVDbGFzc1wiO1xuICAgICAqIC8vLi5cbiAgICAgKmBgYFxuICAgICAqIGBgYGh0bWxcbiAgICAgKjxpZ3gtYnV0dG9uZ3JvdXAgW2l0ZW1Db250ZW50Q3NzQ2xhc3NdPVwic3R5bGUxXCIgW211bHRpU2VsZWN0aW9uXT1cIiFtdWx0aVwiIFt2YWx1ZXNdPVwiYWxpZ25PcHRpb25zXCI+XG4gICAgICpgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKSBzZXQgaXRlbUNvbnRlbnRDc3NDbGFzcyh2YWx1ZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2l0ZW1Db250ZW50Q3NzQ2xhc3MgPSB2YWx1ZSB8fCB0aGlzLl9pdGVtQ29udGVudENzc0NsYXNzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIENTUyBjbGFzcyBvZiB0aGUgaXRlbSBjb250ZW50IG9mIHRoZSBgSWd4QnV0dG9uR3JvdXBgLlxuICAgICAqYGBgdHlwZXNjcmlwdFxuICAgICAqQFZpZXdDaGlsZChcIk15Q2hpbGRcIilcbiAgICAgKnB1YmxpYyBidXR0b25HOiBJZ3hCdXR0b25Hcm91cENvbXBvbmVudDtcbiAgICAgKm5nQWZ0ZXJWaWV3SW5pdCgpe1xuICAgICAqICAgbGV0IGJ1dHRvblNlbGVjdCA9IHRoaXMuYnV0dG9uRy5pdGVtQ29udGVudENzc0NsYXNzO1xuICAgICAqfVxuICAgICAqYGBgXG4gICAgICovXG4gICAgZ2V0IGl0ZW1Db250ZW50Q3NzQ2xhc3MoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZW1Db250ZW50Q3NzQ2xhc3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW4gQElucHV0IHByb3BlcnR5IHRoYXQgZW5hYmxlcyBzZWxlY3RpbmcgbXVsdGlwbGUgYnV0dG9ucy4gQnkgZGVmYXVsdCwgbXVsdGktc2VsZWN0aW9uIGlzIGZhbHNlLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWJ1dHRvbmdyb3VwIFttdWx0aVNlbGVjdGlvbl09XCJmYWxzZVwiIFthbGlnbm1lbnRdPVwiYWxpZ25tZW50XCI+PC9pZ3gtYnV0dG9uZ3JvdXA+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIG11bHRpU2VsZWN0aW9uID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQW4gQElucHV0IHByb3BlcnR5IHRoYXQgYWxsb3dzIHNldHRpbmcgdGhlIGJ1dHRvbnMgaW4gdGhlIGJ1dHRvbiBncm91cC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICAgKiAgICAgIHRoaXMuY2l0aWVzID0gW1xuICAgICAqICAgICAgICBuZXcgQnV0dG9uKHtcbiAgICAgKiAgICAgICAgICBsYWJlbDogXCJTb2ZpYVwiXG4gICAgICogICAgICB9KSxcbiAgICAgKiAgICAgICAgbmV3IEJ1dHRvbih7XG4gICAgICogICAgICAgICAgbGFiZWw6IFwiTG9uZG9uXCJcbiAgICAgKiAgICAgIH0pLFxuICAgICAqICAgICAgICBuZXcgQnV0dG9uKHtcbiAgICAgKiAgICAgICAgICBsYWJlbDogXCJOZXcgWW9ya1wiLFxuICAgICAqICAgICAgICAgIHNlbGVjdGVkOiB0cnVlXG4gICAgICogICAgICB9KSxcbiAgICAgKiAgICAgICAgbmV3IEJ1dHRvbih7XG4gICAgICogICAgICAgICAgbGFiZWw6IFwiVG9reW9cIlxuICAgICAqICAgICAgfSlcbiAgICAgKiAgXTtcbiAgICAgKiAgfVxuICAgICAqICAvLy4uXG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqICA8aWd4LWJ1dHRvbmdyb3VwIFttdWx0aVNlbGVjdGlvbl09XCJmYWxzZVwiIFt2YWx1ZXNdPVwiY2l0aWVzXCI+PC9pZ3gtYnV0dG9uZ3JvdXA+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHZhbHVlczogYW55O1xuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IGFsbG93cyB5b3UgdG8gZGlzYWJsZSB0aGUgYGlneC1idXR0b25ncm91cGAgY29tcG9uZW50LiBCeSBkZWZhdWx0IGl0J3MgZmFsc2UuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtYnV0dG9uZ3JvdXAgW2Rpc2FibGVkXT1cInRydWVcIiBbbXVsdGlTZWxlY3Rpb25dPVwibXVsdGlcIiBbdmFsdWVzXT1cImZvbnRPcHRpb25zXCI+PC9pZ3gtYnV0dG9uZ3JvdXA+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGlzYWJsZWQ7XG4gICAgfVxuICAgIHB1YmxpYyBzZXQgZGlzYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHRoaXMuX2Rpc2FibGVkICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fZGlzYWJsZWQgPSB2YWx1ZTtcblxuICAgICAgICAgICAgaWYgKHRoaXMudmlld0J1dHRvbnMgJiYgdGhpcy50ZW1wbGF0ZUJ1dHRvbnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmJ1dHRvbnMuZm9yRWFjaCgoYikgPT4gYi5kaXNhYmxlZCA9IHRoaXMuX2Rpc2FibGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2VsZWN0ZWRJbmRleGVzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogQWxsb3dzIHlvdSB0byBzZXQgdGhlIGJ1dHRvbiBncm91cCBhbGlnbm1lbnQuXG4gICAgICogQXZhaWxhYmxlIG9wdGlvbnMgYXJlIGBCdXR0b25Hcm91cEFsaWdubWVudC5ob3Jpem9udGFsYCAoZGVmYXVsdCkgYW5kIGBCdXR0b25Hcm91cEFsaWdubWVudC52ZXJ0aWNhbGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqcHVibGljIGFsaWdubWVudCA9IEJ1dHRvbkdyb3VwQWxpZ25tZW50LnZlcnRpY2FsO1xuICAgICAqIC8vLi5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICo8aWd4LWJ1dHRvbmdyb3VwIFttdWx0aVNlbGVjdGlvbl09XCJmYWxzZVwiIFt2YWx1ZXNdPVwiY2l0aWVzXCIgW2FsaWdubWVudF09XCJhbGlnbm1lbnRcIj48L2lneC1idXR0b25ncm91cD5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKSBzZXQgYWxpZ25tZW50KHZhbHVlOiBCdXR0b25Hcm91cEFsaWdubWVudCkge1xuICAgICAgICB0aGlzLl9pc1ZlcnRpY2FsID0gdmFsdWUgPT09IEJ1dHRvbkdyb3VwQWxpZ25tZW50LnZlcnRpY2FsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBhbGlnbm1lbnQgb2YgdGhlIGBpZ3gtYnV0dG9uZ3JvdXBgLlxuICAgICAqYGBgdHlwZXNjcmlwdFxuICAgICAqQFZpZXdDaGlsZChcIk15Q2hpbGRcIilcbiAgICAgKnB1YmxpYyBidXR0b25HOiBJZ3hCdXR0b25Hcm91cENvbXBvbmVudDtcbiAgICAgKm5nQWZ0ZXJWaWV3SW5pdCgpe1xuICAgICAqICAgIGxldCBidXR0b25BbGlnbm1lbnQgPSB0aGlzLmJ1dHRvbkcuYWxpZ25tZW50O1xuICAgICAqfVxuICAgICAqYGBgXG4gICAgICovXG4gICAgZ2V0IGFsaWdubWVudCgpOiBCdXR0b25Hcm91cEFsaWdubWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1ZlcnRpY2FsID8gQnV0dG9uR3JvdXBBbGlnbm1lbnQudmVydGljYWwgOiBCdXR0b25Hcm91cEFsaWdubWVudC5ob3Jpem9udGFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFuIEBPdXB1dCBwcm9wZXJ0eSB0aGF0IGVtaXRzIGFuIGV2ZW50IHdoZW4gYSBidXR0b24gaXMgc2VsZWN0ZWQuXG4gICAgICpgYGB0eXBlc2NyaXB0XG4gICAgICpAVmlld0NoaWxkKFwidG9hc3RcIilcbiAgICAgKnByaXZhdGUgdG9hc3Q6IElneFRvYXN0Q29tcG9uZW50O1xuICAgICAqcHVibGljIG9uU2VsZWN0KGJ1dHRvbmdyb3VwKXtcbiAgICAgKiAgICB0aGlzLnRvYXN0LnNob3coKVxuICAgICAqfVxuICAgICAqIC8vLi4uXG4gICAgICpgYGBcbiAgICAgKmBgYGh0bWxcbiAgICAgKiA8aWd4LWJ1dHRvbmdyb3VwICNNeUNoaWxkIFttdWx0aVNlbGVjdGlvbl09XCIhbXVsdGlcIiAob25TZWxlY3QpPVwib25TZWxlY3QoJGV2ZW50KVwiPjwvaWd4LWJ1dHRvbmdyb3VwPlxuICAgICAqPGlneC10b2FzdCAjdG9hc3QgbWVzc2FnZT1cIllvdSBoYXZlIG1hZGUgYSBzZWxlY3Rpb24hXCI+PC9pZ3gtdG9hc3Q+XG4gICAgICpgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIG9uU2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcjxJQnV0dG9uR3JvdXBFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBBbiBAT3VwdXQgcHJvcGVydHkgdGhhdCBlbWl0cyBhbiBldmVudCB3aGVuIGEgYnV0dG9uIGlzIGRlc2VsZWN0ZWQuXG4gICAgICpgYGB0eXBlc2NyaXB0XG4gICAgICpAVmlld0NoaWxkKFwidG9hc3RcIilcbiAgICAgKnByaXZhdGUgdG9hc3Q6IElneFRvYXN0Q29tcG9uZW50O1xuICAgICAqcHVibGljIG9uVW5zZWxlY3QoYnV0dG9uZ3JvdXApe1xuICAgICAqICAgIHRoaXMudG9hc3Quc2hvdygpXG4gICAgICp9XG4gICAgICogLy8uLi5cbiAgICAgKmBgYFxuICAgICAqYGBgaHRtbFxuICAgICAqIGlneC1idXR0b25ncm91cCAjTXlDaGlsZCBbbXVsdGlTZWxlY3Rpb25dPVwibXVsdGlcIiAob25VbnNlbGVjdCk9XCJvblVuc2VsZWN0KCRldmVudClcIj48L2lneC1idXR0b25ncm91cD5cbiAgICAgKjxpZ3gtdG9hc3QgI3RvYXN0IG1lc3NhZ2U9XCJZb3UgaGF2ZSBkZXNlbGVjdGVkIGEgYnV0dG9uIVwiPjwvaWd4LXRvYXN0PlxuICAgICAqYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvblVuc2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcjxJQnV0dG9uR3JvdXBFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGBpZ3gtYnV0dG9uZ3JvdXBgIGFsaWdubWVudCBpcyB2ZXJ0aWNhbC5cbiAgICAgKiBOb3RlIHRoYXQgaW4gb3JkZXIgZm9yIHRoZSBhY2Nlc3NvciB0byB3b3JrIGNvcnJlY3RseSB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIHNldCBleHBsaWNpdGx5LlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWJ1dHRvbmdyb3VwICNNeUNoaWxkIFthbGlnbm1lbnRdPVwiYWxpZ25tZW50XCIgW3ZhbHVlc109XCJhbGlnbk9wdGlvbnNcIj5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8uLi5cbiAgICAgKkBWaWV3Q2hpbGQoXCJNeUNoaWxkXCIpXG4gICAgICpwcml2YXRlIGJ1dHRvbkc6IElneEJ1dHRvbkdyb3VwQ29tcG9uZW50O1xuICAgICAqbmdBZnRlclZpZXdJbml0KCl7XG4gICAgICogICAgbGV0IG9yaWVudGF0aW9uID0gdGhpcy5idXR0b25HLmlzVmVydGljYWw7XG4gICAgICp9XG4gICAgICpgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGlzVmVydGljYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1ZlcnRpY2FsO1xuICAgIH1cbiAgICBwcml2YXRlIF9pc1ZlcnRpY2FsOiBib29sZWFuO1xuICAgIHByaXZhdGUgX2l0ZW1Db250ZW50Q3NzQ2xhc3M6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX2NkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIpIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzZWxlY3RlZCBidXR0b24vYnV0dG9ucy5cbiAgICAgKmBgYHR5cGVzY3JpcHRcbiAgICAgKkBWaWV3Q2hpbGQoXCJNeUNoaWxkXCIpXG4gICAgICpwcml2YXRlIGJ1dHRvbkc6IElneEJ1dHRvbkdyb3VwQ29tcG9uZW50O1xuICAgICAqbmdBZnRlclZpZXdJbml0KCl7XG4gICAgICogICAgbGV0IHNlbGVjdGVkQnV0dG9uID0gdGhpcy5idXR0b25HLnNlbGVjdGVkQnV0dG9ucztcbiAgICAgKn1cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIGdldCBzZWxlY3RlZEJ1dHRvbnMoKTogSWd4QnV0dG9uRGlyZWN0aXZlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5idXR0b25zLmZpbHRlcigoYiwgaSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJbmRleGVzLmluZGV4T2YoaSkgIT09IC0xO1xuICAgICAgICB9KTtcblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbGVjdHMgYSBidXR0b24gYnkgaXRzIGluZGV4LlxuICAgICAqIEBtZW1iZXJPZiB7QGxpbmsgSWd4QnV0dG9uR3JvdXBDb21wb25lbnR9XG4gICAgICpgYGB0eXBlc2NyaXB0XG4gICAgICpAVmlld0NoaWxkKFwiTXlDaGlsZFwiKVxuICAgICAqcHJpdmF0ZSBidXR0b25HOiBJZ3hCdXR0b25Hcm91cENvbXBvbmVudDtcbiAgICAgKm5nQWZ0ZXJWaWV3SW5pdCgpe1xuICAgICAqICAgIHRoaXMuYnV0dG9uRy5zZWxlY3RCdXR0b24oMik7XG4gICAgICogICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAqfVxuICAgICAqYGBgXG4gICAgICovXG4gICAgcHVibGljIHNlbGVjdEJ1dHRvbihpbmRleDogbnVtYmVyKSB7XG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLmJ1dHRvbnMubGVuZ3RoIHx8IGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnV0dG9uID0gdGhpcy5idXR0b25zW2luZGV4XTtcbiAgICAgICAgY29uc3QgYnV0dG9uRWxlbWVudCA9IGJ1dHRvbi5uYXRpdmVFbGVtZW50O1xuXG4gICAgICAgIGlmIChidXR0b25FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnaWd4LWJ1dHRvbi0tZGlzYWJsZWQnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ZXMucHVzaChpbmRleCk7XG4gICAgICAgIGJ1dHRvbi5zZWxlY3RlZCA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKGJ1dHRvbkVsZW1lbnQsICdhcmlhLXByZXNzZWQnLCAndHJ1ZScpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyhidXR0b25FbGVtZW50LCAnaWd4LWJ1dHRvbi1ncm91cF9faXRlbS0tc2VsZWN0ZWQnKTtcblxuICAgICAgICB0aGlzLm9uU2VsZWN0LmVtaXQoeyBidXR0b246IGJ1dHRvbiwgaW5kZXg6IGluZGV4IH0pO1xuXG4gICAgICAgIGNvbnN0IGluZGV4SW5WaWV3QnV0dG9ucyA9IHRoaXMudmlld0J1dHRvbnMudG9BcnJheSgpLmluZGV4T2YoYnV0dG9uKTtcbiAgICAgICAgaWYgKGluZGV4SW5WaWV3QnV0dG9ucyAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWVzW2luZGV4SW5WaWV3QnV0dG9uc10uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZGVzZWxlY3Qgb3RoZXIgYnV0dG9ucyBpZiBtdWx0aVNlbGVjdGlvbiBpcyBub3QgZW5hYmxlZFxuICAgICAgICBpZiAoIXRoaXMubXVsdGlTZWxlY3Rpb24gJiYgdGhpcy5zZWxlY3RlZEluZGV4ZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhpcy5idXR0b25zLmZvckVhY2goKGIsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaSAhPT0gaW5kZXggJiYgdGhpcy5zZWxlY3RlZEluZGV4ZXMuaW5kZXhPZihpKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXNlbGVjdEJ1dHRvbihpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlc2VsZWN0cyBhIGJ1dHRvbiBieSBpdHMgaW5kZXguXG4gICAgICogQG1lbWJlck9mIHtAbGluayBJZ3hCdXR0b25Hcm91cENvbXBvbmVudH1cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICpAVmlld0NoaWxkKFwiTXlDaGlsZFwiKVxuICAgICAqcHJpdmF0ZSBidXR0b25HOiBJZ3hCdXR0b25Hcm91cENvbXBvbmVudDtcbiAgICAgKm5nQWZ0ZXJWaWV3SW5pdCgpe1xuICAgICAqICAgIHRoaXMuYnV0dG9uRy5kZXNlbGVjdEJ1dHRvbigyKTtcbiAgICAgKiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICp9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGRlc2VsZWN0QnV0dG9uKGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKGluZGV4ID49IHRoaXMuYnV0dG9ucy5sZW5ndGggfHwgaW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBidXR0b24gPSB0aGlzLmJ1dHRvbnNbaW5kZXhdO1xuICAgICAgICBjb25zdCBidXR0b25FbGVtZW50ID0gYnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgaWYgKGJ1dHRvbkVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdpZ3gtYnV0dG9uLS1kaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNlbGVjdGVkSW5kZXhlcy5zcGxpY2UodGhpcy5zZWxlY3RlZEluZGV4ZXMuaW5kZXhPZihpbmRleCksIDEpO1xuICAgICAgICBidXR0b24uc2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRBdHRyaWJ1dGUoYnV0dG9uRWxlbWVudCwgJ2FyaWEtcHJlc3NlZCcsICdmYWxzZScpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5yZW1vdmVDbGFzcyhidXR0b25FbGVtZW50LCAnaWd4LWJ1dHRvbi1ncm91cF9faXRlbS0tc2VsZWN0ZWQnKTtcblxuICAgICAgICB0aGlzLm9uVW5zZWxlY3QuZW1pdCh7IGJ1dHRvbjogYnV0dG9uLCBpbmRleDogaW5kZXggfSk7XG5cbiAgICAgICAgY29uc3QgaW5kZXhJblZpZXdCdXR0b25zID0gdGhpcy52aWV3QnV0dG9ucy50b0FycmF5KCkuaW5kZXhPZihidXR0b24pO1xuICAgICAgICBpZiAoaW5kZXhJblZpZXdCdXR0b25zICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZXNbaW5kZXhJblZpZXdCdXR0b25zXS5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIGNvbnN0IGluaXRCdXR0b25zID0gKCkgPT4ge1xuICAgICAgICAgICAgLy8gQ2FuY2VsIGFueSBleGlzdGluZyBidXR0b25DbGljayBzdWJzY3JpcHRpb25zXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbkNsaWNrTm90aWZpZXIkLm5leHQoKTtcblxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ZXMuc3BsaWNlKDAsIHRoaXMuc2VsZWN0ZWRJbmRleGVzLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIC8vIGluaXRpYWwgY29uZmlndXJhdGlvblxuICAgICAgICAgICAgdGhpcy5idXR0b25zLmZvckVhY2goKGJ1dHRvbiwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBidXR0b25FbGVtZW50ID0gYnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICBidXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghYnV0dG9uLmRpc2FibGVkICYmIGJ1dHRvbi5zZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEJ1dHRvbihpbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnV0dG9uLmJ1dHRvbkNsaWNrLnBpcGUodGFrZVVudGlsKHRoaXMuYnV0dG9uQ2xpY2tOb3RpZmllciQpKS5zdWJzY3JpYmUoKGV2KSA9PiB0aGlzLl9jbGlja0hhbmRsZXIoZXYsIGluZGV4KSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVuZGVyZXIuYWRkQ2xhc3MoYnV0dG9uRWxlbWVudCwgJ2lneC1idXR0b24tZ3JvdXBfX2l0ZW0nKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMudmlld0J1dHRvbnMuY2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLnF1ZXJ5TGlzdE5vdGlmaWVyJCkpLnN1YnNjcmliZSgoKSA9PiBpbml0QnV0dG9ucygpKTtcbiAgICAgICAgdGhpcy50ZW1wbGF0ZUJ1dHRvbnMuY2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLnF1ZXJ5TGlzdE5vdGlmaWVyJCkpLnN1YnNjcmliZSgoKSA9PiBpbml0QnV0dG9ucygpKTtcbiAgICAgICAgaW5pdEJ1dHRvbnMoKTtcblxuICAgICAgICB0aGlzLl9jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuYnV0dG9uQ2xpY2tOb3RpZmllciQubmV4dCgpO1xuICAgICAgICB0aGlzLmJ1dHRvbkNsaWNrTm90aWZpZXIkLmNvbXBsZXRlKCk7XG5cbiAgICAgICAgdGhpcy5xdWVyeUxpc3ROb3RpZmllciQubmV4dCgpO1xuICAgICAgICB0aGlzLnF1ZXJ5TGlzdE5vdGlmaWVyJC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBfY2xpY2tIYW5kbGVyKGV2ZW50LCBpKSB7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkSW5kZXhlcy5pbmRleE9mKGkpICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5kZXNlbGVjdEJ1dHRvbihpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0QnV0dG9uKGkpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElCdXR0b25Hcm91cEV2ZW50QXJncyB7XG4gICAgYnV0dG9uOiBJZ3hCdXR0b25EaXJlY3RpdmU7XG4gICAgaW5kZXg6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbkBOZ01vZHVsZSh7XG4gICAgZGVjbGFyYXRpb25zOiBbSWd4QnV0dG9uR3JvdXBDb21wb25lbnRdLFxuICAgIGV4cG9ydHM6IFtJZ3hCdXR0b25Hcm91cENvbXBvbmVudF0sXG4gICAgaW1wb3J0czogW0lneEJ1dHRvbk1vZHVsZSwgQ29tbW9uTW9kdWxlLCBJZ3hSaXBwbGVNb2R1bGUsIElneEljb25Nb2R1bGVdXG59KVxuXG5leHBvcnQgY2xhc3MgSWd4QnV0dG9uR3JvdXBNb2R1bGUge1xufVxuIl19