UNPKG

igniteui-angular

Version:

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

774 lines • 57.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ChangeDetectorRef, EventEmitter, ElementRef, HostBinding, Input, Output, ViewChild, Renderer2, TemplateRef, Inject, Optional } from '@angular/core'; import { DisplayDensityToken, DisplayDensityBase } from '../core/displayDensity'; import { IgxDragDirective } from '../directives/dragdrop/dragdrop.directive'; /** * @record */ export function IBaseChipEventArgs() { } if (false) { /** @type {?} */ IBaseChipEventArgs.prototype.originalEvent; /** @type {?} */ IBaseChipEventArgs.prototype.owner; } /** * @record */ export function IChipClickEventArgs() { } if (false) { /** @type {?} */ IChipClickEventArgs.prototype.cancel; } /** * @record */ export function IChipKeyDownEventArgs() { } if (false) { /** @type {?} */ IChipKeyDownEventArgs.prototype.originalEvent; /** @type {?} */ IChipKeyDownEventArgs.prototype.cancel; } /** * @record */ export function IChipEnterDragAreaEventArgs() { } if (false) { /** @type {?} */ IChipEnterDragAreaEventArgs.prototype.dragChip; } /** * @record */ export function IChipSelectEventArgs() { } if (false) { /** @type {?} */ IChipSelectEventArgs.prototype.cancel; /** @type {?} */ IChipSelectEventArgs.prototype.selected; } /** @type {?} */ let CHIP_ID = 0; export class IgxChipComponent extends DisplayDensityBase { /** * @param {?} cdr * @param {?} elementRef * @param {?} renderer * @param {?} _displayDensityOptions */ constructor(cdr, elementRef, renderer, _displayDensityOptions) { super(_displayDensityOptions); this.cdr = cdr; this.elementRef = elementRef; this.renderer = renderer; this._displayDensityOptions = _displayDensityOptions; /** * An \@Input property that sets the value of `id` attribute. If not provided it will be automatically generated. * ```html * <igx-chip [id]="'igx-chip-1'"></igx-chip> * ``` */ this.id = `igx-chip-${CHIP_ID++}`; /** * An \@Input property that defines if the `IgxChipComponent` can be dragged in order to change it's position. * By default it is set to false. * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true"></igx-chip> * ``` */ this.draggable = false; /** * An \@Input property that defines if the `IgxChipComponent` should render remove button and throw remove events. * By default it is set to false. * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [removable]="true"></igx-chip> * ``` */ this.removable = false; /** * An \@Input property that defines if the `IgxChipComponent` can be selected on click or through navigation, * By default it is set to false. * ```html * <igx-chip [id]="chip.id" [draggable]="true" [removable]="true" [selectable]="true"></igx-chip> * ``` */ this.selectable = false; /** * @hidden */ this.class = ''; /** * An \@Input property that defines if the `IgxChipComponent` is disabled. When disabled it restricts user interactions * like focusing on click or tab, selection on click or Space, dragging. * By default it is set to false. * ```html * <igx-chip [id]="chip.id" [disabled]="true"></igx-chip> * ``` */ this.disabled = false; /** * Emits an event when the `IgxChipComponent` moving starts. * Returns the moving `IgxChipComponent`. * ```typescript * moveStarted(event: IBaseChipEventArgs){ * let movingChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onMoveStart)="moveStarted($event)"> * ``` */ this.onMoveStart = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` moving ends. * Returns the moved `IgxChipComponent`. * ```typescript * moveEnded(event: IBaseChipEventArgs){ * let movedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onMoveEnd)="moveEnded($event)"> * ``` */ this.onMoveEnd = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` is removed. * Returns the removed `IgxChipComponent`. * ```typescript * remove(event: IBaseChipEventArgs){ * let removedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onRemove)="remove($event)"> * ``` */ this.onRemove = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` is clicked. * Returns the clicked `IgxChipComponent`, whether the event should be canceled. * ```typescript * chipClick(event: IChipClickEventArgs){ * let clickedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onClick)="chipClick($event)"> * ``` */ this.onClick = new EventEmitter(); /** * Emits event when the `IgxChipComponent` is selected/deselected. * Returns the selected chip reference, whether the event should be canceled, what is the next selection state and * when the event is triggered by interaction `originalEvent` is provided, otherwise `originalEvent` is `null`. * ```typescript * chipSelect(event: IChipSelectEventArgs){ * let selectedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onSelection)="chipSelect($event)"> * ``` */ this.onSelection = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` keyboard navigation is being used. * Returns the focused/selected `IgxChipComponent`, whether the event should be canceled, * if the `alt`, `shift` or `control` key is pressed and the pressed key name. * ```typescript * chipKeyDown(event: IChipKeyDownEventArgs){ * let keyDown = event.key; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onKeyDown)="chipKeyDown($event)"> * ``` */ this.onKeyDown = new EventEmitter(); /** * Emits an event when the `IgxChipComponent` has entered the `IgxChipsAreaComponent`. * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as well as * the original drop event arguments. * ```typescript * chipEnter(event: IChipEnterDragAreaEventArgs){ * let targetChip = event.targetChip; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onDragEnter)="chipEnter($event)"> * ``` */ this.onDragEnter = new EventEmitter(); this._selected = false; this._selectedItemClass = 'igx-chip__item--selected'; this._movedWhileRemoving = false; } /** * Sets the `IgxChipComponent` selected state. * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" [selected]="true"> * ``` * @param {?} newValue * @return {?} */ set selected(newValue) { this.changeSelection(newValue); } /** * Returns if the `IgxChipComponent` is selected. * ```typescript * \@ViewChild('myChip') * public chip: IgxChipComponent; * selectedChip(){ * let selectedChip = this.chip.selected; * } * ``` * @return {?} */ get selected() { return this._selected; } /** * An \@Input property that sets the `IgxChipComponent` background color. * The `color` property supports string, rgb, hex. * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [color]="'#ff0000'"></igx-chip> * ``` * @param {?} newColor * @return {?} */ set color(newColor) { this.chipArea.nativeElement.style.backgroundColor = newColor; } /** * Returns the background color of the `IgxChipComponent`. * ```typescript * \@ViewChild('myChip') * public chip: IgxChipComponent; * ngAfterViewInit(){ * let chipColor = this.chip.color; * } * ``` * @return {?} */ get color() { return this.chipArea.nativeElement.style.backgroundColor; } /** * @hidden * @return {?} */ get hostClass() { /** @type {?} */ const classes = [this.getComponentDensityClass('igx-chip')]; classes.push(this.disabled ? 'igx-chip--disabled' : ''); // The custom classes should be at the end. classes.push(this.class); return classes.join(' '); } /** * @hidden * @return {?} */ get removeButtonTemplate() { return this.removeIcon || this.defaultRemoveIcon; } /** * @hidden * @return {?} */ get selectIconTemplate() { return this.selectIcon || this.defaultSelectIcon; } /** * @hidden * @return {?} */ get ghostClass() { return this.getComponentDensityClass('igx-chip__ghost'); } /** * @return {?} */ get chipTabindex() { return !this.disabled ? 0 : ''; } /** * @hidden * @param {?} condition * @return {?} */ selectClass(condition) { /** @type {?} */ const SELECT_CLASS = 'igx-chip__select'; return { [SELECT_CLASS]: condition, [`${SELECT_CLASS}--hidden`]: !condition }; } /** * @protected * @param {?} newValue * @param {?=} srcEvent * @return {?} */ changeSelection(newValue, srcEvent = null) { /** @type {?} */ const onSelectArgs = { originalEvent: srcEvent, owner: this, selected: false, cancel: false }; if (newValue && !this._selected) { onSelectArgs.selected = true; this.onSelection.emit(onSelectArgs); if (!onSelectArgs.cancel) { this.renderer.addClass(this.chipArea.nativeElement, this._selectedItemClass); this._selected = newValue; } } else if (!newValue && this._selected) { this.onSelection.emit(onSelectArgs); if (!onSelectArgs.cancel) { this.renderer.removeClass(this.chipArea.nativeElement, this._selectedItemClass); this._selected = newValue; } } } /** * @hidden * @param {?} event * @return {?} */ onChipKeyDown(event) { /** @type {?} */ const keyDownArgs = { originalEvent: event, owner: this, cancel: false }; this.onKeyDown.emit(keyDownArgs); if (keyDownArgs.cancel) { return; } if ((event.key === 'Delete' || event.key === 'Del') && this.removable) { this.onRemove.emit({ originalEvent: event, owner: this }); } if ((event.key === ' ' || event.key === 'Spacebar') && this.selectable && !this.disabled) { this.changeSelection(!this.selected, event); } if (event.key !== 'Tab') { event.preventDefault(); } } /** * @hidden * @param {?} event * @return {?} */ onRemoveBtnKeyDown(event) { if (event.key === ' ' || event.key === 'Spacebar' || event.key === 'Enter') { this.onRemove.emit({ originalEvent: event, owner: this }); event.preventDefault(); event.stopPropagation(); } } /** * @param {?} event * @return {?} */ onRemoveMouseDown(event) { event.stopPropagation(); } /** * @hidden * @param {?} event * @return {?} */ onRemoveClick(event) { this.onRemove.emit({ originalEvent: event, owner: this }); } /** * @hidden * @return {?} */ onRemoveTouchMove() { // We don't remove chip if user starting touch interacting on the remove button moves the chip this._movedWhileRemoving = true; } /** * @hidden * @param {?} event * @return {?} */ onRemoveTouchEnd(event) { if (!this._movedWhileRemoving) { this.onRemoveClick(event); } this._movedWhileRemoving = false; } /** * @hidden * @param {?} event * @return {?} */ // ----------------------------- // Start chip igxDrag behaviour onChipDragStart(event) { this.onMoveStart.emit({ originalEvent: event.originalEvent, owner: this }); event.cancel = !this.draggable || this.disabled; } /** * @hidden * @return {?} */ onChipDragEnd() { this.dragDir.dropFinished(); } /** * @hidden * @param {?} event * @return {?} */ onChipMoveEnd(event) { // moveEnd is triggered after return animation has finished. This happen when we drag and release the chip. this.onMoveEnd.emit({ originalEvent: event.originalEvent, owner: this }); if (this.selected) { this.chipArea.nativeElement.focus(); } } /** * @hidden * @param {?} event * @return {?} */ onChipDragClicked(event) { /** @type {?} */ const clickEventArgs = { originalEvent: event.originalEvent, owner: this, cancel: false }; this.onClick.emit(clickEventArgs); if (!clickEventArgs.cancel && this.selectable && !this.disabled) { this.changeSelection(!this.selected, event.originalEvent); } } // End chip igxDrag behaviour /** * @hidden * @param {?} event * @return {?} */ // ----------------------------- // Start chip igxDrop behaviour onChipDragEnterHandler(event) { if (this.dragDir === event.drag || !event.dragData || !event.dragData.chip) { return; } /** @type {?} */ const eventArgs = { owner: this, dragChip: event.dragData.chip, originalEvent: event }; this.onDragEnter.emit(eventArgs); } /** * @hidden * @param {?} event * @return {?} */ onChipDrop(event) { // Cancel the default drop logic event.cancel = true; } } IgxChipComponent.decorators = [ { type: Component, args: [{ selector: 'igx-chip', template: "<div #chipArea class=\"igx-chip__item\"\n [attr.tabindex]=\"chipTabindex\"\n (keydown)=\"onChipKeyDown($event)\"\n [igxDrag]=\"{chip: this}\"\n [hideBaseOnDrag]=\"true\"\n [animateOnRelease]=\"true\"\n [ghostImageClass]=\"ghostClass\"\n (dragStart)=\"onChipDragStart($event)\"\n (dragEnd)=\"onChipDragEnd()\"\n (returnMoveEnd)=\"onChipMoveEnd($event)\"\n (dragClicked)=\"onChipDragClicked($event)\"\n igxDrop\n (onEnter)=\"onChipDragEnterHandler($event)\"\n (onDrop)=\"onChipDrop($event)\">\n\n <div [ngClass]=\"selectClass(selected)\">\n <ng-container *ngTemplateOutlet=\"selectIconTemplate\"></ng-container>\n </div>\n\n <ng-content select=\"igx-prefix,[igxPrefix]\"></ng-content>\n\n <div class=\"igx-chip__content\">\n <ng-content></ng-content>\n </div>\n\n <ng-content select=\"igx-suffix,[igxSuffix]\"></ng-content>\n\n <div class=\"igx-chip__remove\" *ngIf=\"removable\"\n tabindex=\"0\"\n (keydown)=\"onRemoveBtnKeyDown($event)\"\n (pointerdown)=\"onRemoveMouseDown($event)\"\n (mousedown)=\"onRemoveMouseDown($event)\"\n (click)=\"onRemoveClick($event)\"\n (touchmove)=\"onRemoveTouchMove()\"\n (touchend)=\"onRemoveTouchEnd($event)\">\n <ng-container *ngTemplateOutlet=\"removeButtonTemplate\"></ng-container>\n </div>\n</div>\n\n<ng-template #defaultSelectIcon>\n <igx-icon>done</igx-icon>\n</ng-template>\n\n<ng-template #defaultRemoveIcon>\n <igx-icon>cancel</igx-icon>\n</ng-template>\n" }] } ]; /** @nocollapse */ IgxChipComponent.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: ElementRef }, { type: Renderer2 }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] } ]; IgxChipComponent.propDecorators = { id: [{ type: HostBinding, args: ['attr.id',] }, { type: Input }], data: [{ type: Input }], draggable: [{ type: Input }], removable: [{ type: Input }], removeIcon: [{ type: Input }], selectable: [{ type: Input }], selectIcon: [{ type: Input }], class: [{ type: Input }], disabled: [{ type: Input }], selected: [{ type: Input }], color: [{ type: Input }], onMoveStart: [{ type: Output }], onMoveEnd: [{ type: Output }], onRemove: [{ type: Output }], onClick: [{ type: Output }], onSelection: [{ type: Output }], onKeyDown: [{ type: Output }], onDragEnter: [{ type: Output }], hostClass: [{ type: HostBinding, args: ['attr.class',] }], chipArea: [{ type: ViewChild, args: ['chipArea', { read: ElementRef },] }], dragDir: [{ type: ViewChild, args: ['chipArea', { read: IgxDragDirective },] }], defaultRemoveIcon: [{ type: ViewChild, args: ['defaultRemoveIcon', { read: TemplateRef },] }], defaultSelectIcon: [{ type: ViewChild, args: ['defaultSelectIcon', { read: TemplateRef },] }] }; if (false) { /** * An \@Input property that sets the value of `id` attribute. If not provided it will be automatically generated. * ```html * <igx-chip [id]="'igx-chip-1'"></igx-chip> * ``` * @type {?} */ IgxChipComponent.prototype.id; /** * An \@Input property that stores data related to the chip. * ```html * <igx-chip [data]="{ value: 'Country' }"></igx-chip> * ``` * @type {?} */ IgxChipComponent.prototype.data; /** * An \@Input property that defines if the `IgxChipComponent` can be dragged in order to change it's position. * By default it is set to false. * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true"></igx-chip> * ``` * @type {?} */ IgxChipComponent.prototype.draggable; /** * An \@Input property that defines if the `IgxChipComponent` should render remove button and throw remove events. * By default it is set to false. * ```html * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [removable]="true"></igx-chip> * ``` * @type {?} */ IgxChipComponent.prototype.removable; /** * An \@Input property that overrides the default icon that the chip applies to the remove button. * ```html * <igx-chip [id]="chip.id" [removable]="true" [removeIcon]="iconTemplate"></igx-chip> * <ng-template #iconTemplate><igx-icon>delete</igx-icon></ng-template> * ``` * @type {?} */ IgxChipComponent.prototype.removeIcon; /** * An \@Input property that defines if the `IgxChipComponent` can be selected on click or through navigation, * By default it is set to false. * ```html * <igx-chip [id]="chip.id" [draggable]="true" [removable]="true" [selectable]="true"></igx-chip> * ``` * @type {?} */ IgxChipComponent.prototype.selectable; /** * An \@Input property that overrides the default icon that the chip applies when it is selected. * ```html * <igx-chip [id]="chip.id" [selectable]="true" [selectIcon]="iconTemplate"></igx-chip> * <ng-template #iconTemplate><igx-icon>done_outline</igx-icon></ng-template> * ``` * @type {?} */ IgxChipComponent.prototype.selectIcon; /** * @hidden * @type {?} */ IgxChipComponent.prototype.class; /** * An \@Input property that defines if the `IgxChipComponent` is disabled. When disabled it restricts user interactions * like focusing on click or tab, selection on click or Space, dragging. * By default it is set to false. * ```html * <igx-chip [id]="chip.id" [disabled]="true"></igx-chip> * ``` * @type {?} */ IgxChipComponent.prototype.disabled; /** * Emits an event when the `IgxChipComponent` moving starts. * Returns the moving `IgxChipComponent`. * ```typescript * moveStarted(event: IBaseChipEventArgs){ * let movingChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onMoveStart)="moveStarted($event)"> * ``` * @type {?} */ IgxChipComponent.prototype.onMoveStart; /** * Emits an event when the `IgxChipComponent` moving ends. * Returns the moved `IgxChipComponent`. * ```typescript * moveEnded(event: IBaseChipEventArgs){ * let movedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onMoveEnd)="moveEnded($event)"> * ``` * @type {?} */ IgxChipComponent.prototype.onMoveEnd; /** * Emits an event when the `IgxChipComponent` is removed. * Returns the removed `IgxChipComponent`. * ```typescript * remove(event: IBaseChipEventArgs){ * let removedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onRemove)="remove($event)"> * ``` * @type {?} */ IgxChipComponent.prototype.onRemove; /** * Emits an event when the `IgxChipComponent` is clicked. * Returns the clicked `IgxChipComponent`, whether the event should be canceled. * ```typescript * chipClick(event: IChipClickEventArgs){ * let clickedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onClick)="chipClick($event)"> * ``` * @type {?} */ IgxChipComponent.prototype.onClick; /** * Emits event when the `IgxChipComponent` is selected/deselected. * Returns the selected chip reference, whether the event should be canceled, what is the next selection state and * when the event is triggered by interaction `originalEvent` is provided, otherwise `originalEvent` is `null`. * ```typescript * chipSelect(event: IChipSelectEventArgs){ * let selectedChip = event.owner; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onSelection)="chipSelect($event)"> * ``` * @type {?} */ IgxChipComponent.prototype.onSelection; /** * Emits an event when the `IgxChipComponent` keyboard navigation is being used. * Returns the focused/selected `IgxChipComponent`, whether the event should be canceled, * if the `alt`, `shift` or `control` key is pressed and the pressed key name. * ```typescript * chipKeyDown(event: IChipKeyDownEventArgs){ * let keyDown = event.key; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onKeyDown)="chipKeyDown($event)"> * ``` * @type {?} */ IgxChipComponent.prototype.onKeyDown; /** * Emits an event when the `IgxChipComponent` has entered the `IgxChipsAreaComponent`. * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as well as * the original drop event arguments. * ```typescript * chipEnter(event: IChipEnterDragAreaEventArgs){ * let targetChip = event.targetChip; * } * ``` * ```html * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (onDragEnter)="chipEnter($event)"> * ``` * @type {?} */ IgxChipComponent.prototype.onDragEnter; /** * @hidden * @type {?} */ IgxChipComponent.prototype.chipArea; /** * @hidden * @type {?} */ IgxChipComponent.prototype.dragDir; /** * @hidden * @type {?} */ IgxChipComponent.prototype.defaultRemoveIcon; /** * @hidden * @type {?} */ IgxChipComponent.prototype.defaultSelectIcon; /** * @type {?} * @protected */ IgxChipComponent.prototype._selected; /** * @type {?} * @protected */ IgxChipComponent.prototype._selectedItemClass; /** * @type {?} * @protected */ IgxChipComponent.prototype._movedWhileRemoving; /** @type {?} */ IgxChipComponent.prototype.cdr; /** @type {?} */ IgxChipComponent.prototype.elementRef; /** * @type {?} * @private */ IgxChipComponent.prototype.renderer; /** * @type {?} * @protected */ IgxChipComponent.prototype._displayDensityOptions; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hpcC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2NoaXBzL2NoaXAuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0gsU0FBUyxFQUNULGlCQUFpQixFQUNqQixZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsV0FBVyxFQUNYLE1BQU0sRUFDTixRQUFRLEVBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUEwQyxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pILE9BQU8sRUFDSCxnQkFBZ0IsRUFLbkIsTUFBTSwyQ0FBMkMsQ0FBQzs7OztBQUduRCx3Q0FHQzs7O0lBRkcsMkNBQThGOztJQUM5RixtQ0FBd0I7Ozs7O0FBRzVCLHlDQUVDOzs7SUFERyxxQ0FBZ0I7Ozs7O0FBR3BCLDJDQUdDOzs7SUFGRyw4Q0FBNkI7O0lBQzdCLHVDQUFnQjs7Ozs7QUFHcEIsaURBRUM7OztJQURHLCtDQUEyQjs7Ozs7QUFHL0IsMENBR0M7OztJQUZHLHNDQUFnQjs7SUFDaEIsd0NBQWtCOzs7SUFHbEIsT0FBTyxHQUFHLENBQUM7QUFNZixNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsa0JBQWtCOzs7Ozs7O0lBd1RwRCxZQUFtQixHQUFzQixFQUFTLFVBQXNCLEVBQVUsUUFBbUIsRUFDOUMsc0JBQThDO1FBQzdGLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBRm5CLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBQVMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUFVLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDOUMsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3Qjs7Ozs7OztRQS9TOUYsT0FBRSxHQUFHLFlBQVksT0FBTyxFQUFFLEVBQUUsQ0FB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MEQ7Ozs7O0lBQzFELCtDQUFzQzs7SUFFMUIsK0JBQTZCOztJQUFFLHNDQUE2Qjs7Ozs7SUFBRSxvQ0FBMkI7Ozs7O0lBQ2pHLGtEQUFpRyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBFbGVtZW50UmVmLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LFxuICAgIE91dHB1dCxcbiAgICBWaWV3Q2hpbGQsXG4gICAgUmVuZGVyZXIyLFxuICAgIFRlbXBsYXRlUmVmLFxuICAgIEluamVjdCxcbiAgICBPcHRpb25hbFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERpc3BsYXlEZW5zaXR5LCBJRGlzcGxheURlbnNpdHlPcHRpb25zLCBEaXNwbGF5RGVuc2l0eVRva2VuLCBEaXNwbGF5RGVuc2l0eUJhc2UgfSBmcm9tICcuLi9jb3JlL2Rpc3BsYXlEZW5zaXR5JztcbmltcG9ydCB7XG4gICAgSWd4RHJhZ0RpcmVjdGl2ZSxcbiAgICBJRHJhZ0Jhc2VFdmVudEFyZ3MsXG4gICAgSURyYWdTdGFydEV2ZW50QXJncyxcbiAgICBJZ3hEcm9wRW50ZXJFdmVudEFyZ3MsXG4gICAgSWd4RHJvcEV2ZW50QXJnc1xufSBmcm9tICcuLi9kaXJlY3RpdmVzL2RyYWdkcm9wL2RyYWdkcm9wLmRpcmVjdGl2ZSc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBJQmFzZUNoaXBFdmVudEFyZ3Mge1xuICAgIG9yaWdpbmFsRXZlbnQ6IFBvaW50ZXJFdmVudCB8IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50IHwgS2V5Ym9hcmRFdmVudCB8IElneERyb3BFbnRlckV2ZW50QXJncztcbiAgICBvd25lcjogSWd4Q2hpcENvbXBvbmVudDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJQ2hpcENsaWNrRXZlbnRBcmdzIGV4dGVuZHMgSUJhc2VDaGlwRXZlbnRBcmdzIHtcbiAgICBjYW5jZWw6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUNoaXBLZXlEb3duRXZlbnRBcmdzIGV4dGVuZHMgSUJhc2VDaGlwRXZlbnRBcmdzIHtcbiAgICBvcmlnaW5hbEV2ZW50OiBLZXlib2FyZEV2ZW50O1xuICAgIGNhbmNlbDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJQ2hpcEVudGVyRHJhZ0FyZWFFdmVudEFyZ3MgZXh0ZW5kcyBJQmFzZUNoaXBFdmVudEFyZ3Mge1xuICAgIGRyYWdDaGlwOiBJZ3hDaGlwQ29tcG9uZW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElDaGlwU2VsZWN0RXZlbnRBcmdzIGV4dGVuZHMgSUJhc2VDaGlwRXZlbnRBcmdzIHtcbiAgICBjYW5jZWw6IGJvb2xlYW47XG4gICAgc2VsZWN0ZWQ6IGJvb2xlYW47XG59XG5cbmxldCBDSElQX0lEID0gMDtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdpZ3gtY2hpcCcsXG4gICAgdGVtcGxhdGVVcmw6ICdjaGlwLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBJZ3hDaGlwQ29tcG9uZW50IGV4dGVuZHMgRGlzcGxheURlbnNpdHlCYXNlIHtcblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgdGhlIHZhbHVlIG9mIGBpZGAgYXR0cmlidXRlLiBJZiBub3QgcHJvdmlkZWQgaXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jaGlwIFtpZF09XCInaWd4LWNoaXAtMSdcIj48L2lneC1jaGlwPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5pZCcpXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgaWQgPSBgaWd4LWNoaXAtJHtDSElQX0lEKyt9YDtcblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHN0b3JlcyBkYXRhIHJlbGF0ZWQgdG8gdGhlIGNoaXAuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY2hpcCBbZGF0YV09XCJ7IHZhbHVlOiAnQ291bnRyeScgfVwiPjwvaWd4LWNoaXA+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZGF0YTogYW55O1xuXG4gICAgLyoqXG4gICAgICogQW4gQElucHV0IHByb3BlcnR5IHRoYXQgZGVmaW5lcyBpZiB0aGUgYElneENoaXBDb21wb25lbnRgIGNhbiBiZSBkcmFnZ2VkIGluIG9yZGVyIHRvIGNoYW5nZSBpdCdzIHBvc2l0aW9uLlxuICAgICAqIEJ5IGRlZmF1bHQgaXQgaXMgc2V0IHRvIGZhbHNlLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNoaXAgW2lkXT1cIidpZ3gtY2hpcC0xJ1wiIFtkcmFnZ2FibGVdPVwidHJ1ZVwiPjwvaWd4LWNoaXA+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZHJhZ2dhYmxlID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBkZWZpbmVzIGlmIHRoZSBgSWd4Q2hpcENvbXBvbmVudGAgc2hvdWxkIHJlbmRlciByZW1vdmUgYnV0dG9uIGFuZCB0aHJvdyByZW1vdmUgZXZlbnRzLlxuICAgICAqIEJ5IGRlZmF1bHQgaXQgaXMgc2V0IHRvIGZhbHNlLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNoaXAgW2lkXT1cIidpZ3gtY2hpcC0xJ1wiIFtkcmFnZ2FibGVdPVwidHJ1ZVwiIFtyZW1vdmFibGVdPVwidHJ1ZVwiPjwvaWd4LWNoaXA+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgcmVtb3ZhYmxlID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBvdmVycmlkZXMgdGhlIGRlZmF1bHQgaWNvbiB0aGF0IHRoZSBjaGlwIGFwcGxpZXMgdG8gdGhlIHJlbW92ZSBidXR0b24uXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY2hpcCBbaWRdPVwiY2hpcC5pZFwiIFtyZW1vdmFibGVdPVwidHJ1ZVwiIFtyZW1vdmVJY29uXT1cImljb25UZW1wbGF0ZVwiPjwvaWd4LWNoaXA+XG4gICAgICogPG5nLXRlbXBsYXRlICNpY29uVGVtcGxhdGU+PGlneC1pY29uPmRlbGV0ZTwvaWd4LWljb24+PC9uZy10ZW1wbGF0ZT5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyByZW1vdmVJY29uOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQW4gQElucHV0IHByb3BlcnR5IHRoYXQgZGVmaW5lcyBpZiB0aGUgYElneENoaXBDb21wb25lbnRgIGNhbiBiZSBzZWxlY3RlZCBvbiBjbGljayBvciB0aHJvdWdoIG5hdmlnYXRpb24sXG4gICAgICogQnkgZGVmYXVsdCBpdCBpcyBzZXQgdG8gZmFsc2UuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY2hpcCBbaWRdPVwiY2hpcC5pZFwiIFtkcmFnZ2FibGVdPVwidHJ1ZVwiIFtyZW1vdmFibGVdPVwidHJ1ZVwiIFtzZWxlY3RhYmxlXT1cInRydWVcIj48L2lneC1jaGlwPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNlbGVjdGFibGUgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IG92ZXJyaWRlcyB0aGUgZGVmYXVsdCBpY29uIHRoYXQgdGhlIGNoaXAgYXBwbGllcyB3aGVuIGl0IGlzIHNlbGVjdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNoaXAgW2lkXT1cImNoaXAuaWRcIiBbc2VsZWN0YWJsZV09XCJ0cnVlXCIgW3NlbGVjdEljb25dPVwiaWNvblRlbXBsYXRlXCI+PC9pZ3gtY2hpcD5cbiAgICAgKiA8bmctdGVtcGxhdGUgI2ljb25UZW1wbGF0ZT48aWd4LWljb24+ZG9uZV9vdXRsaW5lPC9pZ3gtaWNvbj48L25nLXRlbXBsYXRlPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNlbGVjdEljb246IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgY2xhc3MgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IGRlZmluZXMgaWYgdGhlIGBJZ3hDaGlwQ29tcG9uZW50YCBpcyBkaXNhYmxlZC4gV2hlbiBkaXNhYmxlZCBpdCByZXN0cmljdHMgdXNlciBpbnRlcmFjdGlvbnNcbiAgICAgKiBsaWtlIGZvY3VzaW5nIG9uIGNsaWNrIG9yIHRhYiwgc2VsZWN0aW9uIG9uIGNsaWNrIG9yIFNwYWNlLCBkcmFnZ2luZy5cbiAgICAgKiBCeSBkZWZhdWx0IGl0IGlzIHNldCB0byBmYWxzZS5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jaGlwIFtpZF09XCJjaGlwLmlkXCIgW2Rpc2FibGVkXT1cInRydWVcIj48L2lneC1jaGlwPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGRpc2FibGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBgSWd4Q2hpcENvbXBvbmVudGAgc2VsZWN0ZWQgc3RhdGUuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY2hpcCAjbXlDaGlwIFtpZF09XCInaWd4LWNoaXAtMSdcIiBbc2VsZWN0YWJsZV09XCJ0cnVlXCIgW3NlbGVjdGVkXT1cInRydWVcIj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgc2VsZWN0ZWQobmV3VmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VTZWxlY3Rpb24obmV3VmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaWYgdGhlIGBJZ3hDaGlwQ29tcG9uZW50YCBpcyBzZWxlY3RlZC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogQFZpZXdDaGlsZCgnbXlDaGlwJylcbiAgICAgKiBwdWJsaWMgY2hpcDogSWd4Q2hpcENvbXBvbmVudDtcbiAgICAgKiBzZWxlY3RlZENoaXAoKXtcbiAgICAgKiAgICAgbGV0IHNlbGVjdGVkQ2hpcCA9IHRoaXMuY2hpcC5zZWxlY3RlZDtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBzZWxlY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgdGhlIGBJZ3hDaGlwQ29tcG9uZW50YCBiYWNrZ3JvdW5kIGNvbG9yLlxuICAgICAqIFRoZSBgY29sb3JgIHByb3BlcnR5IHN1cHBvcnRzIHN0cmluZywgcmdiLCBoZXguXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY2hpcCAjbXlDaGlwIFtpZF09XCInaWd4LWNoaXAtMSdcIiBbY29sb3JdPVwiJyNmZjAwMDAnXCI+PC9pZ3gtY2hpcD5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgY29sb3IobmV3Q29sb3IpIHtcbiAgICAgICAgdGhpcy5jaGlwQXJlYS5uYXRpdmVFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IG5ld0NvbG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGJhY2tncm91bmQgY29sb3Igb2YgdGhlIGBJZ3hDaGlwQ29tcG9uZW50YC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogQFZpZXdDaGlsZCgnbXlDaGlwJylcbiAgICAgKiBwdWJsaWMgY2hpcDogSWd4Q2hpcENvbXBvbmVudDtcbiAgICAgKiBuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgKiAgICAgbGV0IGNoaXBDb2xvciA9IHRoaXMuY2hpcC5jb2xvcjtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBjb2xvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hpcEFyZWEubmF0aXZlRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgYElneENoaXBDb21wb25lbnRgIG1vdmluZyBzdGFydHMuXG4gICAgICogUmV0dXJucyB0aGUgbW92aW5nIGBJZ3hDaGlwQ29tcG9uZW50YC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbW92ZVN0YXJ0ZWQoZXZlbnQ6IElCYXNlQ2hpcEV2ZW50QXJncyl7XG4gICAgICogICAgIGxldCBtb3ZpbmdDaGlwID0gZXZlbnQub3duZXI7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNoaXAgI215Q2hpcCBbaWRdPVwiJ2lneC1jaGlwLTEnXCIgW2RyYWdnYWJsZV09XCJ0cnVlXCIgKG9uTW92ZVN0YXJ0KT1cIm1vdmVTdGFydGVkKCRldmVudClcIj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25Nb3ZlU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPElCYXNlQ2hpcEV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIGBJZ3hDaGlwQ29tcG9uZW50YCBtb3ZpbmcgZW5kcy5cbiAgICAgKiBSZXR1cm5zIHRoZSBtb3ZlZCBgSWd4Q2hpcENvbXBvbmVudGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIG1vdmVFbmRlZChldmVudDogSUJhc2VDaGlwRXZlbnRBcmdzKXtcbiAgICAgKiAgICAgbGV0IG1vdmVkQ2hpcCA9IGV2ZW50Lm93bmVyO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jaGlwICNteUNoaXAgW2lkXT1cIidpZ3gtY2hpcC0xJ1wiIFtkcmFnZ2FibGVdPVwidHJ1ZVwiIChvbk1vdmVFbmQpPVwibW92ZUVuZGVkKCRldmVudClcIj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25Nb3ZlRW5kID0gbmV3IEV2ZW50RW1pdHRlcjxJQmFzZUNoaXBFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBgSWd4Q2hpcENvbXBvbmVudGAgaXMgcmVtb3ZlZC5cbiAgICAgKiBSZXR1cm5zIHRoZSByZW1vdmVkIGBJZ3hDaGlwQ29tcG9uZW50YC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogcmVtb3ZlKGV2ZW50OiBJQmFzZUNoaXBFdmVudEFyZ3Mpe1xuICAgICAqICAgICBsZXQgcmVtb3ZlZENoaXAgPSBldmVudC5vd25lcjtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY2hpcCAjbXlDaGlwIFtpZF09XCInaWd4LWNoaXAtMSdcIiBbZHJhZ2dhYmxlXT1cInRydWVcIiAob25SZW1vdmUpPVwicmVtb3ZlKCRldmVudClcIj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25SZW1vdmUgPSBuZXcgRXZlbnRFbWl0dGVyPElCYXNlQ2hpcEV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIGBJZ3hDaGlwQ29tcG9uZW50YCBpcyBjbGlja2VkLlxuICAgICAqIFJldHVybnMgdGhlIGNsaWNrZWQgYElneENoaXBDb21wb25lbnRgLCB3aGV0aGVyIHRoZSBldmVudCBzaG91bGQgYmUgY2FuY2VsZWQuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNoaXBDbGljayhldmVudDogSUNoaXBDbGlja0V2ZW50QXJncyl7XG4gICAgICogICAgIGxldCBjbGlja2VkQ2hpcCA9IGV2ZW50Lm93bmVyO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jaGlwICNteUNoaXAgW2lkXT1cIidpZ3gtY2hpcC0xJ1wiIFtkcmFnZ2FibGVdPVwidHJ1ZVwiIChvbkNsaWNrKT1cImNoaXBDbGljaygkZXZlbnQpXCI+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPElDaGlwQ2xpY2tFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBldmVudCB3aGVuIHRoZSBgSWd4Q2hpcENvbXBvbmVudGAgaXMgc2VsZWN0ZWQvZGVzZWxlY3RlZC5cbiAgICAgKiBSZXR1cm5zIHRoZSBzZWxlY3RlZCBjaGlwIHJlZmVyZW5jZSwgd2hldGhlciB0aGUgZXZlbnQgc2hvdWxkIGJlIGNhbmNlbGVkLCB3aGF0IGlzIHRoZSBuZXh0IHNlbGVjdGlvbiBzdGF0ZSBhbmRcbiAgICAgKiB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQgYnkgaW50ZXJhY3Rpb24gYG9yaWdpbmFsRXZlbnRgIGlzIHByb3ZpZGVkLCBvdGhlcndpc2UgYG9yaWdpbmFsRXZlbnRgIGlzIGBudWxsYC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY2hpcFNlbGVjdChldmVudDogSUNoaXBTZWxlY3RFdmVudEFyZ3Mpe1xuICAgICAqICAgICBsZXQgc2VsZWN0ZWRDaGlwID0gZXZlbnQub3duZXI7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNoaXAgI215Q2hpcCBbaWRdPVwiJ2lneC1jaGlwLTEnXCIgW2RyYWdnYWJsZV09XCJ0cnVlXCIgKG9uU2VsZWN0aW9uKT1cImNoaXBTZWxlY3QoJGV2ZW50KVwiPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvblNlbGVjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8SUNoaXBTZWxlY3RFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBgSWd4Q2hpcENvbXBvbmVudGAga2V5Ym9hcmQgbmF2aWdhdGlvbiBpcyBiZWluZyB1c2VkLlxuICAgICAqIFJldHVybnMgdGhlIGZvY3VzZWQvc2VsZWN0ZWQgYElneENoaXBDb21wb25lbnRgLCB3aGV0aGVyIHRoZSBldmVudCBzaG91bGQgYmUgY2FuY2VsZWQsXG4gICAgICogaWYgdGhlIGBhbHRgLCBgc2hpZnRgIG9yIGBjb250cm9sYCBrZXkgaXMgcHJlc3NlZCBhbmQgdGhlIHByZXNzZWQga2V5IG5hbWUuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNoaXBLZXlEb3duKGV2ZW50OiBJQ2hpcEtleURvd25FdmVudEFyZ3Mpe1xuICAgICAqICAgICBsZXQga2V5RG93biA9IGV2ZW50LmtleTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY2hpcCAjbXlDaGlwIFtpZF09XCInaWd4LWNoaXAtMSdcIiBbZHJhZ2dhYmxlXT1cInRydWVcIiAob25LZXlEb3duKT1cImNoaXBLZXlEb3duKCRldmVudClcIj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25LZXlEb3duID0gbmV3IEV2ZW50RW1pdHRlcjxJQ2hpcEtleURvd25FdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBgSWd4Q2hpcENvbXBvbmVudGAgaGFzIGVudGVyZWQgdGhlIGBJZ3hDaGlwc0FyZWFDb21wb25lbnRgLlxuICAgICAqIFJldHVybnMgdGhlIHRhcmdldCBgSWd4Q2hpcENvbXBvbmVudGAsIHRoZSBkcmFnIGBJZ3hDaGlwQ29tcG9uZW50YCwgYXMgIHdlbGwgYXNcbiAgICAgKiB0aGUgb3JpZ2luYWwgZHJvcCBldmVudCBhcmd1bWVudHMuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNoaXBFbnRlcihldmVudDogSUNoaXBFbnRlckRyYWdBcmVhRXZlbnRBcmdzKXtcbiAgICAgKiAgICAgbGV0IHRhcmdldENoaXAgPSBldmVudC50YXJnZXRDaGlwO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jaGlwICNteUNoaXAgW2lkXT1cIidpZ3gtY2hpcC0xJ1wiIFtkcmFnZ2FibGVdPVwidHJ1ZVwiIChvbkRyYWdFbnRlcik9XCJjaGlwRW50ZXIoJGV2ZW50KVwiPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvbkRyYWdFbnRlciA9IG5ldyBFdmVudEVtaXR0ZXI8SUNoaXBFbnRlckRyYWdBcmVhRXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5jbGFzcycpXG4gICAgZ2V0IGhvc3RDbGFzcygpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBjbGFzc2VzID0gW3RoaXMuZ2V0Q29tcG9uZW50RGVuc2l0eUNsYXNzKCdpZ3gtY2hpcCcpXTtcbiAgICAgICAgY2xhc3Nlcy5wdXNoKHRoaXMuZGlzYWJsZWQgPyAnaWd4LWNoaXAtLWRpc2FibGVkJyA6ICcnKTtcbiAgICAgICAgLy8gVGhlIGN1c3RvbSBjbGFzc2VzIHNob3VsZCBiZSBhdCB0aGUgZW5kLlxuICAgICAgICBjbGFzc2VzLnB1c2godGhpcy5jbGFzcyk7XG4gICAgICAgIHJldHVybiBjbGFzc2VzLmpvaW4oJyAnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY2hpcEFyZWEnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSlcbiAgICBwdWJsaWMgY2hpcEFyZWE6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY2hpcEFyZWEnLCB7IHJlYWQ6IElneERyYWdEaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgZHJhZ0RpcjogSWd4RHJhZ0RpcmVjdGl2ZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdkZWZhdWx0UmVtb3ZlSWNvbicsIHsgcmVhZDogVGVtcGxhdGVSZWYgfSlcbiAgICBwdWJsaWMgZGVmYXVsdFJlbW92ZUljb246IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnZGVmYXVsdFNlbGVjdEljb24nLCB7IHJlYWQ6IFRlbXBsYXRlUmVmIH0pXG4gICAgcHVibGljIGRlZmF1bHRTZWxlY3RJY29uOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcmVtb3ZlQnV0dG9uVGVtcGxhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUljb24gfHwgdGhpcy5kZWZhdWx0UmVtb3ZlSWNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldCBzZWxlY3RJY29uVGVtcGxhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdEljb24gfHwgdGhpcy5kZWZhdWx0U2VsZWN0SWNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldCBnaG9zdENsYXNzKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldENvbXBvbmVudERlbnNpdHlDbGFzcygnaWd4LWNoaXBfX2dob3N0Jyk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjaGlwVGFiaW5kZXgoKSB7XG4gICAgICAgIHJldHVybiAhdGhpcy5kaXNhYmxlZCA/IDAgOiAnJztcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgX3NlbGVjdGVkID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIF9zZWxlY3RlZEl0ZW1DbGFzcyA9ICdpZ3gtY2hpcF9faXRlbS0tc2VsZWN0ZWQnO1xuICAgIHByb3R