UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

149 lines 28.2 kB
import { PRODUCT_EXPERIENCE_CORE_SHARED } from '../shared/core.model'; import { Component, HostBinding, HostListener, Input } from '@angular/core'; import { filter, sortBy } from 'lodash-es'; import { Observable, Subject, of } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; import { GainsightService } from '../product-experience/gainsight.service'; import * as i0 from "@angular/core"; import * as i1 from "../product-experience/gainsight.service"; import * as i2 from "ngx-bootstrap/dropdown"; import * as i3 from "../common/icon.directive"; import * as i4 from "../common/outlet.directive"; import * as i5 from "../i18n/c8y-translate.directive"; import * as i6 from "@angular/common"; import * as i7 from "./action-bar-item.component"; import * as i8 from "../i18n/c8y-translate.pipe"; /** * This component is used as the outlet to show the action bars. * In a c8ycli app it is by default placed on the bootstrap component. */ export class ActionBarComponent { constructor(gainsightService) { this.gainsightService = gainsightService; /** * Identifies if the navigator is opened. If yes, the action-bar * needs to move to the right. */ this.navigatorOpen = false; /** * Identifies if the current view has tabs. If yes, the action bar needs * to move down. */ this.hasTabs = false; /** * Identifies if the current view has a header element. */ this.hasHeader = false; /** * Identifies if the tabs are aligned horizontally. If yes, the tabs don't * need to move to the left. */ this.isTabsHorizontal = false; /** * Identifies if in a mobile view the toolbar is expanded or not. */ this.isPageToolbarExpanded = false; /** * Adds the default `c8y-ui-action-bar` class. */ this.uiActionBar = true; /** * The current items to display in the ActionBar. */ this.items$ = of([]); /** * Provides observable for right action items. */ this.right$ = of([]); /** * Provides observable for left action items. */ this.left$ = of([]); /** * Provides observable for more action items. */ this.more$ = of([]); /** * Returns true if no items are present and hides the action bar. */ this.hidden$ = of(true); /** * Binds hidden property to this component's native element */ this.hidden = true; this.destroy$ = new Subject(); } mouseDown(event) { if (event.getAttribute('id') === 'page-toolbar') { return; } const element = event.closest('[px-event]') || event.closest('[title]') || event.closest('[uib-tooltip]'); if (!element || element.getAttribute('disabled')) { return; } const itemName = element.getAttribute('px-event') || element.getAttribute('title') || element.getAttribute('uib-tooltip'); const translatedItemName = this.gainsightService.translateToEnglish(itemName); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_CORE_SHARED.ACTION_BAR.EVENTS.ACTION_BAR_ITEM, { component: PRODUCT_EXPERIENCE_CORE_SHARED.ACTION_BAR.COMPONENTS.ACTION_BAR_COMPONENT, action: `${translatedItemName}`, url: location.href }); } ngOnInit() { this.right$ = this.items$.pipe(map(items => filter(items, { placement: 'right' })), map(items => sortBy(items, this.byPriority))); this.left$ = this.items$.pipe(map(items => filter(items, { placement: 'left' })), map(items => sortBy(items, this.byPriority))); this.more$ = this.items$.pipe(map(items => filter(items, { placement: 'more' })), map(items => sortBy(items, this.byPriority))); this.hidden$ = this.items$.pipe(map(items => { return !(items && items.length); })); this.hidden$.pipe(takeUntil(this.destroy$)).subscribe(hidden => { this.hidden = hidden; }); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } byPriority(item) { return -item.priority; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionBarComponent, deps: [{ token: i1.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ActionBarComponent, selector: "c8y-action-bar", inputs: { navigatorOpen: "navigatorOpen", hasTabs: "hasTabs", hasHeader: "hasHeader", isTabsHorizontal: "isTabsHorizontal", items$: "items$" }, host: { listeners: { "mousedown": "mouseDown($event.target)" }, properties: { "class.navigator-open": "this.navigatorOpen", "class.has-tabs": "this.hasTabs", "class.has-header": "this.hasHeader", "class.horizontal-tabs": "this.isTabsHorizontal", "class.c8y-ui-action-bar": "this.uiActionBar", "hidden": "this.hidden" }, classAttribute: "c8y-ui-action-bar" }, ngImport: i0, template: "<div\n class=\"navbar-header\"\n role=\"presentation\"\n>\n <p class=\"text-label-small p-l-16 p-t-8 p-b-8 visible-xs\">\n <span class=\"text-primary\">{{ 'Action bar' | translate }}</span>\n </p>\n</div>\n\n<div\n class=\"navbar-collapse\"\n id=\"page-toolbar\"\n role=\"complementary\"\n>\n <ul class=\"nav navbar-nav navbar-left gap-sm-8 p-l-sm-16 p-l-lg-0\">\n <ng-container *ngFor=\"let item of left$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </ul>\n <ul class=\"nav navbar-nav navbar-right gap-sm-8\">\n <ng-container *ngFor=\"let item of right$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n <li *ngIf=\"(more$ | async).length === 1; else moreWithMultipleOptions\">\n <ng-container *ngFor=\"let item of more$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </li>\n <ng-template #moreWithMultipleOptions>\n <li\n class=\"no-remove more-wrapper\"\n *ngIf=\"(more$ | async).length > 1\"\n >\n <div\n class=\"dropdown\"\n dropdown\n >\n <c8y-action-bar-item\n [placement]=\"'right'\"\n >\n <button\n class=\"dropdown-toggle c8y-dropdown d-flex\"\n title=\"{{ 'More\u2026' | translate }}\"\n aria-haspopup=\"true\"\n type=\"button\"\n dropdownToggle\n data-cy=\"action-bar--button-more\"\n >\n <span\n class=\"text-truncate\"\n translate\n >\n More\u2026\n </span>\n <i [c8yIcon]=\"'caret-down'\"></i>\n </button>\n <ul class=\"dropdown-menu visible-xs\">\n <ng-container *ngFor=\"let item of more$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </ul>\n <ul\n class=\"dropdown-menu dropdown-menu-right hidden-xs\"\n *dropdownMenu\n >\n <ng-container *ngFor=\"let item of more$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </ul>\n </c8y-action-bar-item>\n </div>\n </li>\n </ng-template>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: i2.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i2.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i2.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i4.OutletDirective, selector: "[c8yOutlet]", inputs: ["c8yOutlet", "c8yOutletProperties", "c8yOutletInjector"] }, { kind: "directive", type: i5.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i7.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "pipe", type: i8.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActionBarComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-action-bar', host: { class: 'c8y-ui-action-bar' }, template: "<div\n class=\"navbar-header\"\n role=\"presentation\"\n>\n <p class=\"text-label-small p-l-16 p-t-8 p-b-8 visible-xs\">\n <span class=\"text-primary\">{{ 'Action bar' | translate }}</span>\n </p>\n</div>\n\n<div\n class=\"navbar-collapse\"\n id=\"page-toolbar\"\n role=\"complementary\"\n>\n <ul class=\"nav navbar-nav navbar-left gap-sm-8 p-l-sm-16 p-l-lg-0\">\n <ng-container *ngFor=\"let item of left$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </ul>\n <ul class=\"nav navbar-nav navbar-right gap-sm-8\">\n <ng-container *ngFor=\"let item of right$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n <li *ngIf=\"(more$ | async).length === 1; else moreWithMultipleOptions\">\n <ng-container *ngFor=\"let item of more$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </li>\n <ng-template #moreWithMultipleOptions>\n <li\n class=\"no-remove more-wrapper\"\n *ngIf=\"(more$ | async).length > 1\"\n >\n <div\n class=\"dropdown\"\n dropdown\n >\n <c8y-action-bar-item\n [placement]=\"'right'\"\n >\n <button\n class=\"dropdown-toggle c8y-dropdown d-flex\"\n title=\"{{ 'More\u2026' | translate }}\"\n aria-haspopup=\"true\"\n type=\"button\"\n dropdownToggle\n data-cy=\"action-bar--button-more\"\n >\n <span\n class=\"text-truncate\"\n translate\n >\n More\u2026\n </span>\n <i [c8yIcon]=\"'caret-down'\"></i>\n </button>\n <ul class=\"dropdown-menu visible-xs\">\n <ng-container *ngFor=\"let item of more$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </ul>\n <ul\n class=\"dropdown-menu dropdown-menu-right hidden-xs\"\n *dropdownMenu\n >\n <ng-container *ngFor=\"let item of more$ | async\">\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: item.injector\"\n ></ng-container>\n </ng-container>\n </ul>\n </c8y-action-bar-item>\n </div>\n </li>\n </ng-template>\n </ul>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.GainsightService }], propDecorators: { navigatorOpen: [{ type: Input }, { type: HostBinding, args: ['class.navigator-open'] }], hasTabs: [{ type: Input }, { type: HostBinding, args: ['class.has-tabs'] }], hasHeader: [{ type: Input }, { type: HostBinding, args: ['class.has-header'] }], isTabsHorizontal: [{ type: Input }, { type: HostBinding, args: ['class.horizontal-tabs'] }], uiActionBar: [{ type: HostBinding, args: ['class.c8y-ui-action-bar'] }], items$: [{ type: Input }], hidden: [{ type: HostBinding }], mouseDown: [{ type: HostListener, args: ['mousedown', ['$event.target']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9jb3JlL2FjdGlvbi1iYXIvYWN0aW9uLWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9jb3JlL2FjdGlvbi1iYXIvYWN0aW9uLWJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUMvRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQzs7Ozs7Ozs7OztBQUczRTs7O0dBR0c7QUFNSCxNQUFNLE9BQU8sa0JBQWtCO0lBbUU3QixZQUFvQixnQkFBa0M7UUFBbEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQWxFdEQ7OztXQUdHO1FBQzJDLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBRXBFOzs7V0FHRztRQUNxQyxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBRXhEOztXQUVHO1FBQ3VDLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFNUQ7OztXQUdHO1FBQzRDLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUV4RTs7V0FFRztRQUNILDBCQUFxQixHQUFHLEtBQUssQ0FBQztRQUU5Qjs7V0FFRztRQUNxQyxnQkFBVyxHQUFHLElBQUksQ0FBQztRQUUzRDs7V0FFRztRQUNNLFdBQU0sR0FBZ0MsRUFBRSxD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QUFlLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQUk9EVUNUX0VYUEVSSUVOQ0VfQ09SRV9TSEFSRUQgfSBmcm9tICcuLi9zaGFyZWQvY29yZS5tb2RlbCc7XG5pbXBvcnQgeyBDb21wb25lbnQsIEhvc3RCaW5kaW5nLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZmlsdGVyLCBzb3J0QnkgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgR2FpbnNpZ2h0U2VydmljZSB9IGZyb20gJy4uL3Byb2R1Y3QtZXhwZXJpZW5jZS9nYWluc2lnaHQuc2VydmljZSc7XG5pbXBvcnQgeyBBY3Rpb25CYXJJdGVtIH0gZnJvbSAnLi9hY3Rpb24tYmFyLm1vZGVsJztcblxuLyoqXG4gKiBUaGlzIGNvbXBvbmVudCBpcyB1c2VkIGFzIHRoZSBvdXRsZXQgdG8gc2hvdyB0aGUgYWN0aW9uIGJhcnMuXG4gKiBJbiBhIGM4eWNsaSBhcHAgaXQgaXMgYnkgZGVmYXVsdCBwbGFjZWQgb24gdGhlIGJvb3RzdHJhcCBjb21wb25lbnQuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1hY3Rpb24tYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FjdGlvbi1iYXIuY29tcG9uZW50Lmh0bWwnLFxuICBob3N0OiB7IGNsYXNzOiAnYzh5LXVpLWFjdGlvbi1iYXInIH1cbn0pXG5leHBvcnQgY2xhc3MgQWN0aW9uQmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogSWRlbnRpZmllcyBpZiB0aGUgbmF2aWdhdG9yIGlzIG9wZW5lZC4gSWYgeWVzLCB0aGUgYWN0aW9uLWJhclxuICAgKiBuZWVkcyB0byBtb3ZlIHRvIHRoZSByaWdodC5cbiAgICovXG4gIEBJbnB1dCgpIEBIb3N0QmluZGluZygnY2xhc3MubmF2aWdhdG9yLW9wZW4nKSBuYXZpZ2F0b3JPcGVuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIElkZW50aWZpZXMgaWYgdGhlIGN1cnJlbnQgdmlldyBoYXMgdGFicy4gSWYgeWVzLCB0aGUgYWN0aW9uIGJhciBuZWVkc1xuICAgKiB0byBtb3ZlIGRvd24uXG4gICAqL1xuICBASW5wdXQoKSBASG9zdEJpbmRpbmcoJ2NsYXNzLmhhcy10YWJzJykgaGFzVGFicyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJZGVudGlmaWVzIGlmIHRoZSBjdXJyZW50IHZpZXcgaGFzIGEgaGVhZGVyIGVsZW1lbnQuXG4gICAqL1xuICBASW5wdXQoKSBASG9zdEJpbmRpbmcoJ2NsYXNzLmhhcy1oZWFkZXInKSBoYXNIZWFkZXIgPSBmYWxzZTtcblxuICAvKipcbiAgICogSWRlbnRpZmllcyBpZiB0aGUgdGFicyBhcmUgYWxpZ25lZCBob3Jpem9udGFsbHkuIElmIHllcywgdGhlIHRhYnMgZG9uJ3RcbiAgICogbmVlZCB0byBtb3ZlIHRvIHRoZSBsZWZ0LlxuICAgKi9cbiAgQElucHV0KCkgQEhvc3RCaW5kaW5nKCdjbGFzcy5ob3Jpem9udGFsLXRhYnMnKSBpc1RhYnNIb3Jpem9udGFsID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIElkZW50aWZpZXMgaWYgaW4gYSBtb2JpbGUgdmlldyB0aGUgdG9vbGJhciBpcyBleHBhbmRlZCBvciBub3QuXG4gICAqL1xuICBpc1BhZ2VUb29sYmFyRXhwYW5kZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogQWRkcyB0aGUgZGVmYXVsdCBgYzh5LXVpLWFjdGlvbi1iYXJgIGNsYXNzLlxuICAgKi9cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5jOHktdWktYWN0aW9uLWJhcicpIHVpQWN0aW9uQmFyID0gdHJ1ZTtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgaXRlbXMgdG8gZGlzcGxheSBpbiB0aGUgQWN0aW9uQmFyLlxuICAgKi9cbiAgQElucHV0KCkgaXRlbXMkOiBPYnNlcnZhYmxlPEFjdGlvbkJhckl0ZW1bXT4gPSBvZihbXSk7XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIG9ic2VydmFibGUgZm9yIHJpZ2h0IGFjdGlvbiBpdGVtcy5cbiAgICovXG4gIHJpZ2h0JDogT2JzZXJ2YWJsZTxBY3Rpb25CYXJJdGVtW10+ID0gb2YoW10pO1xuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBvYnNlcnZhYmxlIGZvciBsZWZ0IGFjdGlvbiBpdGVtcy5cbiAgICovXG4gIGxlZnQkOiBPYnNlcnZhYmxlPEFjdGlvbkJhckl0ZW1bXT4gPSBvZihbXSk7XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIG9ic2VydmFibGUgZm9yIG1vcmUgYWN0aW9uIGl0ZW1zLlxuICAgKi9cbiAgbW9yZSQ6IE9ic2VydmFibGU8QWN0aW9uQmFySXRlbVtdPiA9IG9mKFtdKTtcblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIG5vIGl0ZW1zIGFyZSBwcmVzZW50IGFuZCBoaWRlcyB0aGUgYWN0aW9uIGJhci5cbiAgICovXG4gIGhpZGRlbiQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSBvZih0cnVlKTtcblxuICAvKipcbiAgICogQmluZHMgaGlkZGVuIHByb3BlcnR5IHRvIHRoaXMgY29tcG9uZW50J3MgbmF0aXZlIGVsZW1lbnRcbiAgICovXG4gIEBIb3N0QmluZGluZygpXG4gIGhpZGRlbiA9IHRydWU7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JDogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBnYWluc2lnaHRTZXJ2aWNlOiBHYWluc2lnaHRTZXJ2aWNlKSB7fVxuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlZG93bicsIFsnJGV2ZW50LnRhcmdldCddKVxuICBtb3VzZURvd24oZXZlbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgaWYgKGV2ZW50LmdldEF0dHJpYnV0ZSgnaWQnKSA9PT0gJ3BhZ2UtdG9vbGJhcicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZWxlbWVudCA9XG4gICAgICBldmVudC5jbG9zZXN0KCdbcHgtZXZlbnRdJykgfHwgZXZlbnQuY2xvc2VzdCgnW3RpdGxlXScpIHx8IGV2ZW50LmNsb3Nlc3QoJ1t1aWItdG9vbHRpcF0nKTtcbiAgICBpZiAoIWVsZW1lbnQgfHwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpdGVtTmFtZSA9XG4gICAgICBlbGVtZW50LmdldEF0dHJpYnV0ZSgncHgtZXZlbnQnKSB8fFxuICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3RpdGxlJykgfHxcbiAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd1aWItdG9vbHRpcCcpO1xuICAgIGNvbnN0IHRyYW5zbGF0ZWRJdGVtTmFtZSA9IHRoaXMuZ2FpbnNpZ2h0U2VydmljZS50cmFuc2xhdGVUb0VuZ2xpc2goaXRlbU5hbWUpO1xuXG4gICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyaWdnZXJFdmVudChcbiAgICAgIFBST0RVQ1RfRVhQRVJJRU5DRV9DT1JFX1NIQVJFRC5BQ1RJT05fQkFSLkVWRU5UUy5BQ1RJT05fQkFSX0lURU0sXG4gICAgICB7XG4gICAgICAgIGNvbXBvbmVudDogUFJPRFVDVF9FWFBFUklFTkNFX0NPUkVfU0hBUkVELkFDVElPTl9CQVIuQ09NUE9ORU5UUy5BQ1RJT05fQkFSX0NPTVBPTkVOVCxcbiAgICAgICAgYWN0aW9uOiBgJHt0cmFuc2xhdGVkSXRlbU5hbWV9YCxcbiAgICAgICAgdXJsOiBsb2NhdGlvbi5ocmVmXG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMucmlnaHQkID0gdGhpcy5pdGVtcyQucGlwZShcbiAgICAgIG1hcChpdGVtcyA9PiBmaWx0ZXIoaXRlbXMsIHsgcGxhY2VtZW50OiAncmlnaHQnIH0pKSxcbiAgICAgIG1hcChpdGVtcyA9PiBzb3J0QnkoaXRlbXMsIHRoaXMuYnlQcmlvcml0eSkpXG4gICAgKTtcblxuICAgIHRoaXMubGVmdCQgPSB0aGlzLml0ZW1zJC5waXBlKFxuICAgICAgbWFwKGl0ZW1zID0+IGZpbHRlcihpdGVtcywgeyBwbGFjZW1lbnQ6ICdsZWZ0JyB9KSksXG4gICAgICBtYXAoaXRlbXMgPT4gc29ydEJ5KGl0ZW1zLCB0aGlzLmJ5UHJpb3JpdHkpKVxuICAgICk7XG5cbiAgICB0aGlzLm1vcmUkID0gdGhpcy5pdGVtcyQucGlwZShcbiAgICAgIG1hcChpdGVtcyA9PiBmaWx0ZXIoaXRlbXMsIHsgcGxhY2VtZW50OiAnbW9yZScgfSkpLFxuICAgICAgbWFwKGl0ZW1zID0+IHNvcnRCeShpdGVtcywgdGhpcy5ieVByaW9yaXR5KSlcbiAgICApO1xuXG4gICAgdGhpcy5oaWRkZW4kID0gdGhpcy5pdGVtcyQucGlwZShcbiAgICAgIG1hcChpdGVtcyA9PiB7XG4gICAgICAgIHJldHVybiAhKGl0ZW1zICYmIGl0ZW1zLmxlbmd0aCk7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLmhpZGRlbiQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZShoaWRkZW4gPT4ge1xuICAgICAgdGhpcy5oaWRkZW4gPSBoaWRkZW47XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBwcml2YXRlIGJ5UHJpb3JpdHkoaXRlbSkge1xuICAgIHJldHVybiAtaXRlbS5wcmlvcml0eTtcbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cIm5hdmJhci1oZWFkZXJcIlxuICByb2xlPVwicHJlc2VudGF0aW9uXCJcbj5cbiAgPHAgY2xhc3M9XCJ0ZXh0LWxhYmVsLXNtYWxsIHAtbC0xNiBwLXQtOCBwLWItOCB2aXNpYmxlLXhzXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXByaW1hcnlcIj57eyAnQWN0aW9uIGJhcicgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gIDwvcD5cbjwvZGl2PlxuXG48ZGl2XG4gIGNsYXNzPVwibmF2YmFyLWNvbGxhcHNlXCJcbiAgaWQ9XCJwYWdlLXRvb2xiYXJcIlxuICByb2xlPVwiY29tcGxlbWVudGFyeVwiXG4+XG4gIDx1bCBjbGFzcz1cIm5hdiBuYXZiYXItbmF2IG5hdmJhci1sZWZ0IGdhcC1zbS04IHAtbC1zbS0xNiBwLWwtbGctMFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbGVmdCQgfCBhc3luY1wiPlxuICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAqYzh5T3V0bGV0PVwiaXRlbS5jb21wb25lbnQgfHwgaXRlbS50ZW1wbGF0ZTsgaW5qZWN0b3I6IGl0ZW0uaW5qZWN0b3JcIlxuICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3VsPlxuICA8dWwgY2xhc3M9XCJuYXYgbmF2YmFyLW5hdiBuYXZiYXItcmlnaHQgZ2FwLXNtLThcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJpZ2h0JCB8IGFzeW5jXCI+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpjOHlPdXRsZXQ9XCJpdGVtLmNvbXBvbmVudCB8fCBpdGVtLnRlbXBsYXRlOyBpbmplY3RvcjogaXRlbS5pbmplY3RvclwiXG4gICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGxpICpuZ0lmPVwiKG1vcmUkIHwgYXN5bmMpLmxlbmd0aCA9PT0gMTsgZWxzZSBtb3JlV2l0aE11bHRpcGxlT3B0aW9uc1wiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBtb3JlJCB8IGFzeW5jXCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqYzh5T3V0bGV0PVwiaXRlbS5jb21wb25lbnQgfHwgaXRlbS50ZW1wbGF0ZTsgaW5qZWN0b3I6IGl0ZW0uaW5qZWN0b3JcIlxuICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2xpPlxuICAgIDxuZy10ZW1wbGF0ZSAjbW9yZVdpdGhNdWx0aXBsZU9wdGlvbnM+XG4gICAgICA8bGlcbiAgICAgICAgY2xhc3M9XCJuby1yZW1vdmUgbW9yZS13cmFwcGVyXCJcbiAgICAgICAgKm5nSWY9XCIobW9yZSQgfCBhc3luYykubGVuZ3RoID4gMVwiXG4gICAgICA+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImRyb3Bkb3duXCJcbiAgICAgICAgICBkcm9wZG93blxuICAgICAgICA+XG4gICAgICAgICAgPGM4eS1hY3Rpb24tYmFyLWl0ZW1cbiAgICAgICAgICAgIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBjbGFzcz1cImRyb3Bkb3duLXRvZ2dsZSBjOHktZHJvcGRvd24gZC1mbGV4XCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyAnTW9yZeKApicgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICBhcmlhLWhhc3BvcHVwPVwidHJ1ZVwiXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBkcm9wZG93blRvZ2dsZVxuICAgICAgICAgICAgICBkYXRhLWN5PVwiYWN0aW9uLWJhci0tYnV0dG9uLW1vcmVcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBNb3Jl4oCmXG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGkgW2M4eUljb25dPVwiJ2NhcmV0LWRvd24nXCI+PC9pPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJkcm9wZG93bi1tZW51IHZpc2libGUteHNcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBtb3JlJCB8IGFzeW5jXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgKmM4eU91dGxldD1cIml0ZW0uY29tcG9uZW50IHx8IGl0ZW0udGVtcGxhdGU7IGluamVjdG9yOiBpdGVtLmluamVjdG9yXCJcbiAgICAgICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDx1bFxuICAgICAgICAgICAgICBjbGFzcz1cImRyb3Bkb3duLW1lbnUgZHJvcGRvd24tbWVudS1yaWdodCBoaWRkZW4teHNcIlxuICAgICAgICAgICAgICAqZHJvcGRvd25NZW51XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbW9yZSQgfCBhc3luY1wiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICpjOHlPdXRsZXQ9XCJpdGVtLmNvbXBvbmVudCB8fCBpdGVtLnRlbXBsYXRlOyBpbmplY3RvcjogaXRlbS5pbmplY3RvclwiXG4gICAgICAgICAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9jOHktYWN0aW9uLWJhci1pdGVtPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbGk+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC91bD5cbjwvZGl2PlxuIl19