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