UNPKG

igniteui-angular

Version:

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

472 lines • 38.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { CommonModule } from '@angular/common'; import { Component, ContentChildren, ElementRef, EventEmitter, forwardRef, HostBinding, HostListener, Input, NgModule, Output, QueryList, ViewChild, ViewChildren } from '@angular/core'; import { IgxBadgeModule } from '../badge/badge.component'; import { IgxRippleModule } from '../directives/ripple/ripple.directive'; import { IgxIconModule } from '../icon/index'; import { IgxTabItemComponent } from './tab-item.component'; import { IgxTabsGroupComponent } from './tabs-group.component'; import { IgxLeftButtonStyleDirective, IgxRightButtonStyleDirective, IgxTabItemTemplateDirective } from './tabs.directives'; import { IgxTabsBase } from './tabs.common'; /** @enum {string} */ const TabsType = { FIXED: 'fixed', CONTENTFIT: 'contentfit', }; export { TabsType }; export class IgxTabsComponent { /** * @param {?} _element */ constructor(_element) { this._element = _element; /** * Defines the tab header sizing mode. You can choose between `contentfit` or `fixed`. * By default the header sizing mode is `contentfit`. * ```html * <igx-tabs tabsType="fixed"> * <igx-tabs-group label="HOME">Home</igx-tabs-group> * </igx-tabs> * ``` */ this.tabsType = 'contentfit'; /** * @hidden */ this.class = ''; /** * Emitted when a tab item is deselected. * ```html * <igx-tabs (onTabItemDeselected)="itemDeselected($event)"> * <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group> * <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group> * </igx-tabs> * ``` * ```typescript * itemDeselected(e){ * const tabGroup = e.group; * const tabItem = e.tab; * } * ``` */ this.onTabItemDeselected = new EventEmitter(); /** * Emitted when a tab item is selected. * ```html * <igx-tabs (onTabItemSelected)="itemSelected($event)"> * <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group> * <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group> * </igx-tabs> * ``` * ```typescript * itemSelected(e){ * const tabGroup = e.group; * const tabItem = e.tab; * } * ``` */ this.onTabItemSelected = new EventEmitter(); /** * @hidden */ this.offset = 0; this._selectedIndex = 0; } /** * An \@Input property that sets the value of the `selectedIndex`. * Default value is 0. * ```html * <igx-tabs selectedIndex="1"> * ``` * @return {?} */ get selectedIndex() { return this._selectedIndex; } /** * @param {?} index * @return {?} */ set selectedIndex(index) { this._selectedIndex = index; this.setSelectedGroup(); } /** * @hidden * @return {?} */ get cssClass() { /** @type {?} */ const defaultStyle = `igx-tabs`; /** @type {?} */ const fixedStyle = `igx-tabs--fixed`; /** @type {?} */ const iconStyle = `igx-tabs--icons`; /** @type {?} */ const iconLabelFound = this.groups.find((group) => group.icon != null && group.label != null); /** @type {?} */ let css; switch (TabsType[this.tabsType.toUpperCase()]) { case TabsType.FIXED: { css = fixedStyle; break; } default: { css = defaultStyle; break; } } // Layout fix for items with icons if (iconLabelFound !== undefined) { css = `${css} ${iconStyle}`; } return `${css} ${this.class}`; } /** * @hidden * @param {?} args * @return {?} */ selectedGroupHandler(args) { /** @type {?} */ const prevSelectedIndex = this.selectedIndex; if (prevSelectedIndex !== -1 && this.groups.toArray()[prevSelectedIndex] !== undefined) { this.onTabItemDeselected.emit({ tab: this.groups.toArray()[prevSelectedIndex].relatedTab, group: this.groups.toArray()[prevSelectedIndex] }); } this.selectedIndex = args.group.index; this.groups.forEach((p) => { if (p.index !== this.selectedIndex) { this.deselectGroup(p); } }); } /** * @hidden * @param {?} event * @return {?} */ scrollLeft(event) { this.scroll(false); } /** * @hidden * @param {?} event * @return {?} */ scrollRight(event) { this.scroll(true); } /** * @hidden * @param {?} element * @param {?} scrollRight * @return {?} */ scrollElement(element, scrollRight) { /** @type {?} */ const viewPortWidth = this.viewPort.nativeElement.offsetWidth; this.offset = (scrollRight) ? element.offsetWidth + element.offsetLeft - viewPortWidth : element.offsetLeft; this.itemsContainer.nativeElement.style.transform = `translate(${-this.offset}px)`; } /** * Gets the selected `IgxTabItemComponent`. * ``` * const selectedItem = this.myTabComponent.selectedTabItem; * ``` * @return {?} */ get selectedTabItem() { if (this.tabs && this.selectedIndex !== undefined) { return this.tabs.toArray()[this.selectedIndex]; } } /** * @hidden * @return {?} */ ngAfterViewInit() { this.setSelectedGroup(); this._groupChanges$ = this.groups.changes.subscribe(() => { this.resetSelectionOnCollectionChanged(); }); } /** * @hidden * @return {?} */ ngOnDestroy() { if (this._groupChanges$) { this._groupChanges$.unsubscribe(); } } /** * @private * @return {?} */ setSelectedGroup() { requestAnimationFrame(() => { if (this.selectedIndex <= 0 || this.selectedIndex >= this.groups.length) { // if nothing is selected - select the first tabs group this.selectGroupByIndex(0); } else { this.selectGroupByIndex(this.selectedIndex); } }); } /** * @private * @return {?} */ resetSelectionOnCollectionChanged() { setTimeout(() => { if (this.groups.toArray()[this.selectedIndex] !== undefined) { // persist the selected index and applied it to the new collection this.selectGroupByIndex(this.selectedIndex); } else { if (this.selectedIndex >= this.groups.length) { // in case the selected index is no longer valid, select the last group in the new collection this.selectGroupByIndex(this.groups.length - 1); } } }, 0); } /** * @private * @param {?} selectedIndex * @return {?} */ selectGroupByIndex(selectedIndex) { /** @type {?} */ const selectableGroups = this.groups.filter((selectableGroup) => !selectableGroup.disabled); /** @type {?} */ const group = selectableGroups[selectedIndex]; if (group) { group.select(0); } } /** * @private * @param {?} group * @return {?} */ deselectGroup(group) { // Cannot deselect the selected tab - this will mean that there will be not selected tab left if (group.disabled || this.selectedTabItem.index === group.index) { return; } group.isSelected = false; group.relatedTab.tabindex = -1; } /** * @private * @param {?} scrollRight * @return {?} */ scroll(scrollRight) { /** @type {?} */ const tabsArray = this.tabs.toArray(); for (const tab of tabsArray) { /** @type {?} */ const element = tab.nativeTabItem.nativeElement; if (scrollRight) { if (element.offsetWidth + element.offsetLeft > this.viewPort.nativeElement.offsetWidth + this.offset) { this.scrollElement(element, scrollRight); break; } } else { if (element.offsetWidth + element.offsetLeft >= this.offset) { this.scrollElement(element, scrollRight); break; } } } } } IgxTabsComponent.decorators = [ { type: Component, args: [{ selector: 'igx-tabs', template: "<!-- TODO Remove tab container from here -->\n<div #tabsContainer>\n <div class=\"igx-tabs__header\" #headerContainer>\n <button igxRipple class=\"igx-tabs__header-button\" igxButton=\"icon\" (click)=\"scrollLeft($event)\" igxLeftButtonStyle>\n <igx-icon fontSet=\"material\">navigate_before</igx-icon>\n </button>\n <div class=\"igx-tabs__header-wrapper-fixed\" #viewPort>\n <div #itemsContainer class=\"igx-tabs__header-wrapper-fluid\">\n <igx-tab-item igxRipple *ngFor=\"let group of groups\" [id]=\"'igx-tab-item-' + group.index\" [attr.aria-label]=\"group.label\"\n [attr.aria-disabled]=\"group.disabled\" [attr.aria-selected]=\"group.isSelected\" [attr.aria-controls]=\"'igx-tab-item-group-'+ group.index\"\n [ngClass]=\"{\n 'igx-tabs__header-menu-item': !group.isSelected && !group.disabled,\n 'igx-tabs__header-menu-item--selected': group.isSelected,\n 'igx-tabs__header-menu-item--disabled': group.disabled }\" [relatedGroup]=\"group\" role=\"tab\">\n </igx-tab-item>\n <div #selectedIndicator *ngIf=\"groups.length > 0\" class=\"igx-tabs__header-menu-item-indicator\"></div>\n </div>\n </div>\n <button igxRipple class=\"igx-tabs__header-button\" igxButton=\"icon\" (click)=\"scrollRight($event)\" igxRightButtonStyle>\n <igx-icon fontSet=\"material\">navigate_next</igx-icon>\n </button>\n </div>\n <div class=\"igx-tabs__content-fixed\">\n <div #contentsContainer class=\"igx-tabs__content-fluid\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>", providers: [{ provide: IgxTabsBase, useExisting: IgxTabsComponent }] }] } ]; /** @nocollapse */ IgxTabsComponent.ctorParameters = () => [ { type: ElementRef } ]; IgxTabsComponent.propDecorators = { groups: [{ type: ContentChildren, args: [forwardRef(() => IgxTabsGroupComponent),] }], selectedIndex: [{ type: Input }], tabsType: [{ type: Input, args: ['tabsType',] }], class: [{ type: Input }], onTabItemDeselected: [{ type: Output }], onTabItemSelected: [{ type: Output }], contentsContainer: [{ type: ViewChild, args: ['contentsContainer',] }], headerContainer: [{ type: ViewChild, args: ['headerContainer',] }], itemsContainer: [{ type: ViewChild, args: ['itemsContainer',] }], selectedIndicator: [{ type: ViewChild, args: ['selectedIndicator',] }], tabsContainer: [{ type: ViewChild, args: ['tabsContainer',] }], viewPort: [{ type: ViewChild, args: ['viewPort',] }], tabs: [{ type: ViewChildren, args: [forwardRef(() => IgxTabItemComponent),] }], cssClass: [{ type: HostBinding, args: ['attr.class',] }], selectedGroupHandler: [{ type: HostListener, args: ['onTabItemSelected', ['$event'],] }] }; if (false) { /** * Provides an observable collection of all `IgxTabsGroupComponent`s. * ```typescript * const groupItems = this.myTabComponent.tabs; * ``` * @type {?} */ IgxTabsComponent.prototype.groups; /** * Defines the tab header sizing mode. You can choose between `contentfit` or `fixed`. * By default the header sizing mode is `contentfit`. * ```html * <igx-tabs tabsType="fixed"> * <igx-tabs-group label="HOME">Home</igx-tabs-group> * </igx-tabs> * ``` * @type {?} */ IgxTabsComponent.prototype.tabsType; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.class; /** * Emitted when a tab item is deselected. * ```html * <igx-tabs (onTabItemDeselected)="itemDeselected($event)"> * <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group> * <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group> * </igx-tabs> * ``` * ```typescript * itemDeselected(e){ * const tabGroup = e.group; * const tabItem = e.tab; * } * ``` * @type {?} */ IgxTabsComponent.prototype.onTabItemDeselected; /** * Emitted when a tab item is selected. * ```html * <igx-tabs (onTabItemSelected)="itemSelected($event)"> * <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group> * <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group> * </igx-tabs> * ``` * ```typescript * itemSelected(e){ * const tabGroup = e.group; * const tabItem = e.tab; * } * ``` * @type {?} */ IgxTabsComponent.prototype.onTabItemSelected; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.contentsContainer; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.headerContainer; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.itemsContainer; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.selectedIndicator; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.tabsContainer; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.viewPort; /** * Provides an observable collection of all `IgxTabItemComponent`s. * ```typescript * const tabItems = this.myTabComponent.tabs; * ``` * @type {?} */ IgxTabsComponent.prototype.tabs; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.calculatedWidth; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.visibleItemsWidth; /** * @hidden * @type {?} */ IgxTabsComponent.prototype.offset; /** * @type {?} * @private */ IgxTabsComponent.prototype._groupChanges$; /** * @type {?} * @private */ IgxTabsComponent.prototype._selectedIndex; /** * @type {?} * @private */ IgxTabsComponent.prototype._element; } /** * @hidden */ export class IgxTabsModule { } IgxTabsModule.decorators = [ { type: NgModule, args: [{ declarations: [IgxTabsComponent, IgxTabsGroupComponent, IgxTabItemComponent, IgxTabItemTemplateDirective, IgxRightButtonStyleDirective, IgxLeftButtonStyleDirective], exports: [IgxTabsComponent, IgxTabsGroupComponent, IgxTabItemComponent, IgxTabItemTemplateDirective, IgxRightButtonStyleDirective, IgxLeftButtonStyleDirective], imports: [CommonModule, IgxBadgeModule, IgxIconModule, IgxRippleModule] },] } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL3RhYnMvdGFicy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBRUgsU0FBUyxFQUNULGVBQWUsRUFDZixVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsWUFBWSxFQUVmLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsNEJBQTRCLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzSCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7SUFHeEMsT0FBUSxPQUFPO0lBQ2YsWUFBYSxZQUFZOzs7QUFTN0IsTUFBTSxPQUFPLGdCQUFnQjs7OztJQXNPekIsWUFBb0IsUUFBb0I7UUFBcEIsYUFBUSxHQUFSLFFBQVEsQ0FBWTs7Ozs7Ozs7OztRQWhNakMsYUFBUSxHQUFzQixZQUFZLENBQUM7Ozs7UUFNM0MsVUFBSyxHQUFHLEVBQUUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7OztRQWlCRCx3QkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFD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QkFNN0IsU0FBUyxTQUFDLGVBQWU7dUJBTXpCLFNBQVMsU0FBQyxVQUFVO21CQVNwQixZQUFZLFNBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLG1CQUFtQixDQUFDO3VCQXdCbEQsV0FBVyxTQUFDLFlBQVk7bUNBNkJ4QixZQUFZLFNBQUMsbUJBQW1CLEVBQUUsQ0FBQyxRQUFRLENBQUM7Ozs7Ozs7Ozs7SUF2SzdDLGtDQUNnRDs7Ozs7Ozs7Ozs7SUE0QmhELG9DQUNrRDs7Ozs7SUFLbEQsaUNBQ2tCOzs7Ozs7Ozs7Ozs7Ozs7OztJQWlCbEIsK0NBQTBEOzs7Ozs7Ozs7Ozs7Ozs7OztJQWlCMUQsNkNBQXdEOzs7OztJQUt4RCw2Q0FDcUM7Ozs7O0lBS3JDLDJDQUNtQzs7Ozs7SUFLbkMsMENBQ2tDOzs7OztJQUtsQyw2Q0FDcUM7Ozs7O0lBS3JDLHlDQUNpQzs7Ozs7SUFLakMsb0NBQzRCOzs7Ozs7OztJQVE1QixnQ0FDNEM7Ozs7O0lBSzVDLDJDQUErQjs7Ozs7SUFLL0IsNkNBQWlDOzs7OztJQUtqQyxrQ0FBa0I7Ozs7O0lBRWxCLDBDQUFxQzs7Ozs7SUFDckMsMENBQTJCOzs7OztJQXlGZixvQ0FBNEI7Ozs7O0FBd0c1QyxNQUFNLE9BQU8sYUFBYTs7O1lBaEJ6QixRQUFRLFNBQUM7Z0JBQ04sWUFBWSxFQUFFLENBQUMsZ0JBQWdCO29CQUMzQixxQkFBcUI7b0JBQ3JCLG1CQUFtQjtvQkFDbkIsMkJBQTJCO29CQUMzQiw0QkFBNEI7b0JBQzVCLDJCQUEyQixDQUFDO2dCQUNoQyxPQUFPLEVBQUUsQ0FBQyxnQkFBZ0I7b0JBQ3RCLHFCQUFxQjtvQkFDckIsbUJBQW1CO29CQUNuQiwyQkFBMkI7b0JBQzNCLDRCQUE0QjtvQkFDNUIsMkJBQTJCLENBQUM7Z0JBQ2hDLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQzthQUMxRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBmb3J3YXJkUmVmLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIEhvc3RMaXN0ZW5lcixcbiAgICBJbnB1dCxcbiAgICBOZ01vZHVsZSxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3Q2hpbGRyZW4sXG4gICAgT25EZXN0cm95XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBJZ3hCYWRnZU1vZHVsZSB9IGZyb20gJy4uL2JhZGdlL2JhZGdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hSaXBwbGVNb2R1bGUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3JpcHBsZS9yaXBwbGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEljb25Nb2R1bGUgfSBmcm9tICcuLi9pY29uL2luZGV4JztcbmltcG9ydCB7IElneFRhYkl0ZW1Db21wb25lbnQgfSBmcm9tICcuL3RhYi1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hUYWJzR3JvdXBDb21wb25lbnQgfSBmcm9tICcuL3RhYnMtZ3JvdXAuY29tcG9uZW50JztcbmltcG9ydCB7IElneExlZnRCdXR0b25TdHlsZURpcmVjdGl2ZSwgSWd4UmlnaHRCdXR0b25TdHlsZURpcmVjdGl2ZSwgSWd4VGFiSXRlbVRlbXBsYXRlRGlyZWN0aXZlIH0gZnJvbSAnLi90YWJzLmRpcmVjdGl2ZXMnO1xuaW1wb3J0IHsgSWd4VGFic0Jhc2UgfSBmcm9tICcuL3RhYnMuY29tbW9uJztcblxuZXhwb3J0IGVudW0gVGFic1R5cGUge1xuICAgIEZJWEVEID0gJ2ZpeGVkJyxcbiAgICBDT05URU5URklUID0gJ2NvbnRlbnRmaXQnXG59XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LXRhYnMnLFxuICAgIHRlbXBsYXRlVXJsOiAndGFicy5jb21wb25lbnQuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBJZ3hUYWJzQmFzZSwgdXNlRXhpc3Rpbmc6IElneFRhYnNDb21wb25lbnQgfV1cbn0pXG5cbmV4cG9ydCBjbGFzcyBJZ3hUYWJzQ29tcG9uZW50IGltcGxlbWVudHMgSWd4VGFic0Jhc2UsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG5cbiAgICAvKipcbiAgICAqIFByb3ZpZGVzIGFuIG9ic2VydmFibGUgY29sbGVjdGlvbiBvZiBhbGwgYElneFRhYnNHcm91cENvbXBvbmVudGBzLlxuICAgICogYGBgdHlwZXNjcmlwdFxuICAgICogY29uc3QgZ3JvdXBJdGVtcyA9IHRoaXMubXlUYWJDb21wb25lbnQudGFicztcbiAgICAqIGBgYFxuICAgICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IElneFRhYnNHcm91cENvbXBvbmVudCkpXG4gICAgcHVibGljIGdyb3VwczogUXVlcnlMaXN0PElneFRhYnNHcm91cENvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgdGhlIHZhbHVlIG9mIHRoZSBgc2VsZWN0ZWRJbmRleGAuXG4gICAgKiBEZWZhdWx0IHZhbHVlIGlzIDAuXG4gICAgKiBgYGBodG1sXG4gICAgKiA8aWd4LXRhYnMgc2VsZWN0ZWRJbmRleD1cIjFcIj5cbiAgICAqIGBgYFxuICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ2V0IHNlbGVjdGVkSW5kZXgoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBzZWxlY3RlZEluZGV4KGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IGluZGV4O1xuICAgICAgICB0aGlzLnNldFNlbGVjdGVkR3JvdXAoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIHRoZSB0YWIgaGVhZGVyIHNpemluZyBtb2RlLiBZb3UgY2FuIGNob29zZSBiZXR3ZWVuIGBjb250ZW50Zml0YCBvciBgZml4ZWRgLlxuICAgICAqIEJ5IGRlZmF1bHQgdGhlIGhlYWRlciBzaXppbmcgbW9kZSBpcyBgY29udGVudGZpdGAuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtdGFicyB0YWJzVHlwZT1cImZpeGVkXCI+XG4gICAgICogICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIkhPTUVcIj5Ib21lPC9pZ3gtdGFicy1ncm91cD5cbiAgICAgKiA8L2lneC10YWJzPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgndGFic1R5cGUnKVxuICAgIHB1YmxpYyB0YWJzVHlwZTogc3RyaW5nIHwgVGFic1R5cGUgPSAnY29udGVudGZpdCc7XG5cbiAgICAvKipcbiAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGNsYXNzID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIHdoZW4gYSB0YWIgaXRlbSBpcyBkZXNlbGVjdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LXRhYnMgKG9uVGFiSXRlbURlc2VsZWN0ZWQpPVwiaXRlbURlc2VsZWN0ZWQoJGV2ZW50KVwiPlxuICAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDFcIj5UaGlzIGlzIFRhYiAxIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAyXCI+VGhpcyBpcyBUYWIgMiBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgICogPC9pZ3gtdGFicz5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogaXRlbURlc2VsZWN0ZWQoZSl7XG4gICAgICogICAgICBjb25zdCB0YWJHcm91cCA9IGUuZ3JvdXA7XG4gICAgICogICAgICBjb25zdCB0YWJJdGVtID0gZS50YWI7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25UYWJJdGVtRGVzZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICogRW1pdHRlZCB3aGVuIGEgdGFiIGl0ZW0gaXMgc2VsZWN0ZWQuXG4gICAgKiBgYGBodG1sXG4gICAgKiA8aWd4LXRhYnMgKG9uVGFiSXRlbVNlbGVjdGVkKT1cIml0ZW1TZWxlY3RlZCgkZXZlbnQpXCI+XG4gICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAxXCI+VGhpcyBpcyBUYWIgMSBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAyXCI+VGhpcyBpcyBUYWIgMiBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgKiA8L2lneC10YWJzPlxuICAgICogYGBgXG4gICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgKiBpdGVtU2VsZWN0ZWQoZSl7XG4gICAgKiAgICAgIGNvbnN0IHRhYkdyb3VwID0gZS5ncm91cDtcbiAgICAqICAgICAgY29uc3QgdGFiSXRlbSA9IGUudGFiO1xuICAgICogfVxuICAgICogYGBgXG4gICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIG9uVGFiSXRlbVNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2NvbnRlbnRzQ29udGFpbmVyJylcbiAgICBwdWJsaWMgY29udGVudHNDb250YWluZXI6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnaGVhZGVyQ29udGFpbmVyJylcbiAgICBwdWJsaWMgaGVhZGVyQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2l0ZW1zQ29udGFpbmVyJylcbiAgICBwdWJsaWMgaXRlbXNDb250YWluZXI6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnc2VsZWN0ZWRJbmRpY2F0b3InKVxuICAgIHB1YmxpYyBzZWxlY3RlZEluZGljYXRvcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICogQGhpZGRlblxuICAgICovXG4gICAgQFZpZXdDaGlsZCgndGFic0NvbnRhaW5lcicpXG4gICAgcHVibGljIHRhYnNDb250YWluZXI6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgndmlld1BvcnQnKVxuICAgIHB1YmxpYyB2aWV3UG9ydDogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIFByb3ZpZGVzIGFuIG9ic2VydmFibGUgY29sbGVjdGlvbiBvZiBhbGwgYElneFRhYkl0ZW1Db21wb25lbnRgcy5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgdGFiSXRlbXMgPSB0aGlzLm15VGFiQ29tcG9uZW50LnRhYnM7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IElneFRhYkl0ZW1Db21wb25lbnQpKVxuICAgIHB1YmxpYyB0YWJzOiBRdWVyeUxpc3Q8SWd4VGFiSXRlbUNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGNhbGN1bGF0ZWRXaWR0aDogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB2aXNpYmxlSXRlbXNXaWR0aDogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBvZmZzZXQgPSAwO1xuXG4gICAgcHJpdmF0ZSBfZ3JvdXBDaGFuZ2VzJDogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgX3NlbGVjdGVkSW5kZXggPSAwO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5jbGFzcycpXG4gICAgcHVibGljIGdldCBjc3NDbGFzcygpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdFN0eWxlID0gYGlneC10YWJzYDtcbiAgICAgICAgY29uc3QgZml4ZWRTdHlsZSA9IGBpZ3gtdGFicy0tZml4ZWRgO1xuICAgICAgICBjb25zdCBpY29uU3R5bGUgPSBgaWd4LXRhYnMtLWljb25zYDtcbiAgICAgICAgY29uc3QgaWNvbkxhYmVsRm91bmQgPSB0aGlzLmdyb3Vwcy5maW5kKChncm91cCkgPT4gZ3JvdXAuaWNvbiAhPSBudWxsICYmIGdyb3VwLmxhYmVsICE9IG51bGwpO1xuICAgICAgICBsZXQgY3NzO1xuICAgICAgICBzd2l0Y2ggKFRhYnNUeXBlW3RoaXMudGFic1R5cGUudG9VcHBlckNhc2UoKV0pIHtcbiAgICAgICAgICAgIGNhc2UgVGFic1R5cGUuRklYRUQ6IHtcbiAgICAgICAgICAgICAgICBjc3MgPSBmaXhlZFN0eWxlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIGNzcyA9IGRlZmF1bHRTdHlsZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIExheW91dCBmaXggZm9yIGl0ZW1zIHdpdGggaWNvbnNcbiAgICAgICAgaWYgKGljb25MYWJlbEZvdW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNzcyA9IGAke2Nzc30gJHtpY29uU3R5bGV9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBgJHtjc3N9ICR7dGhpcy5jbGFzc31gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBASG9zdExpc3RlbmVyKCdvblRhYkl0ZW1TZWxlY3RlZCcsIFsnJGV2ZW50J10pXG4gICAgcHVibGljIHNlbGVjdGVkR3JvdXBIYW5kbGVyKGFyZ3MpIHtcbiAgICAgICAgY29uc3QgcHJldlNlbGVjdGVkSW5kZXggPSB0aGlzLnNlbGVjdGVkSW5kZXg7XG4gICAgICAgIGlmIChwcmV2U2VsZWN0ZWRJbmRleCAhPT0gLTEgJiYgdGhpcy5ncm91cHMudG9BcnJheSgpW3ByZXZTZWxlY3RlZEluZGV4XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLm9uVGFiSXRlbURlc2VsZWN0ZWQuZW1pdChcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHRhYjogdGhpcy5ncm91cHMudG9BcnJheSgpW3ByZXZTZWxlY3RlZEluZGV4XS5yZWxhdGVkVGFiLFxuICAgICAgICAgICAgICAgICAgICBncm91cDogdGhpcy5ncm91cHMudG9BcnJheSgpW3ByZXZTZWxlY3RlZEluZGV4XVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gYXJncy5ncm91cC5pbmRleDtcbiAgICAgICAgdGhpcy5ncm91cHMuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICAgICAgaWYgKHAuaW5kZXggIT09IHRoaXMuc2VsZWN0ZWRJbmRleCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVzZWxlY3RHcm91cChwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBzY3JvbGxMZWZ0KGV2ZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHNjcm9sbFJpZ2h0KGV2ZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2Nyb2xsRWxlbWVudChlbGVtZW50OiBhbnksIHNjcm9sbFJpZ2h0OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHZpZXdQb3J0V2lkdGggPSB0aGlzLnZpZXdQb3J0Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG5cbiAgICAgICAgdGhpcy5vZmZzZXQgPSAoc2Nyb2xsUmlnaHQpID8gZWxlbWVudC5vZmZzZXRXaWR0aCArIGVsZW1lbnQub2Zmc2V0TGVmdCAtIHZpZXdQb3J0V2lkdGggOiBlbGVtZW50Lm9mZnNldExlZnQ7XG4gICAgICAgIHRoaXMuaXRlbXNDb250YWluZXIubmF0aXZlRWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7LXRoaXMub2Zmc2V0fXB4KWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc2VsZWN0ZWQgYElneFRhYkl0ZW1Db21wb25lbnRgLlxuICAgICAqIGBgYFxuICAgICAqIGNvbnN0IHNlbGVjdGVkSXRlbSA9IHRoaXMubXlUYWJDb21wb25lbnQuc2VsZWN0ZWRUYWJJdGVtO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldCBzZWxlY3RlZFRhYkl0ZW0oKTogSWd4VGFiSXRlbUNvbXBvbmVudCB7XG4gICAgICAgIGlmICh0aGlzLnRhYnMgJiYgdGhpcy5zZWxlY3RlZEluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhYnMudG9BcnJheSgpW3RoaXMuc2VsZWN0ZWRJbmRleF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50OiBFbGVtZW50UmVmKSB7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIHRoaXMuc2V0U2VsZWN0ZWRHcm91cCgpO1xuICAgICAgICB0aGlzLl9ncm91cENoYW5nZXMkID0gdGhpcy5ncm91cHMuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZXNldFNlbGVjdGlvbk9uQ29sbGVjdGlvbkNoYW5nZWQoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2dyb3VwQ2hhbmdlcyQpIHtcbiAgICAgICAgICAgIHRoaXMuX2dyb3VwQ2hhbmdlcyQudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2V0U2VsZWN0ZWRHcm91cCgpOiB2b2lkIHtcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkSW5kZXggPD0gMCB8fCB0aGlzLnNlbGVjdGVkSW5kZXggPj0gdGhpcy5ncm91cHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgbm90aGluZyBpcyBzZWxlY3RlZCAtIHNlbGVjdCB0aGUgZmlyc3QgdGFicyBncm91cFxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0R3JvdXBCeUluZGV4KDApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEdyb3VwQnlJbmRleCh0aGlzLnNlbGVjdGVkSW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlc2V0U2VsZWN0aW9uT25Db2xsZWN0aW9uQ2hhbmdlZCgpOiB2b2lkIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5ncm91cHMudG9BcnJheSgpW3RoaXMuc2VsZWN0ZWRJbmRleF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIC8vIHBlcnNpc3QgdGhlIHNlbGVjdGVkIGluZGV4IGFuZCBhcHBsaWVkIGl0IHRvIHRoZSBuZXcgY29sbGVjdGlvblxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0R3JvdXBCeUluZGV4KHRoaXMuc2VsZWN0ZWRJbmRleCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkSW5kZXggPj0gdGhpcy5ncm91cHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGluIGNhc2UgdGhlIHNlbGVjdGVkIGluZGV4IGlzIG5vIGxvbmdlciB2YWxpZCwgc2VsZWN0IHRoZSBsYXN0IGdyb3VwIGluIHRoZSBuZXcgY29sbGVjdGlvblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEdyb3VwQnlJbmRleCh0aGlzLmdyb3Vwcy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIDApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2VsZWN0R3JvdXBCeUluZGV4KHNlbGVjdGVkSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBzZWxlY3RhYmxlR3JvdXBzID0gdGhpcy5ncm91cHMuZmlsdGVyKChzZWxlY3RhYmxlR3JvdXApID0+ICFzZWxlY3RhYmxlR3JvdXAuZGlzYWJsZWQpO1xuICAgICAgICBjb25zdCBncm91cCA9IHNlbGVjdGFibGVHcm91cHNbc2VsZWN0ZWRJbmRleF07XG5cbiAgICAgICAgaWYgKGdyb3VwKSB7XG4gICAgICAgICAgICBncm91cC5zZWxlY3QoMCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRlc2VsZWN0R3JvdXAoZ3JvdXA6IElneFRhYnNHcm91cENvbXBvbmVudCk6IHZvaWQge1xuICAgICAgICAvLyBDYW5ub3QgZGVzZWxlY3QgdGhlIHNlbGVjdGVkIHRhYiAtIHRoaXMgd2lsbCBtZWFuIHRoYXQgdGhlcmUgd2lsbCBiZSBub3Qgc2VsZWN0ZWQgdGFiIGxlZnRcbiAgICAgICAgaWYgKGdyb3VwLmRpc2FibGVkIHx8IHRoaXMuc2VsZWN0ZWRUYWJJdGVtLmluZGV4ID09PSBncm91cC5pbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZ3JvdXAuaXNTZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICBncm91cC5yZWxhdGVkVGFiLnRhYmluZGV4ID0gLTE7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzY3JvbGwoc2Nyb2xsUmlnaHQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGFic0FycmF5ID0gdGhpcy50YWJzLnRvQXJyYXkoKTtcbiAgICAgICAgZm9yIChjb25zdCB0YWIgb2YgdGFic0FycmF5KSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGFiLm5hdGl2ZVRhYkl0ZW0ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGlmIChzY3JvbGxSaWdodCkge1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50Lm9mZnNldFdpZHRoICsgZWxlbWVudC5vZmZzZXRMZWZ0ID4gdGhpcy52aWV3UG9ydC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoICsgdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50KGVsZW1lbnQsIHNjcm9sbFJpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5vZmZzZXRXaWR0aCArIGVsZW1lbnQub2Zmc2V0TGVmdCA+PSB0aGlzLm9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbEVsZW1lbnQoZWxlbWVudCwgc2Nyb2xsUmlnaHQpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5ATmdNb2R1bGUoe1xuICAgIGRlY2xhcmF0aW9uczogW0lneFRhYnNDb21wb25lbnQsXG4gICAgICAgIElneFRhYnNHcm91cENvbXBvbmVudCxcbiAgICAgICAgSWd4VGFiSXRlbUNvbXBvbmVudCxcbiAgICAgICAgSWd4VGFiSXRlbVRlbXBsYXRlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hSaWdodEJ1dHRvblN0eWxlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMZWZ0QnV0dG9uU3R5bGVEaXJlY3RpdmVdLFxuICAgIGV4cG9ydHM6IFtJZ3hUYWJzQ29tcG9uZW50LFxuICAgICAgICBJZ3hUYWJzR3JvdXBDb21wb25lbnQsXG4gICAgICAgIElneFRhYkl0ZW1Db21wb25lbnQsXG4gICAgICAgIElneFRhYkl0ZW1UZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4UmlnaHRCdXR0b25TdHlsZURpcmVjdGl2ZSxcbiAgICAgICAgSWd4TGVmdEJ1dHRvblN0eWxlRGlyZWN0aXZlXSxcbiAgICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBJZ3hCYWRnZU1vZHVsZSwgSWd4SWNvbk1vZHVsZSwgSWd4UmlwcGxlTW9kdWxlXVxufSlcblxuZXhwb3J0IGNsYXNzIElneFRhYnNNb2R1bGUge1xufVxuIl19