igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
503 lines • 40 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { CommonModule } from '@angular/common';
import { Component, ContentChild, ContentChildren, ElementRef, EventEmitter, forwardRef, HostBinding, Input, NgModule, Output, QueryList, TemplateRef, ViewChild } from '@angular/core';
import { IgxRippleModule } from '../directives/ripple/ripple.directive';
import { IgxListItemComponent } from './list-item.component';
import { IgxListBase, IgxDataLoadingTemplateDirective, IgxEmptyListTemplateDirective, IgxListItemLeftPanningTemplateDirective, IgxListItemRightPanningTemplateDirective } from './list.common';
/** @type {?} */
let NEXT_ID = 0;
/**
* @record
*/
export function IPanStateChangeEventArgs() { }
if (false) {
/** @type {?} */
IPanStateChangeEventArgs.prototype.oldState;
/** @type {?} */
IPanStateChangeEventArgs.prototype.newState;
/** @type {?} */
IPanStateChangeEventArgs.prototype.item;
}
/**
* @record
*/
export function IListItemClickEventArgs() { }
if (false) {
/** @type {?} */
IListItemClickEventArgs.prototype.item;
/** @type {?} */
IListItemClickEventArgs.prototype.event;
/** @type {?} */
IListItemClickEventArgs.prototype.direction;
}
/**
* @record
*/
export function IListItemPanningEventArgs() { }
if (false) {
/** @type {?} */
IListItemPanningEventArgs.prototype.item;
/** @type {?} */
IListItemPanningEventArgs.prototype.direction;
/** @type {?} */
IListItemPanningEventArgs.prototype.keepItem;
}
/**
* **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>
* ```
*/
export class IgxListComponent {
/**
* @param {?} element
*/
constructor(element) {
this.element = element;
/**
* 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
* @protected
* @return {?}
*/
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
* @return {?}
*/
get role() {
return 'list';
}
/**
* Returns boolean indicating if the list is empty.
* ```typescript
* let isEmpty = this.list.isListEmpty;
* ```
* \@memberof IgxListComponent
* @return {?}
*/
get isListEmpty() {
return !this.children || this.children.length === 0;
}
/**
* Returns boolean indicating if the list has a `cssClass` attribute.
* ```typescript
* let hasCssClass = this.list.cssClass;
* ```
* \@memberof IgxListComponent
* @return {?}
*/
get cssClass() {
return this.children && this.children.length > 0;
}
/**
* Returns the `items` in the list excluding the headers.
* ```typescript
* let listItems: IgxListItemComponent[] = this.list.items;
* ```
* \@memberof IgxListComponent
* @return {?}
*/
get items() {
/** @type {?} */
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
* @return {?}
*/
get headers() {
/** @type {?} */
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;
* ```
* @return {?}
*/
get context() {
return {
$implicit: this
};
}
/**
* Returns the `template` of an empty list.
* ```typescript
* let listTemplate = this.list.template;
* ```
* \@memberof IgxListComponent
* @return {?}
*/
get template() {
if (this.isLoading) {
return this.dataLoadingTemplate ? this.dataLoadingTemplate.template : this.defaultDataLoadingTemplate;
}
else {
return this.emptyListTemplate ? this.emptyListTemplate.template : this.defaultEmptyListTemplate;
}
}
}
IgxListComponent.decorators = [
{ type: Component, args: [{
selector: 'igx-list',
template: "<ng-content></ng-content>\n\n<ng-template #defaultEmptyList>\n <article class=\"message\">\n <p>There are no items in the list.</p>\n </article>\n</ng-template>\n\n<ng-template #defaultDataLoading>\n <article class=\"message\">\n <p>Loading data from the server...</p>\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: IgxListBase, useExisting: IgxListComponent }]
}] }
];
/** @nocollapse */
IgxListComponent.ctorParameters = () => [
{ type: ElementRef }
];
IgxListComponent.propDecorators = {
children: [{ type: ContentChildren, args: [forwardRef(() => IgxListItemComponent),] }],
emptyListTemplate: [{ type: ContentChild, args: [IgxEmptyListTemplateDirective, { read: IgxEmptyListTemplateDirective },] }],
dataLoadingTemplate: [{ type: ContentChild, args: [IgxDataLoadingTemplateDirective, { read: IgxDataLoadingTemplateDirective },] }],
listItemLeftPanningTemplate: [{ type: ContentChild, args: [IgxListItemLeftPanningTemplateDirective, { read: IgxListItemLeftPanningTemplateDirective },] }],
listItemRightPanningTemplate: [{ type: ContentChild, args: [IgxListItemRightPanningTemplateDirective, { read: IgxListItemRightPanningTemplateDirective },] }],
panEndTriggeringThreshold: [{ type: Input }],
defaultEmptyListTemplate: [{ type: ViewChild, args: ['defaultEmptyList', { read: TemplateRef },] }],
defaultDataLoadingTemplate: [{ type: ViewChild, args: ['defaultDataLoading', { read: TemplateRef },] }],
id: [{ type: HostBinding, args: ['attr.id',] }, { type: Input }],
allowLeftPanning: [{ type: Input }],
allowRightPanning: [{ type: Input }],
isLoading: [{ type: Input }],
onLeftPan: [{ type: Output }],
onRightPan: [{ type: Output }],
onPanStateChange: [{ type: Output }],
onItemClicked: [{ type: Output }],
role: [{ type: HostBinding, args: ['attr.role',] }],
isListEmpty: [{ type: HostBinding, args: ['class.igx-list-empty',] }],
cssClass: [{ type: HostBinding, args: ['class.igx-list',] }]
};
if (false) {
/**
* Returns a collection of all items and headers in the list.
* ```typescript
* let listChildren: QueryList = this.list.children;
* ```
* \@memberof IgxListComponent
* @type {?}
*/
IgxListComponent.prototype.children;
/**
* Returns the template which will be used by the IgxList in case there are no list items defined and `isLoading` is set to `false`.
* ```typescript
* let emptyTemplate = this.list.emptyListTemplate;
* ```
* \@memberof IgxListComponent
* @type {?}
*/
IgxListComponent.prototype.emptyListTemplate;
/**
* Returns the template which will be used by the IgxList in case there are no list items defined and `isLoading` is set to `true`.
* ```typescript
* let loadingTemplate = this.list.dataLoadingTemplate;
* ```
* \@memberof IgxListComponent
* @type {?}
*/
IgxListComponent.prototype.dataLoadingTemplate;
/**
* Sets/gets the template shown when left panning a list item.
* Default value is `null`.
* ```html
* <igx-list [allowLeftPanning] = "true"></igx-list>
* ```
* ```typescript
* let itemLeftPanTmpl = this.list.listItemLeftPanningTemplate;
* ```
* \@memberof IgxListComponent
* @type {?}
*/
IgxListComponent.prototype.listItemLeftPanningTemplate;
/**
* Sets/gets the template shown when right panning a list item.
* Default value is `null`.
* ```html
* <igx-list [allowLeftPanning] = "true"></igx-list>
* ```
* ```typescript
* let itemRightPanTmpl = this.list.listItemRightPanningTemplate;
* ```
* \@memberof IgxListComponent
* @type {?}
*/
IgxListComponent.prototype.listItemRightPanningTemplate;
/**
* 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;
* ```
* @type {?}
*/
IgxListComponent.prototype.panEndTriggeringThreshold;
/**
* @hidden
* @type {?}
* @protected
*/
IgxListComponent.prototype.defaultEmptyListTemplate;
/**
* @hidden
* @type {?}
* @protected
*/
IgxListComponent.prototype.defaultDataLoadingTemplate;
/**
* 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
* @type {?}
*/
IgxListComponent.prototype.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
* @type {?}
*/
IgxListComponent.prototype.allowLeftPanning;
/**
* 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
* @type {?}
*/
IgxListComponent.prototype.allowRightPanning;
/**
* 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
* @type {?}
*/
IgxListComponent.prototype.isLoading;
/**
* 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
* @type {?}
*/
IgxListComponent.prototype.onLeftPan;
/**
* 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
* @type {?}
*/
IgxListComponent.prototype.onRightPan;
/**
* 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
* @type {?}
*/
IgxListComponent.prototype.onPanStateChange;
/**
* 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
* @type {?}
*/
IgxListComponent.prototype.onItemClicked;
/** @type {?} */
IgxListComponent.prototype.element;
}
/**
* @hidden
*/
export class IgxListModule {
}
IgxListModule.decorators = [
{ type: NgModule, args: [{
declarations: [IgxListComponent, IgxListItemComponent,
IgxDataLoadingTemplateDirective, IgxEmptyListTemplateDirective,
IgxListItemLeftPanningTemplateDirective, IgxListItemRightPanningTemplateDirective],
exports: [IgxListComponent, IgxListItemComponent,
IgxDataLoadingTemplateDirective, IgxEmptyListTemplateDirective,
IgxListItemLeftPanningTemplateDirective, IgxListItemRightPanningTemplateDirective],
imports: [CommonModule, IgxRippleModule]
},] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2xpc3QvbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0gsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLEtBQUssRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxXQUFXLEVBQ1gsU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUV4RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM3RCxPQUFPLEVBQ0gsV0FBVyxFQUNYLCtCQUErQixFQUMvQiw2QkFBNkIsRUFFN0IsdUNBQXVDLEVBQ3ZDLHdDQUF3QyxFQUFDLE1BQU0sZUFBZSxDQUFDOztJQUUvRCxPQUFPLEdBQUcsQ0FBQzs7OztBQUNmLDhDQUlDOzs7SUFIRyw0Q0FBMEI7O0lBQzFCLDRDQUEwQjs7SUFDMUIsd0NBQTJCOzs7OztBQUcvQiw2Q0FJQzs7O0lBSEcsdUNBQTJCOztJQUMzQix3Q0FBYTs7SUFDYiw0Q0FBMkI7Ozs7O0FBRy9CLCtDQUlDOzs7SUFIRyx5Q0FBMkI7O0lBQzNCLDhDQUEyQjs7SUFDM0IsNkNBQWtCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBCdEIsTUFBTSxPQUFPLGdCQUFnQjs7OztJQUV6QixZQUFtQixPQUFtQjtRQUFuQixZQUFPLEdBQVAsT0FBTyxDQUFZOzs7Ozs7OztRQW1GL0IsOEJBQXlCLEdBQUcsR0FBRyxDQUFDOzs7Ozs7Ozs7Ozs7UUF1QmhDLE9BQUUsR0FBRyxZQUFZLE9BQU8sRUFBRSxFQUFFLENBQUM7Ozs7Ozs7Ozs7OztRQWM3QixxQkFBZ0IsR0FBRyxLQUFLLENBQUM7Ozs7Ozs7Ozs7OztRQWN6QixzQkFBaUIsR0FBRyxLQUFLLENBQUM7Ozs7Ozs7Ozs7Ozs7UUFlMUIsY0FBUyxHQUFHLEtBQUssQ0FBQzs7Ozs7Ozs7O1FBV2xCLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBNkIsQ0FBQzs7Ozs7Ozs7O1FBVzFELGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBNkIsQ0FBQzs7Ozs7Ozs7O1FBVzNELHFCQUFnQixHQUFHLElBQUksWUFBWSxFQUE0QixDQUFDOzs7Ozs7Ozs7UUFXaEUsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBMkIsQ0FBQztJQWhNbkUsQ0FBQzs7Ozs7OztJQWdCRCxJQUFjLGNBQWM7UUFDeEIsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRTtZQUM3QixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFO2lCQUN6QixJQUFJLENBQUMsQ0FBQyxDQUF1QixFQUFFLENBQXVCLEVBQUUsRUFBRTtnQkFDdkQsT0FBTyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7WUFDN0IsQ0FBQyxDQUFDLENBQUM7U0FDVjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7Ozs7Ozs7OztJQWlMRCxJQUNXLElBQUk7UUFDWCxPQUFPLE1BQU0sQ0FBQztJQUNsQixDQUFDOzs7Ozs7Ozs7SUFTRCxJQUNXLFdBQVc7UUFDbEIsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0lBQ3hELENBQUM7Ozs7Ozs7OztJQVNELElBQ1csUUFBUTtRQUNmLE9BQU8sSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDckQsQ0FBQzs7Ozs7Ozs7O0lBU0QsSUFBVyxLQUFLOztjQUNOLEtBQUssR0FBMkIsRUFBRTtRQUN4QyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFO1lBQzdCLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtnQkFDckMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7b0JBQ2pCLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3JCO2FBQ0o7U0FDSjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7Ozs7Ozs7OztJQVNELElBQVcsT0FBTzs7Y0FDUixPQUFPLEdBQTJCLEVBQUU7UUFDMUMsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRTtZQUM3QixLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3pDLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRTtvQkFDaEIsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDdkI7YUFDSjtTQUNKO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQzs7Ozs7Ozs7O0lBU0QsSUFBVyxPQUFPO1FBQ2QsT0FBTztZQUNILFNBQVMsRUFBRSxJQUFJO1NBQ2xCLENBQUM7SUFDTixDQUFDOzs7Ozs7Ozs7SUFTRCxJQUFXLFFBQVE7UUFDZixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQztTQUN6RzthQUFNO1lBQ0gsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQztTQUNuRztJQUNMLENBQUM7OztZQTlTSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLHdnQkFBa0M7Z0JBQ2xDLFNBQVMsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQzthQUN2RTs7OztZQWhFRyxVQUFVOzs7dUJBNkVULGVBQWUsU0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsb0JBQW9CLENBQUM7Z0NBd0J0RCxZQUFZLFNBQUMsNkJBQTZCLEVBQUUsRUFBRSxJQUFJLEVBQUUsNkJBQTZCLEVBQUU7a0NBVW5GLFlBQVksU0FBQywrQkFBK0IsRUFBRSxFQUFFLElBQUksRUFBRSwrQkFBK0IsRUFBRTswQ0FjdkYsWUFBWSxTQUFDLHVDQUF1QyxFQUFFLEVBQUUsSUFBSSxFQUFFLHVDQUF1QyxFQUFFOzJDQWN2RyxZQUFZLFNBQUMsd0NBQXdDLEVBQUUsRUFBRSxJQUFJLEVBQUUsd0NBQXdDLEVBQUU7d0NBVXpHLEtBQUs7dUNBSUwsU0FBUyxTQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRTt5Q0FJbkQsU0FBUyxTQUFDLG9CQUFvQixFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRTtpQkFjckQsV0FBVyxTQUFDLFNBQVMsY0FDckIsS0FBSzsrQkFjTCxLQUFLO2dDQWNMLEtBQUs7d0JBZUwsS0FBSzt3QkFXTCxNQUFNO3lCQVdOLE1BQU07K0JBV04sTUFBTTs0QkFXTixNQUFNO21CQVVOLFdBQVcsU0FBQyxXQUFXOzBCQVl2QixXQUFXLFNBQUMsc0JBQXNCO3VCQVlsQyxXQUFXLFNBQUMsZ0JBQWdCOzs7Ozs7Ozs7OztJQXhON0Isb0NBQ2lEOzs7Ozs7Ozs7SUF1QmpELDZDQUN3RDs7Ozs7Ozs7O0lBU3hELCtDQUM0RDs7Ozs7Ozs7Ozs7OztJQWE1RCx1REFDNEU7Ozs7Ozs7Ozs7Ozs7SUFhNUUsd0RBQzhFOzs7Ozs7Ozs7SUFTOUUscURBQ3VDOzs7Ozs7SUFHdkMsb0RBQ3FEOzs7Ozs7SUFHckQsc0RBQ3VEOzs7Ozs7Ozs7Ozs7O0lBYXZELDhCQUVvQzs7Ozs7Ozs7Ozs7OztJQWFwQyw0Q0FDZ0M7Ozs7Ozs7Ozs7Ozs7SUFhaEMsNkNBQ2lDOzs7Ozs7Ozs7Ozs7OztJQWNqQyxxQ0FDeUI7Ozs7Ozs7Ozs7SUFVekIscUNBQ2lFOzs7Ozs7Ozs7O0lBVWpFLHNDQUNrRTs7Ozs7Ozs7OztJQVVsRSw0Q0FDdUU7Ozs7Ozs7Ozs7SUFVdkUseUNBQ21FOztJQWpNdkQsbUNBQTBCOzs7OztBQXNUMUMsTUFBTSxPQUFPLGFBQWE7OztZQVR6QixRQUFRLFNBQUM7Z0JBQ04sWUFBWSxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsb0JBQW9CO29CQUNqRCwrQkFBK0IsRUFBRSw2QkFBNkI7b0JBQzlELHVDQUF1QyxFQUFFLHdDQUF3QyxDQUFDO2dCQUN0RixPQUFPLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxvQkFBb0I7b0JBQzVDLCtCQUErQixFQUFFLDZCQUE2QjtvQkFDOUQsdUNBQXVDLEVBQUUsd0NBQXdDLENBQUM7Z0JBQ3RGLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxlQUFlLENBQUM7YUFDM0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgQ29udGVudENoaWxkLFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBmb3J3YXJkUmVmLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE91dHB1dCxcbiAgICBRdWVyeUxpc3QsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBJZ3hSaXBwbGVNb2R1bGUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3JpcHBsZS9yaXBwbGUuZGlyZWN0aXZlJztcblxuaW1wb3J0IHsgSWd4TGlzdEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2xpc3QtaXRlbS5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgICBJZ3hMaXN0QmFzZSxcbiAgICBJZ3hEYXRhTG9hZGluZ1RlbXBsYXRlRGlyZWN0aXZlLFxuICAgIElneEVtcHR5TGlzdFRlbXBsYXRlRGlyZWN0aXZlLFxuICAgIElneExpc3RQYW5TdGF0ZSxcbiAgICBJZ3hMaXN0SXRlbUxlZnRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmUsXG4gICAgSWd4TGlzdEl0ZW1SaWdodFBhbm5pbmdUZW1wbGF0ZURpcmVjdGl2ZX0gZnJvbSAnLi9saXN0LmNvbW1vbic7XG5cbmxldCBORVhUX0lEID0gMDtcbmV4cG9ydCBpbnRlcmZhY2UgSVBhblN0YXRlQ2hhbmdlRXZlbnRBcmdzIHtcbiAgICBvbGRTdGF0ZTogSWd4TGlzdFBhblN0YXRlO1xuICAgIG5ld1N0YXRlOiBJZ3hMaXN0UGFuU3RhdGU7XG4gICAgaXRlbTogSWd4TGlzdEl0ZW1Db21wb25lbnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUxpc3RJdGVtQ2xpY2tFdmVudEFyZ3Mge1xuICAgIGl0ZW06IElneExpc3RJdGVtQ29tcG9uZW50O1xuICAgIGV2ZW50OiBFdmVudDtcbiAgICBkaXJlY3Rpb246IElneExpc3RQYW5TdGF0ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJTGlzdEl0ZW1QYW5uaW5nRXZlbnRBcmdzIHtcbiAgICBpdGVtOiBJZ3hMaXN0SXRlbUNvbXBvbmVudDtcbiAgICBkaXJlY3Rpb246IElneExpc3RQYW5TdGF0ZTtcbiAgICBrZWVwSXRlbTogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiAqKklnbml0ZSBVSSBmb3IgQW5ndWxhciBMaXN0KiogLVxuICogW0RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LmluZnJhZ2lzdGljcy5jb20vcHJvZHVjdHMvaWduaXRlLXVpLWFuZ3VsYXIvYW5ndWxhci9jb21wb25lbnRzL2xpc3QuaHRtbClcbiAqXG4gKiBUaGUgSWduaXRlIFVJIExpc3QgZGlzcGxheXMgcm93cyBvZiBpdGVtcyBhbmQgc3VwcG9ydHMgb25lIG9yIG1vcmUgaGVhZGVyIGl0ZW1zIGFzIHdlbGwgYXMgc2VhcmNoIGFuZCBmaWx0ZXJpbmdcbiAqIG9mIGxpc3QgaXRlbXMuIEVhY2ggbGlzdCBpdGVtIGlzIGNvbXBsZXRlbHkgdGVtcGxhdGVhYmxlIGFuZCB3aWxsIHN1cHBvcnQgYW55IHZhbGlkIEhUTUwgb3IgQW5ndWxhciBjb21wb25lbnQuXG4gKlxuICogRXhhbXBsZTpcbiAqIGBgYGh0bWxcbiAqIDxpZ3gtbGlzdD5cbiAqICAgPGlneC1saXN0LWl0ZW0gaXNIZWFkZXI9XCJ0cnVlXCI+Q29udGFjdHM8L2lneC1saXN0LWl0ZW0+XG4gKiAgIDxpZ3gtbGlzdC1pdGVtICpuZ0Zvcj1cImxldCBjb250YWN0IG9mIGNvbnRhY3RzXCI+XG4gKiAgICAgPHNwYW4gY2xhc3M9XCJuYW1lXCI+e3sgY29udGFjdC5uYW1lIH19PC9zcGFuPlxuICogICAgIDxzcGFuIGNsYXNzPVwicGhvbmVcIj57eyBjb250YWN0LnBob25lIH19PC9zcGFuPlxuICogICA8L2lneC1saXN0LWl0ZW0+XG4gKiA8L2lneC1saXN0PlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LWxpc3QnLFxuICAgIHRlbXBsYXRlVXJsOiAnbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBJZ3hMaXN0QmFzZSwgdXNlRXhpc3Rpbmc6IElneExpc3RDb21wb25lbnQgfV1cbn0pXG5leHBvcnQgY2xhc3MgSWd4TGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIElneExpc3RCYXNlIHtcblxuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBlbGVtZW50OiBFbGVtZW50UmVmKSB7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGNvbGxlY3Rpb24gb2YgYWxsIGl0ZW1zIGFuZCBoZWFkZXJzIGluIHRoZSBsaXN0LlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbGlzdENoaWxkcmVuOiBRdWVyeUxpc3QgPSB0aGlzLmxpc3QuY2hpbGRyZW47XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4TGlzdEl0ZW1Db21wb25lbnQpKVxuICAgIHB1YmxpYyBjaGlsZHJlbjogUXVlcnlMaXN0PElneExpc3RJdGVtQ29tcG9uZW50PjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZ2V0IHNvcnRlZENoaWxkcmVuKCk6IElneExpc3RJdGVtQ29tcG9uZW50W10ge1xuICAgICAgICBpZiAodGhpcy5jaGlsZHJlbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi50b0FycmF5KClcbiAgICAgICAgICAgICAgICAuc29ydCgoYTogSWd4TGlzdEl0ZW1Db21wb25lbnQsIGI6IElneExpc3RJdGVtQ29tcG9uZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhLmluZGV4IC0gYi5pbmRleDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0ZW1wbGF0ZSB3aGljaCB3aWxsIGJlIHVzZWQgYnkgdGhlIElneExpc3QgaW4gY2FzZSB0aGVyZSBhcmUgbm8gbGlzdCBpdGVtcyBkZWZpbmVkIGFuZCBgaXNMb2FkaW5nYCBpcyBzZXQgdG8gYGZhbHNlYC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGVtcHR5VGVtcGxhdGUgPSB0aGlzLmxpc3QuZW1wdHlMaXN0VGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkKElneEVtcHR5TGlzdFRlbXBsYXRlRGlyZWN0aXZlLCB7IHJlYWQ6IElneEVtcHR5TGlzdFRlbXBsYXRlRGlyZWN0aXZlIH0pXG4gICAgcHVibGljIGVtcHR5TGlzdFRlbXBsYXRlOiBJZ3hFbXB0eUxpc3RUZW1wbGF0ZURpcmVjdGl2ZTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRlbXBsYXRlIHdoaWNoIHdpbGwgYmUgdXNlZCBieSB0aGUgSWd4TGlzdCBpbiBjYXNlIHRoZXJlIGFyZSBubyBsaXN0IGl0ZW1zIGRlZmluZWQgYW5kIGBpc0xvYWRpbmdgIGlzIHNldCB0byBgdHJ1ZWAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBsb2FkaW5nVGVtcGxhdGUgPSB0aGlzLmxpc3QuZGF0YUxvYWRpbmdUZW1wbGF0ZTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGQoSWd4RGF0YUxvYWRpbmdUZW1wbGF0ZURpcmVjdGl2ZSwgeyByZWFkOiBJZ3hEYXRhTG9hZGluZ1RlbXBsYXRlRGlyZWN0aXZlIH0pXG4gICAgcHVibGljIGRhdGFMb2FkaW5nVGVtcGxhdGU6IElneERhdGFMb2FkaW5nVGVtcGxhdGVEaXJlY3RpdmU7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzL2dldHMgdGhlIHRlbXBsYXRlIHNob3duIHdoZW4gbGVmdCBwYW5uaW5nIGEgbGlzdCBpdGVtLlxuICAgICAqIERlZmF1bHQgdmFsdWUgaXMgYG51bGxgLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiAgPGlneC1saXN0IFthbGxvd0xlZnRQYW5uaW5nXSA9IFwidHJ1ZVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBpdGVtTGVmdFBhblRtcGwgPSB0aGlzLmxpc3QubGlzdEl0ZW1MZWZ0UGFubmluZ1RlbXBsYXRlO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hMaXN0Q29tcG9uZW50XG4gICAgICovXG4gICAgQENvbnRlbnRDaGlsZChJZ3hMaXN0SXRlbUxlZnRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmUsIHsgcmVhZDogSWd4TGlzdEl0ZW1MZWZ0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlIH0pXG4gICAgcHVibGljIGxpc3RJdGVtTGVmdFBhbm5pbmdUZW1wbGF0ZTogSWd4TGlzdEl0ZW1MZWZ0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlO1xuXG4gICAgLyoqXG4gICAgICogU2V0cy9nZXRzIHRoZSB0ZW1wbGF0ZSBzaG93biB3aGVuIHJpZ2h0IHBhbm5pbmcgYSBsaXN0IGl0ZW0uXG4gICAgICogRGVmYXVsdCB2YWx1ZSBpcyBgbnVsbGAuXG4gICAgICogYGBgaHRtbFxuICAgICAqICA8aWd4LWxpc3QgW2FsbG93TGVmdFBhbm5pbmddID0gXCJ0cnVlXCI+PC9pZ3gtbGlzdD5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGl0ZW1SaWdodFBhblRtcGwgPSB0aGlzLmxpc3QubGlzdEl0ZW1SaWdodFBhbm5pbmdUZW1wbGF0ZTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGQoSWd4TGlzdEl0ZW1SaWdodFBhbm5pbmdUZW1wbGF0ZURpcmVjdGl2ZSwgeyByZWFkOiBJZ3hMaXN0SXRlbVJpZ2h0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlIH0pXG4gICAgcHVibGljIGxpc3RJdGVtUmlnaHRQYW5uaW5nVGVtcGxhdGU6IElneExpc3RJdGVtUmlnaHRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmU7XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhIHRocmVzaG9sZCBhZnRlciB3aGljaCB0aGUgaXRlbSdzIHBhbm5pbmcgd2lsbCBiZSBjb21wbGV0ZWQgYXV0b21hdGljYWxseS5cbiAgICAgKiBCeSBkZWZhdWx0IHRoaXMgcHJvcGVydHkgaXMgc2V0IHRvIDAuNSB3aGljaCBpcyA1MCUgb2YgdGhlIGxpc3QgaXRlbSdzIHdpZHRoLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmxpc3QucGFuRW5kVHJpZ2dlcmluZ1RocmVzaG9sZCA9IDAuODtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBwYW5FbmRUcmlnZ2VyaW5nVGhyZXNob2xkID0gMC41O1xuXG4gICAgLyoqQGhpZGRlbiovXG4gICAgQFZpZXdDaGlsZCgnZGVmYXVsdEVtcHR5TGlzdCcsIHsgcmVhZDogVGVtcGxhdGVSZWYgfSlcbiAgICBwcm90ZWN0ZWQgZGVmYXVsdEVtcHR5TGlzdFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgLyoqQGhpZGRlbiovXG4gICAgQFZpZXdDaGlsZCgnZGVmYXVsdERhdGFMb2FkaW5nJywgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICAgIHByb3RlY3RlZCBkZWZhdWx0RGF0YUxvYWRpbmdUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB0aGUgYGlkYCBvZiB0aGUgbGlzdC5cbiAgICAgKiBJZiBub3Qgc2V0LCB0aGUgYGlkYCBvZiB0aGUgZmlyc3QgbGlzdCBjb21wb25lbnQgd2lsbCBiZSBgXCJpZ3gtbGlzdC0wXCJgLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWxpc3QgaWQgPSBcIm15LWZpcnN0LWxpc3RcIj48L2lneC1saXN0PlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbGlzdElkID0gIHRoaXMubGlzdC5pZDtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5pZCcpXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgaWQgPSBgaWd4LWxpc3QtJHtORVhUX0lEKyt9YDtcblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB3aGV0aGVyIHRoZSBsZWZ0IHBhbm5pbmcgb2YgYW4gaXRlbSBpcyBhbGxvd2VkLlxuICAgICAqIERlZmF1bHQgdmFsdWUgaXMgYGZhbHNlYC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogIDxpZ3gtbGlzdCBbYWxsb3dMZWZ0UGFubmluZ10gPSBcInRydWVcIj48L2lneC1saXN0PlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXNMZWZ0UGFubmluZ0FsbG93ZWQgPSB0aGlzLmxpc3QuYWxsb3dMZWZ0UGFubmluZztcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGFsbG93TGVmdFBhbm5pbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB3aGV0aGVyIHRoZSByaWdodCBwYW5uaW5nIG9mIGFuIGl0ZW0gaXMgYWxsb3dlZC5cbiAgICAgKiBEZWZhdWx0IHZhbHVlIGlzIGBmYWxzZWAuXG4gICAgICogYGBgaHRtbFxuICAgICAqICA8aWd4LWxpc3QgW2FsbG93UmlnaHRQYW5uaW5nXSA9IFwidHJ1ZVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBpc1JpZ2h0UGFubmluZ0FsbG93ZWQgPSB0aGlzLmxpc3QuYWxsb3dSaWdodFBhbm5pbmc7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBhbGxvd1JpZ2h0UGFubmluZyA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogU2V0cy9nZXRzIHdoZXRoZXIgdGhlIGxpc3QgaXMgY3VycmVudGx5IGxvYWRpbmcgZGF0YS5cbiAgICAgKiBTZXQgaXQgdG8gZGlzcGxheSB0aGUgZGF0YUxvYWRpbmdUZW1wbGF0ZSB3aGlsZSBkYXRhIGlzIGJlaW5nIHJldHJpZXZlZC5cbiAgICAgKiBEZWZhdWx0IHZhbHVlIGlzIGBmYWxzZWAuXG4gICAgICogYGBgaHRtbFxuICAgICAqICA8aWd4LWxpc3QgW2lzTG9hZGluZ109XCJ0cnVlXCI+PC9pZ3gtbGlzdD5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGlzTG9hZGluZyA9IHRoaXMubGlzdC5pc0xvYWRpbmc7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpc0xvYWRpbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IHdpdGhpbiB0aGUgY3VycmVudCBsaXN0IHdoZW4gbGVmdCBwYW4gZ2VzdHVyZSBpcyBleGVjdXRlZCBvbiBhIGxpc3QgaXRlbS5cbiAgICAgKiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3Qgb2YgdHlwZSBgSUxpc3RJdGVtUGFubmluZ0V2ZW50QXJnc2AgYXMgYW4gZXZlbnQgYXJndW1lbnQuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtbGlzdCBbYWxsb3dMZWZ0UGFubmluZ109XCJ0cnVlXCIgKG9uTGVmdFBhbik9XCJvbkxlZnRQYW4oJGV2ZW50KVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25MZWZ0UGFuID0gbmV3IEV2ZW50RW1pdHRlcjxJTGlzdEl0ZW1QYW5uaW5nRXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgd2l0aGluIHRoZSBjdXJyZW50IGxpc3Qgd2hlbiByaWdodCBwYW4gZ2VzdHVyZSBpcyBleGVjdXRlZCBvbiBhIGxpc3QgaXRlbS5cbiAgICAgKiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3Qgb2YgdHlwZSBgSUxpc3RJdGVtUGFubmluZ0V2ZW50QXJnc2AgYXMgYW4gZXZlbnQgYXJndW1lbnQuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtbGlzdCBbYWxsb3dSaWdodFBhbm5pbmddPVwidHJ1ZVwiIChvblJpZ2h0UGFuKT1cIm9uUmlnaHRQYW4oJGV2ZW50KVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25SaWdodFBhbiA9IG5ldyBFdmVudEVtaXR0ZXI8SUxpc3RJdGVtUGFubmluZ0V2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICogRW1pdHMgYW4gZXZlbnQgd2l0aGluIHRoZSBjdXJyZW50IGxpc3Qgd2hlbiBwYW4gZ2VzdHVyZSBpcyBleGVjdXRlZCBvbiBsaXN0IGl0ZW0uXG4gICAgKiBQcm92aWRlcyByZWZlcmVuY2VzIHRvIHRoZSBgSWd4TGlzdEl0ZW1Db21wb25lbnRgIGFuZCBgSWd4TGlzdFBhblN0YXRlYCBhcyBldmVudCBhcmd1bWVudHMuXG4gICAgKiBgYGBodG1sXG4gICAgKiA8aWd4LWxpc3QgKG9uUGFuU3RhdGVDaGFuZ2UpID0gXCJvblBhblN0YXRlQ2hhbmdlKCRldmVudClcIj48L2lneC1saXN0PlxuICAgICogYGBgXG4gICAgKiBAbWVtYmVyb2YgSWd4TGlzdENvbXBvbmVudFxuICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uUGFuU3RhdGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPElQYW5TdGF0ZUNoYW5nZUV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IHdpdGhpbiB0aGUgY3VycmVudCBsaXN0IHdoZW4gYSBsaXN0IGl0ZW0gaGFzIGJlZW4gY2xpY2tlZC5cbiAgICAgKiBQcm92aWRlcyByZWZlcmVuY2VzIHRvIHRoZSBgSWd4TGlzdEl0ZW1Db21wb25lbnRgIGFuZCBgRXZlbnRgIGFzIGV2ZW50IGFyZ3VtZW50cy5cbiAgICAgKiAgYGBgaHRtbFxuICAgICAqIDxpZ3gtbGlzdCAob25JdGVtQ2xpY2tlZCkgPSBcIm9uSXRlbUNsaWNrZWQoJGV2ZW50KVwiPjwvaWd4LWxpc3Q+XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25JdGVtQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8SUxpc3RJdGVtQ2xpY2tFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgcm9sZWAgYXR0cmlidXRlLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbGlzdFJvbGUgPSAgdGhpcy5saXN0LnJvbGU7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIucm9sZScpXG4gICAgcHVibGljIGdldCByb2xlKCkge1xuICAgICAgICByZXR1cm4gJ2xpc3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBsaXN0IGlzIGVtcHR5LlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXNFbXB0eSA9ICB0aGlzLmxpc3QuaXNMaXN0RW1wdHk7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1saXN0LWVtcHR5JylcbiAgICBwdWJsaWMgZ2V0IGlzTGlzdEVtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIXRoaXMuY2hpbGRyZW4gfHwgdGhpcy5jaGlsZHJlbi5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIGxpc3QgaGFzIGEgYGNzc0NsYXNzYCBhdHRyaWJ1dGUuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBoYXNDc3NDbGFzcyA9ICB0aGlzLmxpc3QuY3NzQ2xhc3M7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1saXN0JylcbiAgICBwdWJsaWMgZ2V0IGNzc0NsYXNzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbiAmJiB0aGlzLmNoaWxkcmVuLmxlbmd0aCA+IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYGl0ZW1zYCBpbiB0aGUgbGlzdCBleGNsdWRpbmcgdGhlIGhlYWRlcnMuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBsaXN0SXRlbXM6IElneExpc3RJdGVtQ29tcG9uZW50W10gPSB0aGlzLmxpc3QuaXRlbXM7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGl0ZW1zKCk6IElneExpc3RJdGVtQ29tcG9uZW50W10ge1xuICAgICAgICBjb25zdCBpdGVtczogSWd4TGlzdEl0ZW1Db21wb25lbnRbXSA9IFtdO1xuICAgICAgICBpZiAodGhpcy5jaGlsZHJlbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuc29ydGVkQ2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNoaWxkLmlzSGVhZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goY2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGVhZGVycyBpbiB0aGUgbGlzdC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGxpc3RIZWFkZXJzOiBJZ3hMaXN0SXRlbUNvbXBvbmVudFtdID0gIHRoaXMubGlzdC5oZWFkZXJzO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hMaXN0Q29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGdldCBoZWFkZXJzKCk6IElneExpc3RJdGVtQ29tcG9uZW50W10ge1xuICAgICAgICBjb25zdCBoZWFkZXJzOiBJZ3hMaXN0SXRlbUNvbXBvbmVudFtdID0gW107XG4gICAgICAgIGlmICh0aGlzLmNoaWxkcmVuICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbi50b0FycmF5KCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNIZWFkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVycy5wdXNoKGNoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhlYWRlcnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYGNvbnRleHRgIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBgdGVtcGxhdGUgY29udGV4dGAgYmluZGluZyBpbnRvIHRoZSBgbGlzdCBjb250YWluZXJgXG4gICAgICogYnkgcHJvdmlkaW5nIHRoZSBgJGltcGxpY2l0YCBkZWNsYXJhdGlvbiB3aGljaCBpcyB0aGUgYElneExpc3RDb21wb25lbnRgIGl0c2VsZi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGxpc3RDb21wb25lbnQgPSAgdGhpcy5saXN0LmNvbnRleHQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBjb250ZXh0KCk6IGFueSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAkaW1wbGljaXQ6IHRoaXNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgdGVtcGxhdGVgIG9mIGFuIGVtcHR5IGxpc3QuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBsaXN0VGVtcGxhdGUgPSB0aGlzLmxpc3QudGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneExpc3RDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xuICAgICAgICBpZiAodGhpcy5pc0xvYWRpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGFMb2FkaW5nVGVtcGxhdGUgPyB0aGlzLmRhdGFMb2FkaW5nVGVtcGxhdGUudGVtcGxhdGUgOiB0aGlzLmRlZmF1bHREYXRhTG9hZGluZ1RlbXBsYXRlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1wdHlMaXN0VGVtcGxhdGUgPyB0aGlzLmVtcHR5TGlzdFRlbXBsYXRlLnRlbXBsYXRlIDogdGhpcy5kZWZhdWx0RW1wdHlMaXN0VGVtcGxhdGU7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5ATmdNb2R1bGUoe1xuICAgIGRlY2xhcmF0aW9uczogW0lneExpc3RDb21wb25lbnQsIElneExpc3RJdGVtQ29tcG9uZW50LFxuICAgICAgICBJZ3hEYXRhTG9hZGluZ1RlbXBsYXRlRGlyZWN0aXZlLCBJZ3hFbXB0eUxpc3RUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4TGlzdEl0ZW1MZWZ0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlLCBJZ3hMaXN0SXRlbVJpZ2h0UGFubmluZ1RlbXBsYXRlRGlyZWN0aXZlXSxcbiAgICBleHBvcnRzOiBbSWd4TGlzdENvbXBvbmVudCwgSWd4TGlzdEl0ZW1Db21wb25lbnQsXG4gICAgICAgIElneERhdGFMb2FkaW5nVGVtcGxhdGVEaXJlY3RpdmUsIElneEVtcHR5TGlzdFRlbXBsYXRlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMaXN0SXRlbUxlZnRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmUsIElneExpc3RJdGVtUmlnaHRQYW5uaW5nVGVtcGxhdGVEaXJlY3RpdmVdLFxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIElneFJpcHBsZU1vZHVsZV1cbn0pXG5leHBvcnQgY2xhc3MgSWd4TGlzdE1vZHVsZSB7XG59XG4iXX0=