UNPKG

@catull/igniteui-angular

Version:

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

593 lines 62.5 kB
import { __decorate, __extends, __metadata, __param } from "tslib"; import { ChangeDetectorRef, Component, ContentChildren, ElementRef, forwardRef, QueryList, OnInit, Input, OnDestroy, ViewChild, ContentChild, AfterViewInit, Output, EventEmitter, Optional, Inject } from '@angular/core'; import { IgxToggleDirective } from '../directives/toggle/toggle.directive'; import { IgxDropDownItemComponent } from './drop-down-item.component'; import { IgxDropDownBaseDirective } from './drop-down.base'; import { Navigate } from './drop-down.common'; import { IGX_DROPDOWN_BASE } from './drop-down.common'; import { isIE } from '../core/utils'; import { IgxSelectionAPIService } from '../core/selection'; import { Subject } from 'rxjs'; import { IgxDropDownItemBaseDirective } from './drop-down-item.base'; import { IgxForOfDirective } from '../directives/for-of/for_of.directive'; import { take } from 'rxjs/operators'; import { DisplayDensityToken } from '../core/density'; /** * **Ignite UI for Angular DropDown** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/drop_down.html) * * The Ignite UI for Angular Drop Down displays a scrollable list of items which may be visually grouped and * supports selection of a single item. Clicking or tapping an item selects it and closes the Drop Down * * Example: * ```html * <igx-drop-down> * <igx-drop-down-item *ngFor="let item of items" disabled={{item.disabled}} isHeader={{item.header}}> * {{ item.value }} * </igx-drop-down-item> * </igx-drop-down> * ``` */ var IgxDropDownComponent = /** @class */ (function (_super) { __extends(IgxDropDownComponent, _super); function IgxDropDownComponent(elementRef, cdr, selection, _displayDensityOptions) { var _this = _super.call(this, elementRef, cdr, _displayDensityOptions) || this; _this.elementRef = elementRef; _this.cdr = cdr; _this.selection = selection; _this._displayDensityOptions = _displayDensityOptions; _this.destroy$ = new Subject(); /** * Emitted before the dropdown is opened * * ```html * <igx-drop-down (onOpening)='handleOpening()'></igx-drop-down> * ``` */ _this.onOpening = new EventEmitter(); /** * Emitted after the dropdown is opened * * ```html * <igx-drop-down (onOpened)='handleOpened()'></igx-drop-down> * ``` */ _this.onOpened = new EventEmitter(); /** * Emitted before the dropdown is closed * * ```html * <igx-drop-down (onClosing)='handleClosing()'></igx-drop-down> * ``` */ _this.onClosing = new EventEmitter(); /** * Emitted after the dropdown is closed * * ```html * <igx-drop-down (onClosed)='handleClosed()'></igx-drop-down> * ``` */ _this.onClosed = new EventEmitter(); /** * Gets/sets whether items take focus. Disabled by default. * When enabled, drop down items gain tab index and are focused when active - * this includes activating the selected item when opening the drop down and moving with keyboard navigation. * * Note: Keep that focus shift in mind when using the igxDropDownItemNavigation directive * and ensure it's placed either on each focusable item or a common ancestor to allow it to handle keyboard events. * * ```typescript * // get * let dropDownAllowsItemFocus = this.dropdown.allowItemsFocus; * ``` * * ```html * <!--set--> * <igx-drop-down [allowItemsFocus]='true'></igx-drop-down> * ``` */ _this.allowItemsFocus = false; return _this; } IgxDropDownComponent_1 = IgxDropDownComponent; Object.defineProperty(IgxDropDownComponent.prototype, "focusedItem", { /** * @hidden @internal */ get: function () { var _this = this; if (this.virtDir) { return this._focusedItem && this._focusedItem.index !== -1 ? (this.children.find(function (e) { return e.index === _this._focusedItem.index; }) || null) : null; } return this._focusedItem; }, set: function (value) { if (!value) { this.selection.clear(this.id + "-active"); this._focusedItem = null; return; } this._focusedItem = value; if (this.virtDir) { this._focusedItem = { value: value.value, index: value.index }; } this.selection.set(this.id + "-active", new Set([this._focusedItem])); }, enumerable: true, configurable: true }); Object.defineProperty(IgxDropDownComponent.prototype, "id", { get: function () { return this._id; }, set: function (value) { this.toggleDirective.id = value; this.selection.set(value, this.selection.get(this.id)); this.selection.clear(this.id); this.selection.set(value, this.selection.get(this.id + "-active")); this.selection.clear(this.id + "-active"); this._id = value; }, enumerable: true, configurable: true }); Object.defineProperty(IgxDropDownComponent.prototype, "listId", { /** Id of the internal listbox of the drop down */ get: function () { return this.id + '-list'; }, enumerable: true, configurable: true }); Object.defineProperty(IgxDropDownComponent.prototype, "selectedItem", { /** * Get currently selected item * * ```typescript * let currentItem = this.dropdown.selectedItem; * ``` */ get: function () { var selectedItem = this.selection.first_item(this.id); if (selectedItem) { return selectedItem; } return null; }, enumerable: true, configurable: true }); Object.defineProperty(IgxDropDownComponent.prototype, "collapsed", { /** * Gets if the dropdown is collapsed * * ```typescript * let isCollapsed = this.dropdown.collapsed; * ``` */ get: function () { return this.toggleDirective.collapsed; }, enumerable: true, configurable: true }); Object.defineProperty(IgxDropDownComponent.prototype, "scrollContainer", { /** @hidden @internal */ get: function () { return this.scrollContainerRef.nativeElement; }, enumerable: true, configurable: true }); Object.defineProperty(IgxDropDownComponent.prototype, "collectionLength", { get: function () { if (this.virtDir) { return this.virtDir.totalItemCount || this.virtDir.igxForOf.length; } }, enumerable: true, configurable: true }); /** * Opens the dropdown * * ```typescript * this.dropdown.open(); * ``` */ IgxDropDownComponent.prototype.open = function (overlaySettings) { this.toggleDirective.open(overlaySettings); this.updateScrollPosition(); }; /** * Closes the dropdown * * ```typescript * this.dropdown.close(); * ``` */ IgxDropDownComponent.prototype.close = function () { this.toggleDirective.close(); }; /** * Toggles the dropdown * * ```typescript * this.dropdown.toggle(); * ``` */ IgxDropDownComponent.prototype.toggle = function (overlaySettings) { if (this.collapsed || this.toggleDirective.isClosing) { this.open(overlaySettings); } else { this.close(); } }; /** * Select an item by index * @param index of the item to select; If the drop down uses *igxFor, pass the index in data */ IgxDropDownComponent.prototype.setSelectedItem = function (index) { if (index < 0 || index >= this.items.length) { return; } var newSelection; if (this.virtDir) { newSelection = { value: this.virtDir.igxForOf[index], index: index }; } else { newSelection = this.items[index]; } this.selectItem(newSelection); }; /** * Navigates to the item on the specified index * If the data in the drop-down is virtualized, pass the index of the item in the virtualized data. * @param newIndex number */ IgxDropDownComponent.prototype.navigateItem = function (index) { var _this = this; if (this.virtDir) { if (index === -1 || index >= this.collectionLength) { return; } var direction_1 = index > (this.focusedItem ? this.focusedItem.index : -1) ? Navigate.Down : Navigate.Up; var subRequired = this.isIndexOutOfBounds(index, direction_1); this.focusedItem = { value: this.virtDir.igxForOf[index], index: index }; if (subRequired) { this.virtDir.scrollTo(index); } if (subRequired) { this.virtDir.onChunkLoad.pipe(take(1)).subscribe(function () { _this.skipHeader(direction_1); }); } else { this.skipHeader(direction_1); } } else { _super.prototype.navigateItem.call(this, index); } if (this.allowItemsFocus && this.focusedItem) { this.focusedItem.element.nativeElement.focus(); this.cdr.markForCheck(); } }; IgxDropDownComponent.prototype.isIndexOutOfBounds = function (index, direction) { var virtState = this.virtDir.state; var currentPosition = this.virtDir.getScroll().scrollTop; var itemPosition = this.virtDir.getScrollForIndex(index, direction === Navigate.Down); var indexOutOfChunk = index < virtState.startIndex || index > virtState.chunkSize + virtState.startIndex; var scrollNeeded = direction === Navigate.Down ? currentPosition < itemPosition : currentPosition > itemPosition; var subRequired = indexOutOfChunk || scrollNeeded; return subRequired; }; IgxDropDownComponent.prototype.skipHeader = function (direction) { if (!this.focusedItem) { return; } if (this.focusedItem.isHeader || this.focusedItem.disabled) { if (direction === Navigate.Up) { this.navigatePrev(); } else { this.navigateNext(); } } }; /** * @hidden @internal */ IgxDropDownComponent.prototype.updateScrollPosition = function () { if (!this.virtDir) { return; } if (!this.selectedItem) { this.virtDir.scrollTo(0); return; } var targetScroll = this.virtDir.getScrollForIndex(this.selectedItem.index); var itemsInView = this.virtDir.igxForContainerSize / this.virtDir.igxForItemSize; targetScroll -= (itemsInView / 2 - 1) * this.virtDir.igxForItemSize; this.virtDir.getScroll().scrollTop = targetScroll; }; /** * @hidden @internal */ IgxDropDownComponent.prototype.onToggleOpening = function (e) { this.onOpening.emit(e); if (e.cancel) { return; } if (!this.virtDir && this.selectedItem) { this.scrollToItem(this.selectedItem); } if (this.virtDir) { this.virtDir.scrollPosition = this._scrollPosition; } }; /** * @hidden @internal */ IgxDropDownComponent.prototype.onToggleOpened = function () { if (this.selectedItem) { this.focusedItem = this.selectedItem; this._focusedItem.focused = true; } else if (this.allowItemsFocus) { this.navigateFirst(); } this.onOpened.emit(); }; /** * @hidden @internal */ IgxDropDownComponent.prototype.onToggleClosing = function (e) { this.onClosing.emit(e); if (this.virtDir) { this._scrollPosition = this.virtDir.scrollPosition; } }; /** * @hidden @internal */ IgxDropDownComponent.prototype.onToggleClosed = function () { if (this._focusedItem) { this._focusedItem.focused = false; } this.onClosed.emit(); }; /** * @hidden @internal */ IgxDropDownComponent.prototype.ngOnDestroy = function () { this.destroy$.next(true); this.destroy$.complete(); this.selection.clear(this.id); this.selection.clear(this.id + "-active"); }; IgxDropDownComponent.prototype.scrollToItem = function (item) { var _this = this; var itemPosition = this.calculateScrollPosition(item); // in IE11 setting sctrollTop is somehow slow and forces dropdown // to appear on screen before animation start. As a result dropdown // flickers badly. This is why we set scrollTop just a little later // allowing animation to start and prevent dropdown flickering if (isIE()) { setTimeout(function () { _this.scrollContainer.scrollTop = (itemPosition); }, 1); } else { this.scrollContainer.scrollTop = (itemPosition); } }; /** @hidden @internal */ IgxDropDownComponent.prototype.calculateScrollPosition = function (item) { if (!item) { return 0; } var elementRect = item.element.nativeElement.getBoundingClientRect(); var parentRect = this.scrollContainer.getBoundingClientRect(); var scrollDelta = parentRect.top - elementRect.top; var scrollPosition = this.scrollContainer.scrollTop - scrollDelta; var dropDownHeight = this.scrollContainer.clientHeight; scrollPosition -= dropDownHeight / 2; scrollPosition += item.elementHeight / 2; return Math.floor(scrollPosition); }; /** * @hidden @internal */ IgxDropDownComponent.prototype.ngOnInit = function () { this.toggleDirective.id = this.id; }; IgxDropDownComponent.prototype.ngAfterViewInit = function () { if (this.virtDir) { this.virtDir.igxForItemSize = 28; } }; /** Keydown Handler */ IgxDropDownComponent.prototype.onItemActionKey = function (key, event) { _super.prototype.onItemActionKey.call(this, key, event); this.close(); }; /** * Virtual scroll implementation * @hidden @internal */ IgxDropDownComponent.prototype.navigateFirst = function () { if (this.virtDir) { this.navigateItem(0); } else { _super.prototype.navigateFirst.call(this); } }; /** * @hidden @internal */ IgxDropDownComponent.prototype.navigateLast = function () { if (this.virtDir) { this.navigateItem(this.virtDir.totalItemCount ? this.virtDir.totalItemCount - 1 : this.virtDir.igxForOf.length - 1); } else { _super.prototype.navigateLast.call(this); } }; /** * @hidden @internal */ IgxDropDownComponent.prototype.navigateNext = function () { if (this.virtDir) { this.navigateItem(this._focusedItem ? this._focusedItem.index + 1 : 0); } else { _super.prototype.navigateNext.call(this); } }; /** * @hidden @internal */ IgxDropDownComponent.prototype.navigatePrev = function () { if (this.virtDir) { this.navigateItem(this._focusedItem ? this._focusedItem.index - 1 : 0); } else { _super.prototype.navigatePrev.call(this); } }; /** * Handles the `onSelection` emit and the drop down toggle when selection changes * @hidden * @internal * @param newSelection * @param event */ IgxDropDownComponent.prototype.selectItem = function (newSelection, event) { var oldSelection = this.selectedItem; if (!newSelection) { newSelection = this.focusedItem; } if (newSelection === null) { return; } if (newSelection instanceof IgxDropDownItemBaseDirective && newSelection.isHeader) { return; } if (this.virtDir) { newSelection = { value: newSelection.value, index: newSelection.index }; } var args = { oldSelection: oldSelection, newSelection: newSelection, cancel: false }; this.onSelection.emit(args); if (!args.cancel) { if (this.isSelectionValid(args.newSelection)) { this.selection.set(this.id, new Set([args.newSelection])); if (!this.virtDir) { if (oldSelection) { oldSelection.selected = false; } if (args.newSelection) { args.newSelection.selected = true; } } if (event) { this.toggleDirective.close(); } } else { throw new Error('Please provide a valid drop-down item for the selection!'); } } }; /** * Checks whether the selection is valid * `null` - the selection should be emptied * Virtual? - the selection should at least have and `index` and `value` property * Non-virtual? - the selection should be a valid drop-down item and **not** be a header */ IgxDropDownComponent.prototype.isSelectionValid = function (selection) { return selection === null || (this.virtDir && selection.hasOwnProperty('value') && selection.hasOwnProperty('index')) || (selection instanceof IgxDropDownItemComponent && !selection.isHeader); }; var IgxDropDownComponent_1; IgxDropDownComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: ChangeDetectorRef }, { type: IgxSelectionAPIService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] } ]; }; __decorate([ ContentChild(IgxForOfDirective, { read: IgxForOfDirective }), __metadata("design:type", IgxForOfDirective) ], IgxDropDownComponent.prototype, "virtDir", void 0); __decorate([ ViewChild(IgxToggleDirective, { static: true }), __metadata("design:type", IgxToggleDirective) ], IgxDropDownComponent.prototype, "toggleDirective", void 0); __decorate([ ViewChild('scrollContainer', { static: true }), __metadata("design:type", ElementRef) ], IgxDropDownComponent.prototype, "scrollContainerRef", void 0); __decorate([ ContentChildren(forwardRef(function () { return IgxDropDownItemComponent; }), { descendants: true }), __metadata("design:type", QueryList) ], IgxDropDownComponent.prototype, "children", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxDropDownComponent.prototype, "onOpening", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxDropDownComponent.prototype, "onOpened", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxDropDownComponent.prototype, "onClosing", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxDropDownComponent.prototype, "onClosed", void 0); __decorate([ Input(), __metadata("design:type", Object) ], IgxDropDownComponent.prototype, "allowItemsFocus", void 0); __decorate([ Input(), __metadata("design:type", String), __metadata("design:paramtypes", [String]) ], IgxDropDownComponent.prototype, "id", null); IgxDropDownComponent = IgxDropDownComponent_1 = __decorate([ Component({ selector: 'igx-drop-down', template: "<div #scrollContainer class=\"igx-drop-down__list\" igxToggle [style.width]=\"width\" [style.height]=\"height\"\n[style.maxHeight]=\"maxHeight\" [attr.id]=\"this.listId\" role=\"listbox\"\n (onOpening)=\"onToggleOpening($event)\" (onOpened)=\"onToggleOpened()\"\n (onClosing)=\"onToggleClosing($event)\" (onClosed)=\"onToggleClosed()\">\n <ng-container *ngIf=\"!collapsed\">\n <ng-content></ng-content>\n </ng-container>\n</div>\n", providers: [{ provide: IGX_DROPDOWN_BASE, useExisting: IgxDropDownComponent_1 }] }), __param(3, Optional()), __param(3, Inject(DisplayDensityToken)), __metadata("design:paramtypes", [ElementRef, ChangeDetectorRef, IgxSelectionAPIService, Object]) ], IgxDropDownComponent); return IgxDropDownComponent; }(IgxDropDownBaseDirective)); export { IgxDropDownComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC1kb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZHJvcC1kb3duL2Ryb3AtZG93bi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULGVBQWUsRUFDZixVQUFVLEVBQ1YsVUFBVSxFQUNWLFNBQVMsRUFDVCxNQUFNLEVBQ04sS0FBSyxFQUNMLFNBQVMsRUFDVCxTQUFTLEVBQ1QsWUFBWSxFQUNaLGFBQWEsRUFDYixNQUFNLEVBQ04sWUFBWSxFQUNaLFFBQVEsRUFDUixNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDM0UsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUQsT0FBTyxFQUFxQixRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsaUJBQWlCLEVBQWlCLE1BQU0sb0JBQW9CLENBQUM7QUFFdEUsT0FBTyxFQUFtRCxJQUFJLEVBQWtCLE1BQU0sZUFBZSxDQUFDO0FBQ3RHLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFckUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDMUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxtQkFBbUIsRUFBMEIsTUFBTSxpQkFBaUIsQ0FBQztBQUU5RTs7Ozs7Ozs7Ozs7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QU96QztRQURDLGVBQWUsQ0FBQyxVQUFVLENBQUMsY0FBTSxPQUFBLHdCQUF3QixFQUF4QixDQUF3QixDQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUM7a0NBQ2xFLFNBQVM7MERBQStCO0lBVXpEO1FBREMsTUFBTSxFQUFFOzsyREFDbUU7SUFVNUU7UUFEQyxNQUFNLEVBQUU7OzBEQUNrQztJQVUzQztRQURDLE1BQU0sRUFBRTs7MkRBQzBFO0lBVW5GO1FBREMsTUFBTSxFQUFFOzswREFDa0M7SUFxQjNDO1FBREMsS0FBSyxFQUFFOztpRUFDdUI7SUErQi9CO1FBREMsS0FBSyxFQUFFOzs7a0RBR1A7SUFoSFEsb0JBQW9CO1FBTGhDLFNBQVMsQ0FBQztZQUNQLFFBQVEsRUFBRSxlQUFlO1lBQ3pCLDZjQUF5QztZQUN6QyxTQUFTLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsc0JBQW9CLEVBQUUsQ0FBQztTQUNqRixDQUFDO1FBeUtPLFdBQUEsUUFBUSxFQUFFLENBQUEsRUFBRSxXQUFBLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO3lDQUhsQixVQUFVO1lBQ2pCLGlCQUFpQjtZQUNYLHNCQUFzQjtPQXZLdEMsb0JBQW9CLENBd2dCaEM7SUFBRCwyQkFBQztDQUFBLEFBeGdCRCxDQUEwQyx3QkFBd0IsR0F3Z0JqRTtTQXhnQlksb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgQ29udGVudENoaWxkcmVuLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgZm9yd2FyZFJlZixcbiAgICBRdWVyeUxpc3QsXG4gICAgT25Jbml0LFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBWaWV3Q2hpbGQsXG4gICAgQ29udGVudENoaWxkLFxuICAgIEFmdGVyVmlld0luaXQsXG4gICAgT3V0cHV0LFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBPcHRpb25hbCxcbiAgICBJbmplY3Rcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJZ3hUb2dnbGVEaXJlY3RpdmUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3RvZ2dsZS90b2dnbGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneERyb3BEb3duSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vZHJvcC1kb3duLWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7IElneERyb3BEb3duQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4vZHJvcC1kb3duLmJhc2UnO1xuaW1wb3J0IHsgRHJvcERvd25BY3Rpb25LZXksIE5hdmlnYXRlIH0gZnJvbSAnLi9kcm9wLWRvd24uY29tbW9uJztcbmltcG9ydCB7IElHWF9EUk9QRE9XTl9CQVNFLCBJRHJvcERvd25CYXNlIH0gZnJvbSAnLi9kcm9wLWRvd24uY29tbW9uJztcbmltcG9ydCB7IElTZWxlY3Rpb25FdmVudEFyZ3MgfSBmcm9tICcuL2Ryb3AtZG93bi5jb21tb24nO1xuaW1wb3J0IHsgQ2FuY2VsYWJsZUV2ZW50QXJncywgQ2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3MsIGlzSUUsIElCYXNlRXZlbnRBcmdzIH0gZnJvbSAnLi4vY29yZS91dGlscyc7XG5pbXBvcnQgeyBJZ3hTZWxlY3Rpb25BUElTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9zZWxlY3Rpb24nO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSWd4RHJvcERvd25JdGVtQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4vZHJvcC1kb3duLWl0ZW0uYmFzZSc7XG5pbXBvcnQgeyBPdmVybGF5U2V0dGluZ3MgfSBmcm9tICcuLi9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBJZ3hGb3JPZkRpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvZm9yLW9mL2Zvcl9vZi5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IERpc3BsYXlEZW5zaXR5VG9rZW4sIElEaXNwbGF5RGVuc2l0eU9wdGlvbnMgfSBmcm9tICcuLi9jb3JlL2RlbnNpdHknO1xuXG4vKipcbiAqICoqSWduaXRlIFVJIGZvciBBbmd1bGFyIERyb3BEb3duKiogLVxuICogW0RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LmluZnJhZ2lzdGljcy5jb20vcHJvZHVjdHMvaWduaXRlLXVpLWFuZ3VsYXIvYW5ndWxhci9jb21wb25lbnRzL2Ryb3BfZG93bi5odG1sKVxuICpcbiAqIFRoZSBJZ25pdGUgVUkgZm9yIEFuZ3VsYXIgRHJvcCBEb3duIGRpc3BsYXlzIGEgc2Nyb2xsYWJsZSBsaXN0IG9mIGl0ZW1zIHdoaWNoIG1heSBiZSB2aXN1YWxseSBncm91cGVkIGFuZFxuICogc3VwcG9ydHMgc2VsZWN0aW9uIG9mIGEgc2luZ2xlIGl0ZW0uIENsaWNraW5nIG9yIHRhcHBpbmcgYW4gaXRlbSBzZWxlY3RzIGl0IGFuZCBjbG9zZXMgdGhlIERyb3AgRG93blxuICpcbiAqIEV4YW1wbGU6XG4gKiBgYGBodG1sXG4gKiA8aWd4LWRyb3AtZG93bj5cbiAqICAgPGlneC1kcm9wLWRvd24taXRlbSAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtc1wiIGRpc2FibGVkPXt7aXRlbS5kaXNhYmxlZH19IGlzSGVhZGVyPXt7aXRlbS5oZWFkZXJ9fT5cbiAqICAgICB7eyBpdGVtLnZhbHVlIH19XG4gKiAgIDwvaWd4LWRyb3AtZG93bi1pdGVtPlxuICogPC9pZ3gtZHJvcC1kb3duPlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LWRyb3AtZG93bicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2Ryb3AtZG93bi5jb21wb25lbnQuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBJR1hfRFJPUERPV05fQkFTRSwgdXNlRXhpc3Rpbmc6IElneERyb3BEb3duQ29tcG9uZW50IH1dXG59KVxuZXhwb3J0IGNsYXNzIElneERyb3BEb3duQ29tcG9uZW50IGV4dGVuZHMgSWd4RHJvcERvd25CYXNlRGlyZWN0aXZlIGltcGxlbWVudHMgSURyb3BEb3duQmFzZSwgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICAgIHByb3RlY3RlZCBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG4gICAgcHJvdGVjdGVkIF9zY3JvbGxQb3NpdGlvbjogbnVtYmVyO1xuXG4gICAgQENvbnRlbnRDaGlsZChJZ3hGb3JPZkRpcmVjdGl2ZSwgeyByZWFkOiBJZ3hGb3JPZkRpcmVjdGl2ZSB9KVxuICAgIHByb3RlY3RlZCB2aXJ0RGlyOiBJZ3hGb3JPZkRpcmVjdGl2ZTxhbnk+O1xuXG4gICAgQFZpZXdDaGlsZChJZ3hUb2dnbGVEaXJlY3RpdmUsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIHRvZ2dsZURpcmVjdGl2ZTogSWd4VG9nZ2xlRGlyZWN0aXZlO1xuXG4gICAgQFZpZXdDaGlsZCgnc2Nyb2xsQ29udGFpbmVyJywgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBwcm90ZWN0ZWQgc2Nyb2xsQ29udGFpbmVyUmVmOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBJZ3hEcm9wRG93bkl0ZW1Db21wb25lbnQpLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pXG4gICAgcHVibGljIGNoaWxkcmVuOiBRdWVyeUxpc3Q8SWd4RHJvcERvd25JdGVtQmFzZURpcmVjdGl2ZT47XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIGJlZm9yZSB0aGUgZHJvcGRvd24gaXMgb3BlbmVkXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1kcm9wLWRvd24gKG9uT3BlbmluZyk9J2hhbmRsZU9wZW5pbmcoKSc+PC9pZ3gtZHJvcC1kb3duPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvbk9wZW5pbmcgPSBuZXcgRXZlbnRFbWl0dGVyPENhbmNlbGFibGVFdmVudEFyZ3MgJiBJQmFzZUV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgYWZ0ZXIgdGhlIGRyb3Bkb3duIGlzIG9wZW5lZFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtZHJvcC1kb3duIChvbk9wZW5lZCk9J2hhbmRsZU9wZW5lZCgpJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uT3BlbmVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCBiZWZvcmUgdGhlIGRyb3Bkb3duIGlzIGNsb3NlZFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtZHJvcC1kb3duIChvbkNsb3NpbmcpPSdoYW5kbGVDbG9zaW5nKCknPjwvaWd4LWRyb3AtZG93bj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25DbG9zaW5nID0gbmV3IEV2ZW50RW1pdHRlcjxDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncyAmIElCYXNlRXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCBhZnRlciB0aGUgZHJvcGRvd24gaXMgY2xvc2VkXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1kcm9wLWRvd24gKG9uQ2xvc2VkKT0naGFuZGxlQ2xvc2VkKCknPjwvaWd4LWRyb3AtZG93bj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25DbG9zZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzL3NldHMgd2hldGhlciBpdGVtcyB0YWtlIGZvY3VzLiBEaXNhYmxlZCBieSBkZWZhdWx0LlxuICAgICAqIFdoZW4gZW5hYmxlZCwgZHJvcCBkb3duIGl0ZW1zIGdhaW4gdGFiIGluZGV4IGFuZCBhcmUgZm9jdXNlZCB3aGVuIGFjdGl2ZSAtXG4gICAgICogdGhpcyBpbmNsdWRlcyBhY3RpdmF0aW5nIHRoZSBzZWxlY3RlZCBpdGVtIHdoZW4gb3BlbmluZyB0aGUgZHJvcCBkb3duIGFuZCBtb3Zpbmcgd2l0aCBrZXlib2FyZCBuYXZpZ2F0aW9uLlxuICAgICAqXG4gICAgICogTm90ZTogS2VlcCB0aGF0IGZvY3VzIHNoaWZ0IGluIG1pbmQgd2hlbiB1c2luZyB0aGUgaWd4RHJvcERvd25JdGVtTmF2aWdhdGlvbiBkaXJlY3RpdmVcbiAgICAgKiBhbmQgZW5zdXJlIGl0J3MgcGxhY2VkIGVpdGhlciBvbiBlYWNoIGZvY3VzYWJsZSBpdGVtIG9yIGEgY29tbW9uIGFuY2VzdG9yIHRvIGFsbG93IGl0IHRvIGhhbmRsZSBrZXlib2FyZCBldmVudHMuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IGRyb3BEb3duQWxsb3dzSXRlbUZvY3VzID0gdGhpcy5kcm9wZG93bi5hbGxvd0l0ZW1zRm9jdXM7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLXNldC0tPlxuICAgICAqIDxpZ3gtZHJvcC1kb3duIFthbGxvd0l0ZW1zRm9jdXNdPSd0cnVlJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgYWxsb3dJdGVtc0ZvY3VzID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZm9jdXNlZEl0ZW0oKTogSWd4RHJvcERvd25JdGVtQmFzZURpcmVjdGl2ZSB7XG4gICAgICAgIGlmICh0aGlzLnZpcnREaXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9mb2N1c2VkSXRlbSAmJiB0aGlzLl9mb2N1c2VkSXRlbS5pbmRleCAhPT0gLTEgP1xuICAgICAgICAgICAgICAgICh0aGlzLmNoaWxkcmVuLmZpbmQoZSA9PiBlLmluZGV4ID09PSB0aGlzLl9mb2N1c2VkSXRlbS5pbmRleCkgfHwgbnVsbCkgOlxuICAgICAgICAgICAgICAgIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvY3VzZWRJdGVtO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgZm9jdXNlZEl0ZW0odmFsdWU6IElneERyb3BEb3duSXRlbUJhc2VEaXJlY3RpdmUpIHtcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIoYCR7dGhpcy5pZH0tYWN0aXZlYCk7XG4gICAgICAgICAgICB0aGlzLl9mb2N1c2VkSXRlbSA9IG51bGw7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZm9jdXNlZEl0ZW0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMudmlydERpcikge1xuICAgICAgICAgICAgdGhpcy5fZm9jdXNlZEl0ZW0gPSB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLnZhbHVlLFxuICAgICAgICAgICAgICAgIGluZGV4OiB2YWx1ZS5pbmRleFxuICAgICAgICAgICAgfSBhcyBJZ3hEcm9wRG93bkl0ZW1CYXNlRGlyZWN0aXZlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldChgJHt0aGlzLmlkfS1hY3RpdmVgLCBuZXcgU2V0KFt0aGlzLl9mb2N1c2VkSXRlbV0pKTtcbiAgICB9XG5cbiAgICBASW5wdXQoKVxuICAgIGdldCBpZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5faWQ7XG4gICAgfVxuICAgIHNldCBpZCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlRGlyZWN0aXZlLmlkID0gdmFsdWU7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldCh2YWx1ZSwgdGhpcy5zZWxlY3Rpb24uZ2V0KHRoaXMuaWQpKTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIodGhpcy5pZCk7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldCh2YWx1ZSwgdGhpcy5zZWxlY3Rpb24uZ2V0KGAke3RoaXMuaWR9LWFjdGl2ZWApKTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIoYCR7dGhpcy5pZH0tYWN0aXZlYCk7XG4gICAgICAgIHRoaXMuX2lkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqIElkIG9mIHRoZSBpbnRlcm5hbCBsaXN0Ym94IG9mIHRoZSBkcm9wIGRvd24gKi9cbiAgICBwdWJsaWMgZ2V0IGxpc3RJZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaWQgKyAnLWxpc3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBjdXJyZW50bHkgc2VsZWN0ZWQgaXRlbVxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBjdXJyZW50SXRlbSA9IHRoaXMuZHJvcGRvd24uc2VsZWN0ZWRJdGVtO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc2VsZWN0ZWRJdGVtKCk6IElneERyb3BEb3duSXRlbUJhc2VEaXJlY3RpdmUge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSB0aGlzLnNlbGVjdGlvbi5maXJzdF9pdGVtKHRoaXMuaWQpO1xuICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtKSB7XG4gICAgICAgICAgICByZXR1cm4gc2VsZWN0ZWRJdGVtO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgaWYgdGhlIGRyb3Bkb3duIGlzIGNvbGxhcHNlZFxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBpc0NvbGxhcHNlZCA9IHRoaXMuZHJvcGRvd24uY29sbGFwc2VkO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgY29sbGFwc2VkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy50b2dnbGVEaXJlY3RpdmUuY29sbGFwc2VkO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyBnZXQgc2Nyb2xsQ29udGFpbmVyKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Nyb2xsQ29udGFpbmVyUmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjb2xsZWN0aW9uTGVuZ3RoKCkge1xuICAgICAgICBpZiAodGhpcy52aXJ0RGlyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52aXJ0RGlyLnRvdGFsSXRlbUNvdW50IHx8IHRoaXMudmlydERpci5pZ3hGb3JPZi5sZW5ndGg7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvdGVjdGVkIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgIHByb3RlY3RlZCBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBJZ3hTZWxlY3Rpb25BUElTZXJ2aWNlLFxuICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERpc3BsYXlEZW5zaXR5VG9rZW4pIHByb3RlY3RlZCBfZGlzcGxheURlbnNpdHlPcHRpb25zOiBJRGlzcGxheURlbnNpdHlPcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKGVsZW1lbnRSZWYsIGNkciwgX2Rpc3BsYXlEZW5zaXR5T3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIGRyb3Bkb3duXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5kcm9wZG93bi5vcGVuKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIG9wZW4ob3ZlcmxheVNldHRpbmdzPzogT3ZlcmxheVNldHRpbmdzKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlRGlyZWN0aXZlLm9wZW4ob3ZlcmxheVNldHRpbmdzKTtcbiAgICAgICAgdGhpcy51cGRhdGVTY3JvbGxQb3NpdGlvbigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgZHJvcGRvd25cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmRyb3Bkb3duLmNsb3NlKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGNsb3NlKCkge1xuICAgICAgICB0aGlzLnRvZ2dsZURpcmVjdGl2ZS5jbG9zZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRvZ2dsZXMgdGhlIGRyb3Bkb3duXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5kcm9wZG93bi50b2dnbGUoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgdG9nZ2xlKG92ZXJsYXlTZXR0aW5ncz86IE92ZXJsYXlTZXR0aW5ncykge1xuICAgICAgICBpZiAodGhpcy5jb2xsYXBzZWQgfHwgdGhpcy50b2dnbGVEaXJlY3RpdmUuaXNDbG9zaW5nKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW4ob3ZlcmxheVNldHRpbmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbGVjdCBhbiBpdGVtIGJ5IGluZGV4XG4gICAgICogQHBhcmFtIGluZGV4IG9mIHRoZSBpdGVtIHRvIHNlbGVjdDsgSWYgdGhlIGRyb3AgZG93biB1c2VzICppZ3hGb3IsIHBhc3MgdGhlIGluZGV4IGluIGRhdGFcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0U2VsZWN0ZWRJdGVtKGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBuZXdTZWxlY3Rpb246IElneERyb3BEb3duSXRlbUJhc2VEaXJlY3RpdmU7XG4gICAgICAgIGlmICh0aGlzLnZpcnREaXIpIHtcbiAgICAgICAgICAgIG5ld1NlbGVjdGlvbiA9IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogdGhpcy52aXJ0RGlyLmlneEZvck9mW2luZGV4XSxcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgfSBhcyBJZ3hEcm9wRG93bkl0ZW1CYXNlRGlyZWN0aXZlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3U2VsZWN0aW9uID0gdGhpcy5pdGVtc1tpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZWxlY3RJdGVtKG5ld1NlbGVjdGlvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIHRvIHRoZSBpdGVtIG9uIHRoZSBzcGVjaWZpZWQgaW5kZXhcbiAgICAgKiBJZiB0aGUgZGF