@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
466 lines • 45.5 kB
JavaScript
var IgxListComponent_1;
import { __decorate, __metadata, __param } from "tslib";
import { CommonModule } from '@angular/common';
import { Component, ContentChild, ContentChildren, ElementRef, EventEmitter, forwardRef, HostBinding, Input, NgModule, Output, QueryList, TemplateRef, ViewChild, Optional, Inject, Directive } from '@angular/core';
import { IgxRippleModule } from '../directives/ripple/ripple.directive';
import { IgxListItemComponent } from './list-item.component';
import { IgxListBaseDirective, IgxDataLoadingTemplateDirective, IgxEmptyListTemplateDirective, IgxListItemLeftPanningTemplateDirective, IgxListItemRightPanningTemplateDirective } from './list.common';
import { DisplayDensityToken, DisplayDensity } from '../core/density';
let NEXT_ID = 0;
/**
* **Ignite UI for Angular List** -
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/list.html)
*
* The Ignite UI List displays rows of items and supports one or more header items as well as search and filtering
* of list items. Each list item is completely templateable and will support any valid HTML or Angular component.
*
* Example:
* ```html
* <igx-list>
* <igx-list-item isHeader="true">Contacts</igx-list-item>
* <igx-list-item *ngFor="let contact of contacts">
* <span class="name">{{ contact.name }}</span>
* <span class="phone">{{ contact.phone }}</span>
* </igx-list-item>
* </igx-list>
* ```
*/
/**
* igxListThumbnail is container for the List media
* Use it to wrap anything you want to be used as a thumbnail.
*/
let IgxListThumbnailDirective = class IgxListThumbnailDirective {
};
IgxListThumbnailDirective = __decorate([
Directive({
// tslint:disable-next-line:directive-selector
selector: '[igxListThumbnail]'
})
], IgxListThumbnailDirective);
export { IgxListThumbnailDirective };
/**
* igxListAction is container for the List action
* Use it to wrap anything you want to be used as a list action: icon, checkbox...
*/
let IgxListActionDirective = class IgxListActionDirective {
};
IgxListActionDirective = __decorate([
Directive({
// tslint:disable-next-line:directive-selector
selector: '[igxListAction]'
})
], IgxListActionDirective);
export { IgxListActionDirective };
/**
* igxListLine is container for the List text content
* Use it to wrap anything you want to be used as a plane text.
*/
let IgxListLineDirective = class IgxListLineDirective {
};
IgxListLineDirective = __decorate([
Directive({
// tslint:disable-next-line:directive-selector
selector: '[igxListLine]'
})
], IgxListLineDirective);
export { IgxListLineDirective };
/**
* igxListLineTitle is a directive that add class to the target element
* Use it to make anything to look like list Title.
*/
let IgxListLineTitleDirective = class IgxListLineTitleDirective {
constructor() {
this.cssClass = 'igx-list__item-line-title';
}
};
__decorate([
HostBinding('class.igx-list__item-line-title'),
__metadata("design:type", Object)
], IgxListLineTitleDirective.prototype, "cssClass", void 0);
IgxListLineTitleDirective = __decorate([
Directive({
// tslint:disable-next-line:directive-selector
selector: '[igxListLineTitle]'
})
], IgxListLineTitleDirective);
export { IgxListLineTitleDirective };
/**
* igxListLineSubTitle is a directive that add class to the target element
* Use it to make anything to look like list Subtitle.
*/
let IgxListLineSubTitleDirective = class IgxListLineSubTitleDirective {
constructor() {
this.cssClass = 'igx-list__item-line-subtitle';
}
};
__decorate([
HostBinding('class.igx-list__item-line-subtitle'),
__metadata("design:type", Object)
], IgxListLineSubTitleDirective.prototype, "cssClass", void 0);
IgxListLineSubTitleDirective = __decorate([
Directive({
// tslint:disable-next-line:directive-selector
selector: '[igxListLineSubTitle]'
})
], IgxListLineSubTitleDirective);
export { IgxListLineSubTitleDirective };
let IgxListComponent = IgxListComponent_1 = class IgxListComponent extends IgxListBaseDirective {
constructor(element, _displayDensityOptions) {
super(_displayDensityOptions);
this.element = element;
this._displayDensityOptions = _displayDensityOptions;
/**
* Provides a threshold after which the item's panning will be completed automatically.
* By default this property is set to 0.5 which is 50% of the list item's width.
* ```typescript
* this.list.panEndTriggeringThreshold = 0.8;
* ```
*/
this.panEndTriggeringThreshold = 0.5;
/**
* Sets/gets the `id` of the list.
* If not set, the `id` of the first list component will be `"igx-list-0"`.
* ```html
* <igx-list id = "my-first-list"></igx-list>
* ```
* ```typescript
* let listId = this.list.id;
* ```
* @memberof IgxListComponent
*/
this.id = `igx-list-${NEXT_ID++}`;
/**
* Sets/gets whether the left panning of an item is allowed.
* Default value is `false`.
* ```html
* <igx-list [allowLeftPanning] = "true"></igx-list>
* ```
* ```typescript
* let isLeftPanningAllowed = this.list.allowLeftPanning;
* ```
* @memberof IgxListComponent
*/
this.allowLeftPanning = false;
/**
* Sets/gets whether the right panning of an item is allowed.
* Default value is `false`.
* ```html
* <igx-list [allowRightPanning] = "true"></igx-list>
* ```
* ```typescript
* let isRightPanningAllowed = this.list.allowRightPanning;
* ```
* @memberof IgxListComponent
*/
this.allowRightPanning = false;
/**
* Sets/gets whether the list is currently loading data.
* Set it to display the dataLoadingTemplate while data is being retrieved.
* Default value is `false`.
* ```html
* <igx-list [isLoading]="true"></igx-list>
* ```
* ```typescript
* let isLoading = this.list.isLoading;
* ```
* @memberof IgxListComponent
*/
this.isLoading = false;
/**
* Emits an event within the current list when left pan gesture is executed on a list item.
* Provides a reference to an object of type `IListItemPanningEventArgs` as an event argument.
* ```html
* <igx-list [allowLeftPanning]="true" (onLeftPan)="onLeftPan($event)"></igx-list>
* ```
* @memberof IgxListComponent
*/
this.onLeftPan = new EventEmitter();
/**
* Emits an event within the current list when right pan gesture is executed on a list item.
* Provides a reference to an object of type `IListItemPanningEventArgs` as an event argument.
* ```html
* <igx-list [allowRightPanning]="true" (onRightPan)="onRightPan($event)"></igx-list>
* ```
* @memberof IgxListComponent
*/
this.onRightPan = new EventEmitter();
/**
* Emits an event within the current list when pan gesture is executed on list item.
* Provides references to the `IgxListItemComponent` and `IgxListPanState` as event arguments.
* ```html
* <igx-list (onPanStateChange) = "onPanStateChange($event)"></igx-list>
* ```
* @memberof IgxListComponent
*/
this.onPanStateChange = new EventEmitter();
/**
* Emits an event within the current list when a list item has been clicked.
* Provides references to the `IgxListItemComponent` and `Event` as event arguments.
* ```html
* <igx-list (onItemClicked) = "onItemClicked($event)"></igx-list>
* ```
* @memberof IgxListComponent
*/
this.onItemClicked = new EventEmitter();
}
/**
* @hidden
* @internal
*/
get sortedChildren() {
if (this.children !== undefined) {
return this.children.toArray()
.sort((a, b) => {
return a.index - b.index;
});
}
return null;
}
/**
* Gets the `role` attribute.
* ```typescript
* let listRole = this.list.role;
* ```
* @memberof IgxListComponent
*/
get role() {
return 'list';
}
/**
* Returns boolean indicating if the list is empty.
* ```typescript
* let isEmpty = this.list.isListEmpty;
* ```
* @memberof IgxListComponent
*/
get isListEmpty() {
return !this.children || this.children.length === 0;
}
/**
* @hidden
*/
get cssClass() {
return !this.isListEmpty && this.displayDensity === DisplayDensity.comfortable;
}
/**
* @hidden
*/
get cssClassCompact() {
return !this.isListEmpty && this.displayDensity === DisplayDensity.compact;
}
/**
* @hidden
*/
get cssClassCosy() {
return !this.isListEmpty && this.displayDensity === DisplayDensity.cosy;
}
/**
* Returns the `items` in the list excluding the headers.
* ```typescript
* let listItems: IgxListItemComponent[] = this.list.items;
* ```
* @memberof IgxListComponent
*/
get items() {
const items = [];
if (this.children !== undefined) {
for (const child of this.sortedChildren) {
if (!child.isHeader) {
items.push(child);
}
}
}
return items;
}
/**
* Returns the headers in the list.
* ```typescript
* let listHeaders: IgxListItemComponent[] = this.list.headers;
* ```
* @memberof IgxListComponent
*/
get headers() {
const headers = [];
if (this.children !== undefined) {
for (const child of this.children.toArray()) {
if (child.isHeader) {
headers.push(child);
}
}
}
return headers;
}
/**
* Returns the `context` object which represents the `template context` binding into the `list container`
* by providing the `$implicit` declaration which is the `IgxListComponent` itself.
* ```typescript
* let listComponent = this.list.context;
* ```
*/
get context() {
return {
$implicit: this
};
}
/**
* Returns the `template` of an empty list.
* ```typescript
* let listTemplate = this.list.template;
* ```
* @memberof IgxListComponent
*/
get template() {
if (this.isLoading) {
return this.dataLoadingTemplate ? this.dataLoadingTemplate.template : this.defaultDataLoadingTemplate;
}
else {
return this.emptyListTemplate ? this.emptyListTemplate.template : this.defaultEmptyListTemplate;
}
}
};
IgxListComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] }
];
__decorate([
ContentChildren(forwardRef(() => IgxListItemComponent), { descendants: true }),
__metadata("design:type", QueryList)
], IgxListComponent.prototype, "children", void 0);
__decorate([
ContentChild(IgxEmptyListTemplateDirective, { read: IgxEmptyListTemplateDirective }),
__metadata("design:type", IgxEmptyListTemplateDirective)
], IgxListComponent.prototype, "emptyListTemplate", void 0);
__decorate([
ContentChild(IgxDataLoadingTemplateDirective, { read: IgxDataLoadingTemplateDirective }),
__metadata("design:type", IgxDataLoadingTemplateDirective)
], IgxListComponent.prototype, "dataLoadingTemplate", void 0);
__decorate([
ContentChild(IgxListItemLeftPanningTemplateDirective, { read: IgxListItemLeftPanningTemplateDirective }),
__metadata("design:type", IgxListItemLeftPanningTemplateDirective)
], IgxListComponent.prototype, "listItemLeftPanningTemplate", void 0);
__decorate([
ContentChild(IgxListItemRightPanningTemplateDirective, { read: IgxListItemRightPanningTemplateDirective }),
__metadata("design:type", IgxListItemRightPanningTemplateDirective)
], IgxListComponent.prototype, "listItemRightPanningTemplate", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "panEndTriggeringThreshold", void 0);
__decorate([
ViewChild('defaultEmptyList', { read: TemplateRef, static: true }),
__metadata("design:type", TemplateRef)
], IgxListComponent.prototype, "defaultEmptyListTemplate", void 0);
__decorate([
ViewChild('defaultDataLoading', { read: TemplateRef, static: true }),
__metadata("design:type", TemplateRef)
], IgxListComponent.prototype, "defaultDataLoadingTemplate", void 0);
__decorate([
HostBinding('attr.id'),
Input(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "id", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "allowLeftPanning", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "allowRightPanning", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "isLoading", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "onLeftPan", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "onRightPan", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "onPanStateChange", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxListComponent.prototype, "onItemClicked", void 0);
__decorate([
HostBinding('attr.role'),
__metadata("design:type", Object),
__metadata("design:paramtypes", [])
], IgxListComponent.prototype, "role", null);
__decorate([
HostBinding('class.igx-list-empty'),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [])
], IgxListComponent.prototype, "isListEmpty", null);
__decorate([
HostBinding('class.igx-list'),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [])
], IgxListComponent.prototype, "cssClass", null);
__decorate([
HostBinding('class.igx-list--compact'),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [])
], IgxListComponent.prototype, "cssClassCompact", null);
__decorate([
HostBinding('class.igx-list--cosy'),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [])
], IgxListComponent.prototype, "cssClassCosy", null);
IgxListComponent = IgxListComponent_1 = __decorate([
Component({
selector: 'igx-list',
template: "<ng-content></ng-content>\n\n<ng-template #defaultEmptyList>\n <article class=\"message\">\n There are no items in the list.\n </article>\n</ng-template>\n\n<ng-template #defaultDataLoading>\n <article class=\"message\">\n Loading data from the server...\n </article>\n</ng-template>\n\n<ng-container *ngIf=\"!children || children.length === 0 || isLoading\">\n <ng-container *ngTemplateOutlet=\"template; context: context\">\n </ng-container>\n</ng-container>\n",
providers: [{ provide: IgxListBaseDirective, useExisting: IgxListComponent_1 }]
}),
__param(1, Optional()), __param(1, Inject(DisplayDensityToken)),
__metadata("design:paramtypes", [ElementRef, Object])
], IgxListComponent);
export { IgxListComponent };
/**
* @hidden
*/
let IgxListModule = class IgxListModule {
};
IgxListModule = __decorate([
NgModule({
declarations: [
IgxListBaseDirective,
IgxListComponent,
IgxListItemComponent,
IgxListThumbnailDirective,
IgxListActionDirective,
IgxListLineDirective,
IgxListLineTitleDirective,
IgxListLineSubTitleDirective,
IgxDataLoadingTemplateDirective,
IgxEmptyListTemplateDirective,
IgxListItemLeftPanningTemplateDirective,
IgxListItemRightPanningTemplateDirective
],
exports: [
IgxListComponent,
IgxListItemComponent,
IgxListThumbnailDirective,
IgxListActionDirective,
IgxListLineDirective,
IgxListLineTitleDirective,
IgxListLineSubTitleDirective,
IgxDataLoadingTemplateDirective,
IgxEmptyListTemplateDirective,
IgxListItemLeftPanningTemplateDirective,
IgxListItemRightPanningTemplateDirective
],
imports: [
CommonModule,
IgxRippleModule
]
})
], IgxListModule);
export { IgxListModule };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2xpc3QvbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUNILFNBQVMsRUFDVCxZQUFZLEVBQ1osZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsV0FBVyxFQUNYLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUFFLFNBQVMsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBRXhFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdELE9BQU8sRUFDSCxvQkFBb0IsRUFDcEIsK0JBQStCLEVBQy9CLDZCQUE2QixFQUU3Qix1Q0FBdUMsRUFDdkMsd0NBQXdDLEVBQzNDLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBMEIsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHOUYsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBbUJoQjs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFFSDs7O0dBR0c7QUFNSCxJQUFhLHlCQUF5QixHQUF0QyxNQUFhLHlCQUF5QjtDQUFHLENBQUE7QUFBNUIseUJBQXlCO0lBTHJDLFNBQVMsQ0FBQztRQUNQLDhDQUE4QztRQUM5QyxRQUFRLEVBQUUsb0JBQW9CO0tBQ2pDLENBQUM7R0FFVyx5QkFBeUIsQ0FBRztTQUE1Qix5QkFBeUI7QUFFdEM7OztHQUdHO0FBTUgsSUFBYSxzQkFBc0IsR0FBbkMsTUFBYSxzQkFBc0I7Q0FBRyxDQUFBO0FB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QUFFLFdBQUEsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUE7cUNBRGhCLFVBQVU7R0FGN0IsZ0JBQWdCLENBd1Q1QjtTQXhUWSxnQkFBZ0I7QUEwVDdCOztHQUVHO0FBa0NILElBQWEsYUFBYSxHQUExQixNQUFhLGFBQWE7Q0FDekIsQ0FBQTtBQURZLGFBQWE7SUFqQ3pCLFFBQVEsQ0FBQztRQUNOLFlBQVksRUFBRTtZQUNWLG9CQUFvQjtZQUNwQixnQkFBZ0I7WUFDaEIsb0JBQW9CO1lBQ3BCLHlCQUF5QjtZQUN6QixzQkFBc0I7WUFDdEIsb0JBQW9CO1lBQ3BCLHlCQUF5QjtZQUN6Qiw0QkFBNEI7WUFDNUIsK0JBQStCO1lBQy9CLDZCQUE2QjtZQUM3Qix1Q0FBdUM7WUFDdkMsd0NBQXdDO1NBQzNDO1FBQ0QsT0FBTyxFQUFFO1lBQ0wsZ0JBQWdCO1lBQ2hCLG9CQUFvQjtZQUNwQix5QkFBeUI7WUFDekIsc0JBQXNCO1lBQ3RCLG9CQUFvQjtZQUNwQix5QkFBeUI7WUFDekIsNEJBQTRCO1lBQzVCLCtCQUErQjtZQUMvQiw2QkFBNkI7WUFDN0IsdUNBQXVDO1lBQ3ZDLHdDQUF3QztTQUMzQztRQUNELE9BQU8sRUFBRTtZQUNMLFlBQVk7WUFDWixlQUFlO1NBQ2xCO0tBQ0osQ0FBQztHQUNXLGFBQWEsQ0FDekI7U0FEWSxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgZm9yd2FyZFJlZixcbiAgICBIb3N0QmluZGluZyxcbiAgICBJbnB1dCxcbiAgICBOZ01vZHVsZSxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFRlbXBsYXRlUmVmLFxuICAgIFZpZXdDaGlsZCxcbiAgICBPcHRpb25hbCxcbiAgICBJbmplY3QsIERpcmVjdGl2ZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgSWd4UmlwcGxlTW9kdWxlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9yaXBwbGUvcmlwcGxlLmRpcmVjdGl2ZSc7XG5cbmltcG9ydCB7IElneExpc3RJdGVtQ29tcG9uZW50IH0gZnJvbSAnLi9saXN0LWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7XG4gICAgSWd4TGlzdEJhc2VEaXJlY3RpdmUsXG4gICAgSWd4RGF0YUxvYWRpbmdUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICBJZ3hFbXB0eUxpc3RUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICBJZ3hMaXN0UGFuU3RhdGUsXG4gICAgSWd4TGlzdEl0ZW1MZWZ0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlLFxuICAgIElneExpc3RJdGVtUmlnaHRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmVcbn0gZnJvbSAnLi9saXN0LmNvbW1vbic7XG5pbXBvcnQgeyBJRGlzcGxheURlbnNpdHlPcHRpb25zLCBEaXNwbGF5RGVuc2l0eVRva2VuLCBEaXNwbGF5RGVuc2l0eSB9IGZyb20gJy4uL2NvcmUvZGVuc2l0eSc7XG5pbXBvcnQgeyBJQmFzZUV2ZW50QXJncyB9IGZyb20gJy4uL2NvcmUvdXRpbHMnO1xuXG5sZXQgTkVYVF9JRCA9IDA7XG5leHBvcnQgaW50ZXJmYWNlIElQYW5TdGF0ZUNoYW5nZUV2ZW50QXJncyBleHRlbmRzIElCYXNlRXZlbnRBcmdzIHtcbiAgICBvbGRTdGF0ZTogSWd4TGlzdFBhblN0YXRlO1xuICAgIG5ld1N0YXRlOiBJZ3hMaXN0UGFuU3RhdGU7XG4gICAgaXRlbTogSWd4TGlzdEl0ZW1Db21wb25lbnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUxpc3RJdGVtQ2xpY2tFdmVudEFyZ3MgZXh0ZW5kcyBJQmFzZUV2ZW50QXJncyB7XG4gICAgaXRlbTogSWd4TGlzdEl0ZW1Db21wb25lbnQ7XG4gICAgZXZlbnQ6IEV2ZW50O1xuICAgIGRpcmVjdGlvbjogSWd4TGlzdFBhblN0YXRlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElMaXN0SXRlbVBhbm5pbmdFdmVudEFyZ3MgZXh0ZW5kcyBJQmFzZUV2ZW50QXJncyB7XG4gICAgaXRlbTogSWd4TGlzdEl0ZW1Db21wb25lbnQ7XG4gICAgZGlyZWN0aW9uOiBJZ3hMaXN0UGFuU3RhdGU7XG4gICAga2VlcEl0ZW06IGJvb2xlYW47XG59XG5cbi8qKlxuICogKipJZ25pdGUgVUkgZm9yIEFuZ3VsYXIgTGlzdCoqIC1cbiAqIFtEb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5pbmZyYWdpc3RpY3MuY29tL3Byb2R1Y3RzL2lnbml0ZS11aS1hbmd1bGFyL2FuZ3VsYXIvY29tcG9uZW50cy9saXN0Lmh0bWwpXG4gKlxuICogVGhlIElnbml0ZSBVSSBMaXN0IGRpc3BsYXlzIHJvd3Mgb2YgaXRlbXMgYW5kIHN1cHBvcnRzIG9uZSBvciBtb3JlIGhlYWRlciBpdGVtcyBhcyB3ZWxsIGFzIHNlYXJjaCBhbmQgZmlsdGVyaW5nXG4gKiBvZiBsaXN0IGl0ZW1zLiBFYWNoIGxpc3QgaXRlbSBpcyBjb21wbGV0ZWx5IHRlbXBsYXRlYWJsZSBhbmQgd2lsbCBzdXBwb3J0IGFueSB2YWxpZCBIVE1MIG9yIEFuZ3VsYXIgY29tcG9uZW50LlxuICpcbiAqIEV4YW1wbGU6XG4gKiBgYGBodG1sXG4gKiA8aWd4LWxpc3Q+XG4gKiAgIDxpZ3gtbGlzdC1pdGVtIGlzSGVhZGVyPVwidHJ1ZVwiPkNvbnRhY3RzPC9pZ3gtbGlzdC1pdGVtPlxuICogICA8aWd4LWxpc3QtaXRlbSAqbmdGb3I9XCJsZXQgY29udGFjdCBvZiBjb250YWN0c1wiPlxuICogICAgIDxzcGFuIGNsYXNzPVwibmFtZVwiPnt7IGNvbnRhY3QubmFtZSB9fTwvc3Bhbj5cbiAqICAgICA8c3BhbiBjbGFzcz1cInBob25lXCI+e3sgY29udGFjdC5waG9uZSB9fTwvc3Bhbj5cbiAqICAgPC9pZ3gtbGlzdC1pdGVtPlxuICogPC9pZ3gtbGlzdD5cbiAqIGBgYFxuICovXG5cbi8qKlxuICogaWd4TGlzdFRodW1ibmFpbCBpcyBjb250YWluZXIgZm9yIHRoZSBMaXN0IG1lZGlhXG4gKiBVc2UgaXQgdG8gd3JhcCBhbnl0aGluZyB5b3Ugd2FudCB0byBiZSB1c2VkIGFzIGEgdGh1bWJuYWlsLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGlyZWN0aXZlLXNlbGVjdG9yXG4gICAgc2VsZWN0b3I6ICdbaWd4TGlzdFRodW1ibmFpbF0nXG59KVxuXG5leHBvcnQgY2xhc3MgSWd4TGlzdFRodW1ibmFpbERpcmVjdGl2ZSB7fVxuXG4vKipcbiAqIGlneExpc3RBY3Rpb24gaXMgY29udGFpbmVyIGZvciB0aGUgTGlzdCBhY3Rpb25cbiAqIFVzZSBpdCB0byB3cmFwIGFueXRoaW5nIHlvdSB3YW50IHRvIGJlIHVzZWQgYXMgYSBsaXN0IGFjdGlvbjogaWNvbiwgY2hlY2tib3guLi5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRpcmVjdGl2ZS1zZWxlY3RvclxuICAgIHNlbGVjdG9yOiAnW2lneExpc3RBY3Rpb25dJ1xufSlcblxuZXhwb3J0IGNsYXNzIElneExpc3RBY3Rpb25EaXJlY3RpdmUge31cblxuLyoqXG4gKiBpZ3hMaXN0TGluZSBpcyBjb250YWluZXIgZm9yIHRoZSBMaXN0IHRleHQgY29udGVudFxuICogVXNlIGl0IHRvIHdyYXAgYW55dGhpbmcgeW91IHdhbnQgdG8gYmUgdXNlZCBhcyBhIHBsYW5lIHRleHQuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkaXJlY3RpdmUtc2VsZWN0b3JcbiAgICBzZWxlY3RvcjogJ1tpZ3hMaXN0TGluZV0nXG59KVxuXG5leHBvcnQgY2xhc3MgSWd4TGlzdExpbmVEaXJlY3RpdmUge31cblxuLyoqXG4gKiBpZ3hMaXN0TGluZVRpdGxlIGlzIGEgZGlyZWN0aXZlIHRoYXQgYWRkIGNsYXNzIHRvIHRoZSB0YXJnZXQgZWxlbWVudFxuICogVXNlIGl0IHRvIG1ha2UgYW55dGhpbmcgdG8gbG9vayBsaWtlIGxpc3QgVGl0bGUuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkaXJlY3RpdmUtc2VsZWN0b3JcbiAgICBzZWxlY3RvcjogJ1tpZ3hMaXN0TGluZVRpdGxlXSdcbn0pXG5cbmV4cG9ydCBjbGFzcyBJZ3hMaXN0TGluZVRpdGxlRGlyZWN0aXZlIHtcbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1saXN0X19pdGVtLWxpbmUtdGl0bGUnKVxuICAgIHB1YmxpYyBjc3NDbGFzcyA9ICdpZ3gtbGlzdF9faXRlbS1saW5lLXRpdGxlJztcbn1cblxuLyoqXG4gKiBpZ3hMaXN0TGluZVN1YlRpdGxlIGlzIGEgZGlyZWN0aXZlIHRoYXQgYWRkIGNsYXNzIHRvIHRoZSB0YXJnZXQgZWxlbWVudFxuICogVXNlIGl0IHRvIG1ha2UgYW55dGhpbmcgdG8gbG9vayBsaWtlIGxpc3QgU3VidGl0bGUuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkaXJlY3RpdmUtc2VsZWN0b3JcbiAgICBzZWxlY3RvcjogJ1tpZ3hMaXN0TGluZVN1YlRpdGxlXSdcbn0pXG5cbmV4cG9ydCBjbGFzcyBJZ3hMaXN0TGluZVN1YlRpdGxlRGlyZWN0aXZlIHtcbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1saXN0X19pdGVtLWxpbmUtc3VidGl0bGUnKVxuICAgIHB1YmxpYyBjc3NDbGFzcyA9ICdpZ3gtbGlzdF9faXRlbS1saW5lLXN1YnRpdGxlJztcbn1cblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdpZ3gtbGlzdCcsXG4gICAgdGVtcGxhdGVVcmw6ICdsaXN0LmNvbXBvbmVudC5odG1sJyxcbiAgICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IElneExpc3RCYXNlRGlyZWN0aXZlLCB1c2VFeGlzdGluZzogSWd4TGlzdENvbXBvbmVudCB9XVxufSlcbmV4cG9ydCBjbGFzcyBJZ3hMaXN0Q29tcG9uZW50IGV4dGVuZHMgSWd4TGlzdEJhc2VEaXJlY3RpdmUge1xuXG4gICAgY29uc3RydWN0b3IocHVibGljIGVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRGlzcGxheURlbnNpdHlUb2tlbikgcHJvdGVjdGVkIF9kaXNwbGF5RGVuc2l0eU9wdGlvbnM6IElEaXNwbGF5RGVuc2l0eU9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIoX2Rpc3BsYXlEZW5zaXR5T3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gb2YgYWxsIGl0ZW1zIGFuZCBoZWFkZXJzIGluIHRoZSBsaXN0LlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbGlzdENoaWxkcmVuOiBRdWVyeUxpc3QgPSB0aGlzLmxpc3QuY2hpbGRyZW47XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4TGlzdEl0ZW1Db21wb25lbnQpLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pXG4gICAgcHVibGljIGNoaWxkcmVuOiBRdWVyeUxpc3Q8SWd4TGlzdEl0ZW1Db21wb25lbnQ+O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBnZXQgc29ydGVkQ2hpbGRyZW4oKTogSWd4TGlzdEl0ZW1Db21wb25lbnRbXSB7XG4gICAgICAgIGlmICh0aGlzLmNoaWxkcmVuICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLnRvQXJyYXkoKVxuICAgICAgICAgICAgICAgIC5zb3J0KChhOiBJZ3hMaXN0SXRlbUNvbXBvbmVudCwgYjogSWd4TGlzdEl0ZW1Db21wb25lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEuaW5kZXggLSBiLmluZGV4O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRlbXBsYXRlIHdoaWNoIHdpbGwgYmUgdXNlZCBieSB0aGUgSWd4TGlzdCBpbiBjYXNlIHRoZXJlIGFyZSBubyBsaXN0IGl0ZW1zIGRlZmluZWQgYW5kIGBpc0xvYWRpbmdgIGlzIHNldCB0byBgZmFsc2VgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgZW1wdHlUZW1wbGF0ZSA9IHRoaXMubGlzdC5lbXB0eUxpc3RUZW1wbGF0ZTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGQoSWd4RW1wdHlMaXN0VGVtcGxhdGVEaXJlY3RpdmUsIHsgcmVhZDogSWd4RW1wdHlMaXN0VGVtcGxhdGVEaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgZW1wdHlMaXN0VGVtcGxhdGU6IElneEVtcHR5TGlzdFRlbXBsYXRlRGlyZWN0aXZlO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGVtcGxhdGUgd2hpY2ggd2lsbCBiZSB1c2VkIGJ5IHRoZSBJZ3hMaXN0IGluIGNhc2UgdGhlcmUgYXJlIG5vIGxpc3QgaXRlbXMgZGVmaW5lZCBhbmQgYGlzTG9hZGluZ2AgaXMgc2V0IHRvIGB0cnVlYC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGxvYWRpbmdUZW1wbGF0ZSA9IHRoaXMubGlzdC5kYXRhTG9hZGluZ1RlbXBsYXRlO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hMaXN0Q29tcG9uZW50XG4gICAgICovXG4gICAgQENvbnRlbnRDaGlsZChJZ3hEYXRhTG9hZGluZ1RlbXBsYXRlRGlyZWN0aXZlLCB7IHJlYWQ6IElneERhdGFMb2FkaW5nVGVtcGxhdGVEaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgZGF0YUxvYWRpbmdUZW1wbGF0ZTogSWd4RGF0YUxvYWRpbmdUZW1wbGF0ZURpcmVjdGl2ZTtcblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB0aGUgdGVtcGxhdGUgc2hvd24gd2hlbiBsZWZ0IHBhbm5pbmcgYSBsaXN0IGl0ZW0uXG4gICAgICogRGVmYXVsdCB2YWx1ZSBpcyBgbnVsbGAuXG4gICAgICogYGBgaHRtbFxuICAgICAqICA8aWd4LWxpc3QgW2FsbG93TGVmdFBhbm5pbmddID0gXCJ0cnVlXCI+PC9pZ3gtbGlzdD5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGl0ZW1MZWZ0UGFuVG1wbCA9IHRoaXMubGlzdC5saXN0SXRlbUxlZnRQYW5uaW5nVGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkKElneExpc3RJdGVtTGVmdFBhbm5pbmdUZW1wbGF0ZURpcmVjdGl2ZSwgeyByZWFkOiBJZ3hMaXN0SXRlbUxlZnRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgbGlzdEl0ZW1MZWZ0UGFubmluZ1RlbXBsYXRlOiBJZ3hMaXN0SXRlbUxlZnRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmU7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzL2dldHMgdGhlIHRlbXBsYXRlIHNob3duIHdoZW4gcmlnaHQgcGFubmluZyBhIGxpc3QgaXRlbS5cbiAgICAgKiBEZWZhdWx0IHZhbHVlIGlzIGBudWxsYC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogIDxpZ3gtbGlzdCBbYWxsb3dMZWZ0UGFubmluZ10gPSBcInRydWVcIj48L2lneC1saXN0PlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXRlbVJpZ2h0UGFuVG1wbCA9IHRoaXMubGlzdC5saXN0SXRlbVJpZ2h0UGFubmluZ1RlbXBsYXRlO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hMaXN0Q29tcG9uZW50XG4gICAgICovXG4gICAgQENvbnRlbnRDaGlsZChJZ3hMaXN0SXRlbVJpZ2h0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlLCB7IHJlYWQ6IElneExpc3RJdGVtUmlnaHRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgbGlzdEl0ZW1SaWdodFBhbm5pbmdUZW1wbGF0ZTogSWd4TGlzdEl0ZW1SaWdodFBhbm5pbmdUZW1wbGF0ZURpcmVjdGl2ZTtcblxuICAgIC8qKlxuICAgICAqIFByb3ZpZGVzIGEgdGhyZXNob2xkIGFmdGVyIHdoaWNoIHRoZSBpdGVtJ3MgcGFubmluZyB3aWxsIGJlIGNvbXBsZXRlZCBhdXRvbWF0aWNhbGx5LlxuICAgICAqIEJ5IGRlZmF1bHQgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gMC41IHdoaWNoIGlzIDUwJSBvZiB0aGUgbGlzdCBpdGVtJ3Mgd2lkdGguXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMubGlzdC5wYW5FbmRUcmlnZ2VyaW5nVGhyZXNob2xkID0gMC44O1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHBhbkVuZFRyaWdnZXJpbmdUaHJlc2hvbGQgPSAwLjU7XG5cbiAgICAvKipAaGlkZGVuKi9cbiAgICBAVmlld0NoaWxkKCdkZWZhdWx0RW1wdHlMaXN0JywgeyByZWFkOiBUZW1wbGF0ZVJlZiwgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGRlZmF1bHRFbXB0eUxpc3RUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICAgIC8qKkBoaWRkZW4qL1xuICAgIEBWaWV3Q2hpbGQoJ2RlZmF1bHREYXRhTG9hZGluZycsIHsgcmVhZDogVGVtcGxhdGVSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICAgIHByb3RlY3RlZCBkZWZhdWx0RGF0YUxvYWRpbmdUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB0aGUgYGlkYCBvZiB0aGUgbGlzdC5cbiAgICAgKiBJZiBub3Qgc2V0LCB0aGUgYGlkYCBvZiB0aGUgZmlyc3QgbGlzdCBjb21wb25lbnQgd2lsbCBiZSBgXCJpZ3gtbGlzdC0wXCJgLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWxpc3QgaWQgPSBcIm15LWZpcnN0LWxpc3RcIj48L2lneC1saXN0PlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbGlzdElkID0gIHRoaXMubGlzdC5pZDtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5pZCcpXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgaWQgPSBgaWd4LWxpc3QtJHtORVhUX0lEKyt9YDtcblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB3aGV0aGVyIHRoZSBsZWZ0IHBhbm5pbmcgb2YgYW4gaXRlbSBpcyBhbGxvd2VkLlxuICAgICAqIERlZmF1bHQgdmFsdWUgaXMgYGZhbHNlYC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogIDxpZ3gtbGlzdCBbYWxsb3dMZWZ0UGFubmluZ10gPSBcInRydWVcIj48L2lneC1saXN0PlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXNMZWZ0UGFubmluZ0FsbG93ZWQgPSB0aGlzLmxpc3QuYWxsb3dMZWZ0UGFubmluZztcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGFsbG93TGVmdFBhbm5pbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB3aGV0aGVyIHRoZSByaWdodCBwYW5uaW5nIG9mIGFuIGl0ZW0gaXMgYWxsb3dlZC5cbiAgICAgKiBEZWZhdWx0IHZhbHVlIGlzIGBmYWxzZWAuXG4gICAgICogYGBgaHRtbFxuICAgICAqICA8aWd4LWxpc3QgW2FsbG93UmlnaHRQYW5uaW5nXSA9IFwidHJ1ZVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBpc1JpZ2h0UGFubmluZ0FsbG93ZWQgPSB0aGlzLmxpc3QuYWxsb3dSaWdodFBhbm5pbmc7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBhbGxvd1JpZ2h0UGFubmluZyA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogU2V0cy9nZXRzIHdoZXRoZXIgdGhlIGxpc3QgaXMgY3VycmVudGx5IGxvYWRpbmcgZGF0YS5cbiAgICAgKiBTZXQgaXQgdG8gZGlzcGxheSB0aGUgZGF0YUxvYWRpbmdUZW1wbGF0ZSB3aGlsZSBkYXRhIGlzIGJlaW5nIHJldHJpZXZlZC5cbiAgICAgKiBEZWZhdWx0IHZhbHVlIGlzIGBmYWxzZWAuXG4gICAgICogYGBgaHRtbFxuICAgICAqICA8aWd4LWxpc3QgW2lzTG9hZGluZ109XCJ0cnVlXCI+PC9pZ3gtbGlzdD5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGlzTG9hZGluZyA9IHRoaXMubGlzdC5pc0xvYWRpbmc7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpc0xvYWRpbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IHdpdGhpbiB0aGUgY3VycmVudCBsaXN0IHdoZW4gbGVmdCBwYW4gZ2VzdHVyZSBpcyBleGVjdXRlZCBvbiBhIGxpc3QgaXRlbS5cbiAgICAgKiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3Qgb2YgdHlwZSBgSUxpc3RJdGVtUGFubmluZ0V2ZW50QXJnc2AgYXMgYW4gZXZlbnQgYXJndW1lbnQuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtbGlzdCBbYWxsb3dMZWZ0UGFubmluZ109XCJ0cnVlXCIgKG9uTGVmdFBhbik9XCJvbkxlZnRQYW4oJGV2ZW50KVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25MZWZ0UGFuID0gbmV3IEV2ZW50RW1pdHRlcjxJTGlzdEl0ZW1QYW5uaW5nRXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgd2l0aGluIHRoZSBjdXJyZW50IGxpc3Qgd2hlbiByaWdodCBwYW4gZ2VzdHVyZSBpcyBleGVjdXRlZCBvbiBhIGxpc3QgaXRlbS5cbiAgICAgKiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3Qgb2YgdHlwZSBgSUxpc3RJdGVtUGFubmluZ0V2ZW50QXJnc2AgYXMgYW4gZXZlbnQgYXJndW1lbnQuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtbGlzdCBbYWxsb3dSaWdodFBhbm5pbmddPVwidHJ1ZVwiIChvblJpZ2h0UGFuKT1cIm9uUmlnaHRQYW4oJGV2ZW50KVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25SaWdodFBhbiA9IG5ldyBFdmVudEVtaXR0ZXI8SUxpc3RJdGVtUGFubmluZ0V2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICogRW1pdHMgYW4gZXZlbnQgd2l0aGluIHRoZSBjdXJyZW50IGxpc3Qgd2hlbiBwYW4gZ2VzdHVyZSBpcyBleGVjdXRlZCBvbiBsaXN0IGl0ZW0uXG4gICAgKiBQcm92aWRlcyByZWZlcmVuY2VzIHRvIHRoZSBgSWd4TGlzdEl0ZW1Db21wb25lbnRgIGFuZCBgSWd4TGlzdFBhblN0YXRlYCBhcyBldmVudCBhcmd1bWVudHMuXG4gICAgKiBgYGBodG1sXG4gICAgKiA8aWd4LWxpc3QgKG9uUGFuU3RhdGVDaGFuZ2UpID0gXCJvblBhblN0YXRlQ2hhbmdlKCRldmVudClcIj48L2lneC1saXN0PlxuICAgICogYGBgXG4gICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uUGFuU3RhdGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPElQYW5TdGF0ZUNoYW5nZUV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IHdpdGhpbiB0aGUgY3VycmVudCBsaXN0IHdoZW4gYSBsaXN0IGl0ZW0gaGFzIGJlZW4gY2xpY2tlZC5cbiAgICAgKiBQcm92aWRlcyByZWZlcmVuY2VzIHRvIHRoZSBgSWd4TGlzdEl0ZW1Db21wb25lbnRgIGFuZCBgRXZlbnRgIGFzIGV2ZW50IGFyZ3VtZW50cy5cbiAgICAgKiAgYGBgaHRtbFxuICAgICAqIDxpZ3gtbGlzdCAob25JdGVtQ2xpY2tlZCkgPSBcIm9uSXRlbUNsaWNrZWQoJGV2ZW50KVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25JdGVtQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8SUxpc3RJdGVtQ2xpY2tFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgcm9sZWAgYXR0cmlidXRlLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbGlzdFJvbGUgPSAgdGhpcy5saXN0LnJvbGU7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIucm9sZScpXG4gICAgcHVibGljIGdldCByb2xlKCkge1xuICAgICAgICByZXR1cm4gJ2xpc3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBsaXN0IGlzIGVtcHR5LlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXNFbXB0eSA9ICB0aGlzLmxpc3QuaXNMaXN0RW1wdHk7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1saXN0LWVtcHR5JylcbiAgICBwdWJsaWMgZ2V0IGlzTGlzdEVtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIXRoaXMuY2hpbGRyZW4gfHwgdGhpcy5jaGlsZHJlbi5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuaWd4LWxpc3QnKVxuICAgIHB1YmxpYyBnZXQgY3NzQ2xhc3MoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhdGhpcy5pc0xpc3RFbXB0eSAmJiB0aGlzLmRpc3BsYXlEZW5zaXR5ID09PSBEaXNwbGF5RGVuc2l0eS5jb21mb3J0YWJsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5pZ3gtbGlzdC0tY29tcGFjdCcpXG4gICAgcHVibGljIGdldCBjc3NDbGFzc0NvbXBhY3QoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhdGhpcy5pc0xpc3RFbXB0eSAmJiB0aGlzLmRpc3BsYXlEZW5zaXR5ID09PSBEaXNwbGF5RGVuc2l0eS5jb21wYWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1saXN0LS1jb3N5JylcbiAgICBwdWJsaWMgZ2V0IGNzc0NsYXNzQ29zeSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmlzTGlzdEVtcHR5ICYmIHRoaXMuZGlzcGxheURlbnNpdHkgPT09IERpc3BsYXlEZW5zaXR5LmNvc3k7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYGl0ZW1zYCBpbiB0aGUgbGlzdCBleGNsdWRpbmcgdGhlIGhlYWRlcnMuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBsaXN0SXRlbXM6IElneExpc3RJdGVtQ29tcG9uZW50W10gPSB0aGlzLmxpc3QuaXRlbXM7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGl0ZW1zKCk6IElneExpc3RJdGVtQ29tcG9uZW50W10ge1xuICAgICAgICBjb25zdCBpdGVtczogSWd4TGlzdEl0ZW1Db21wb25lbnRbXSA9IFtdO1xuICAgICAgICBpZiAodGhpcy5jaGlsZHJlbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuc29ydGVkQ2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNoaWxkLmlzSGVhZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goY2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGVhZGVycyBpbiB0aGUgbGlzdC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGxpc3RIZWFkZXJzOiBJZ3hMaXN0SXRlbUNvbXBvbmVudFtdID0gIHRoaXMubGlzdC5oZWFkZXJzO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hMaXN0Q29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGdldCBoZWFkZXJzKCk6IElneExpc3RJdGVtQ29tcG9uZW50W10ge1xuICAgICAgICBjb25zdCBoZWFkZXJzOiBJZ3hMaXN0SXRlbUNvbXBvbmVudFtdID0gW107XG4gICAgICAgIGlmICh0aGlzLmNoaWxkcmVuICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbi50b0FycmF5KCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNIZWFkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVycy5wdXNoKGNoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhlYWRlcnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYGNvbnRleHRgIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBgdGVtcGxhdGUgY29udGV4dGAgYmluZGluZyBpbnRvIHRoZSBgbGlzdCBjb250YWluZXJgXG4gICAgICogYnkgcHJvdmlkaW5nIHRoZSBgJGltcGxpY2l0YCBkZWNsYXJhdGlvbiB3aGljaCBpcyB0aGUgYElneExpc3RDb21wb25lbnRgIGl0c2VsZi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGxpc3RDb21wb25lbnQgPSAgdGhpcy5saXN0LmNvbnRleHQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBjb250ZXh0KCk6IGFueSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAkaW1wbGljaXQ6IHRoaXNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgdGVtcGxhdGVgIG9mIGFuIGVtcHR5IGxpc3QuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBsaXN0VGVtcGxhdGUgPSB0aGlzLmxpc3QudGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xuICAgICAgICBpZiAodGhpcy5pc0xvYWRpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGFMb2FkaW5nVGVtcGxhdGUgPyB0aGlzLmRhdGFMb2FkaW5nVGVtcGxhdGUudGVtcGxhdGUgOiB0aGlzLmRlZmF1bHREYXRhTG9hZGluZ1RlbXBsYXRlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1wdHlMaXN0VGVtcGxhdGUgPyB0aGlzLmVtcHR5TGlzdFRlbXBsYXRlLnRlbXBsYXRlIDogdGhpcy5kZWZhdWx0RW1wdHlMaXN0VGVtcGxhdGU7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5ATmdNb2R1bGUoe1xuICAgIGRlY2xhcmF0aW9uczogW1xuICAgICAgICBJZ3hMaXN0QmFzZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4TGlzdENvbXBvbmVudCxcbiAgICAgICAgSWd4TGlzdEl0ZW1Db21wb25lbnQsXG4gICAgICAgIElneExpc3RUaHVtYm5haWxEaXJlY3RpdmUsXG4gICAgICAgIElneExpc3RBY3Rpb25EaXJlY3RpdmUsXG4gICAgICAgIElneExpc3RMaW5lRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMaXN0TGluZVRpdGxlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMaXN0TGluZVN1YlRpdGxlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hEYXRhTG9hZGluZ1RlbXBsYXRlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hFbXB0eUxpc3RUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4TGlzdEl0ZW1MZWZ0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMaXN0SXRlbVJpZ2h0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlXG4gICAgXSxcbiAgICBleHBvcnRzOiBbXG4gICAgICAgIElneExpc3RDb21wb25lbnQsXG4gICAgICAgIElneExpc3RJdGVtQ29tcG9uZW50LFxuICAgICAgICBJZ3hMaXN0VGh1bWJuYWlsRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMaXN0QWN0aW9uRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMaXN0TGluZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4TGlzdExpbmVUaXRsZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4TGlzdExpbmVTdWJUaXRsZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4RGF0YUxvYWRpbmdUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4RW1wdHlMaXN0VGVtcGxhdGVEaXJlY3RpdmUsXG4gICAgICAgIElneExpc3RJdGVtTGVmdFBhbm5pbmdUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4TGlzdEl0ZW1SaWdodFBhbm5pbmdUZW1wbGF0ZURpcmVjdGl2ZVxuICAgIF0sXG4gICAgaW1wb3J0czogW1xuICAgICAgICBDb21tb25Nb2R1bGUsXG4gICAgICAgIElneFJpcHBsZU1vZHVsZVxuICAgIF1cbn0pXG5leHBvcnQgY2xhc3MgSWd4TGlzdE1vZHVsZSB7XG59XG4iXX0=