UNPKG

gentics-ui-core

Version:

This is the common core framework for the Gentics CMS and Mesh UI, and other Angular applications.

173 lines 21.7 kB
import { Component, ContentChildren, QueryList, Input, Output, EventEmitter } from '@angular/core'; import { Tab } from './tab.component'; import { coerceToBoolean } from '../../common/coerce-to-boolean'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/router"; import * as i3 from "../icon/icon.directive"; /** * Tabs can be either pure or stateful. Stateful tabs will keep track of which one is active by keeping an internal * state. * * Pure tabs will only change the active tab when the `activeId` property is updated. * * ## Stateful Tabs * ```html * <gtx-tabs (tabChange)="goToTab($event)"> * <gtx-tab title="Details">Optional content here.</gtx-tab> * <gtx-tab title="Orders"></gtx-tab> * <gtx-tab title="Notes"></gtx-tab> * </gtx-tabs> * ``` * * ## Pure Tabs * ```html * <gtx-tabs pure [activeId]="activeTab"> * <gtx-tab title="Details" id="1" (select)="activeTab = $event"></gtx-tab> * <gtx-tab title="Orders" id="2" (select)="activeTab = $event"></gtx-tab> * <gtx-tab title="Notes" id="3" (select)="activeTab = $event"></gtx-tab> * </gtx-tabs> * ``` * * ## With `routerLink` * A gtx-tab can take an optional `[routerLink]` binding which will set router links for the tabs. * ```html * <gtx-tabs pure [activeId]="activeTab"> * <gtx-tab title="Details" id="1" [routerLink]="['customer', 'details']"></gtx-tab> * <gtx-tab title="Orders" id="2" [routerLink]="['customer', 'orders']"></gtx-tab> * <gtx-tab title="Notes" id="3" [routerLink]="['customer', 'notes']"></gtx-tab> * </gtx-tabs> * ``` * * ##### Vertical Tabs * A gtx-tabs can take an optional `vertical` property which allows to display tabs vertically. * ```html * <gtx-tabs vertical> * <gtx-tab title="Details"></gtx-tab> * <gtx-tab title="Orders"></gtx-tab> * <gtx-tab title="Notes"></gtx-tab> * </gtx-tabs> * ``` * * * ##### Active Tabs with Icons * A gtx-tabs can take an optional `hideTitle` property which allows to hide the title for non-active tabs with icons. * ```html * <gtx-tabs hideTitle> * <gtx-tab icon="folder" title="Tab 1">Tab 1 Content</gtx-tab> * <gtx-tab icon="cloud" title="Tab 2">Tab 2 Content</gtx-tab> * </gtx-tabs> * ``` * */ export class Tabs { constructor() { /** * Fires an event whenever the active tab changes. Argument is the id of the selected tab. */ this.tabChange = new EventEmitter(); this.shouldHideTitle = false; this.verticalTabs = false; this.tabsShouldWrap = false; this.isPure = false; } /** * When present (or set to true), tabs are displayed vertically. */ set vertical(val) { this.verticalTabs = coerceToBoolean(val); } /** * When present (or set to true), only active tabs with icons will show the title. * Non-active tabs with icons will hide the title, show only icon. */ set hideTitle(val) { this.shouldHideTitle = coerceToBoolean(val); } /** * When present, sets the tabs to pure (stateless) mode. */ set pure(val) { this.isPure = val != null; } /** * When present (or set to true), tabs which do not fit into the width of their container will wrap onto * a new line. Otherwise, tabs will remain on one line and the contents will be elided if all the available * space is filled. */ set wrap(val) { this.tabsShouldWrap = coerceToBoolean(val); } ngAfterContentInit() { if (this.isPure) { this.tabsChangeSubscription = this.tabs.changes.subscribe(() => { setTimeout(() => this.setActiveTab()); }); } else { let activeTabs = this.tabs.filter(tab => tab.active); // if there is no active tab set, activate the first if (activeTabs.length === 0) { this.tabs.first.active = true; } } this.tabs.notifyOnChanges(); } ngOnChanges(changes) { this.setActiveTab(); } ngOnDestroy() { if (this.tabsChangeSubscription) { this.tabsChangeSubscription.unsubscribe(); } } /** * Sets the tab with id === this.activeId to active. */ setActiveTab() { if (this.tabs) { let tabToActivate = this.tabs.filter(t => t.id === this.activeId)[0]; if (tabToActivate) { this.setAsActive(tabToActivate); } } } /** * Invoked when a tab link is clicked. */ selectTab(tab) { if (tab.disabled) { return; } if (!this.isPure) { this.setAsActive(tab); this.tabChange.emit(tab.id); } else { tab.select.emit(tab.id); } } setAsActive(tab) { this.tabs.toArray().forEach(tab => tab.active = false); tab.active = true; } } /** @nocollapse */ Tabs.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: Tabs, deps: [], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ Tabs.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: Tabs, selector: "gtx-tabs", inputs: { vertical: "vertical", hideTitle: "hideTitle", activeId: "activeId", pure: "pure", wrap: "wrap" }, outputs: { tabChange: "tabChange" }, queries: [{ propertyName: "tabs", predicate: Tab }], usesOnChanges: true, ngImport: i0, template: "<ul class=\"tab-links\" [class.vertical]=\"verticalTabs\" [class.wrap]=\"tabsShouldWrap\">\n <li class=\"tab-link\" role=\"presentation\"\n *ngFor=\"let tab of tabs\"\n [title]=\"tab.title\"\n (click)=\"selectTab(tab)\"\n [ngClass]=\"{\n disabled: tab.disabled,\n 'is-active': tab.active,\n 'has-icon': !!tab.icon,\n 'icon-only': shouldHideTitle && !tab.active || (tab.icon && !tab.title)\n }\">\n <a role=\"tab\" *ngIf=\"tab.routerLink && !tab.disabled\" [routerLink]=\"tab.routerLink\">\n <icon *ngIf=\"tab.icon\">{{tab.icon}}</icon><span [class.animatedTitle]=\"shouldHideTitle\" *ngIf=\"!shouldHideTitle || tab.active || (!tab.active && !tab.icon)\">{{ tab.title }}</span></a>\n <a role=\"tab\" *ngIf=\"!tab.routerLink || tab.disabled\">\n <icon *ngIf=\"tab.icon\">{{tab.icon}}</icon><span [class.animatedTitle]=\"shouldHideTitle\" *ngIf=\"!shouldHideTitle || tab.active || (!tab.active && !tab.icon)\">{{ tab.title }}</span></a>\n </li>\n</ul>\n<ng-content></ng-content>\n", directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i3.Icon, selector: "icon" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: Tabs, decorators: [{ type: Component, args: [{ selector: 'gtx-tabs', template: "<ul class=\"tab-links\" [class.vertical]=\"verticalTabs\" [class.wrap]=\"tabsShouldWrap\">\n <li class=\"tab-link\" role=\"presentation\"\n *ngFor=\"let tab of tabs\"\n [title]=\"tab.title\"\n (click)=\"selectTab(tab)\"\n [ngClass]=\"{\n disabled: tab.disabled,\n 'is-active': tab.active,\n 'has-icon': !!tab.icon,\n 'icon-only': shouldHideTitle && !tab.active || (tab.icon && !tab.title)\n }\">\n <a role=\"tab\" *ngIf=\"tab.routerLink && !tab.disabled\" [routerLink]=\"tab.routerLink\">\n <icon *ngIf=\"tab.icon\">{{tab.icon}}</icon><span [class.animatedTitle]=\"shouldHideTitle\" *ngIf=\"!shouldHideTitle || tab.active || (!tab.active && !tab.icon)\">{{ tab.title }}</span></a>\n <a role=\"tab\" *ngIf=\"!tab.routerLink || tab.disabled\">\n <icon *ngIf=\"tab.icon\">{{tab.icon}}</icon><span [class.animatedTitle]=\"shouldHideTitle\" *ngIf=\"!shouldHideTitle || tab.active || (!tab.active && !tab.icon)\">{{ tab.title }}</span></a>\n </li>\n</ul>\n<ng-content></ng-content>\n" }] }], propDecorators: { tabs: [{ type: ContentChildren, args: [Tab] }], tabChange: [{ type: Output }], vertical: [{ type: Input }], hideTitle: [{ type: Input }], activeId: [{ type: Input }], pure: [{ type: Input }], wrap: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy90YWJzL3RhYnMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdGFicy90YWJzLnRwbC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBb0IsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQXNDLE1BQU0sZUFBZSxDQUFDO0FBQ3hKLE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUNwQyxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sZ0NBQWdDLENBQUM7Ozs7O0FBRy9EOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtREc7QUFLSCxNQUFNLE9BQU8sSUFBSTtJQUpqQjtRQVFJOztXQUVHO1FBQ08sY0FBUyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFzQ2pELG9CQUFlLEdBQVksS0FBSyxDQUFDO1FBQ2pDLGlCQUFZLEdBQVksS0FBSyxDQUFDO1FBQzlCLG1CQUFjLEdBQVksS0FBSyxDQUFDO1FBQ3hCLFdBQU0sR0FBWSxLQUFLLENBQUM7S0E4RG5DO0lBckdHOztPQUVHO0lBQ0gsSUFBYSxRQUFRLENBQUMsR0FBUTtRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBYSxTQUFTLENBQUMsR0FBUTtRQUMzQixJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBT0Q7O09BRUc7SUFDSCxJQUFhLElBQUksQ0FBQyxHQUFRO1FBQ3RCLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxJQUFJLElB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ZW50Q2hpbGRyZW4sIFF1ZXJ5TGlzdCwgQWZ0ZXJDb250ZW50SW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBTaW1wbGVDaGFuZ2VzLCBPbkNoYW5nZXMsIE9uRGVzdHJveX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1RhYn0gZnJvbSAnLi90YWIuY29tcG9uZW50JztcbmltcG9ydCB7Y29lcmNlVG9Cb29sZWFufSBmcm9tICcuLi8uLi9jb21tb24vY29lcmNlLXRvLWJvb2xlYW4nO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbi8qKlxuICogVGFicyBjYW4gYmUgZWl0aGVyIHB1cmUgb3Igc3RhdGVmdWwuIFN0YXRlZnVsIHRhYnMgd2lsbCBrZWVwIHRyYWNrIG9mIHdoaWNoIG9uZSBpcyBhY3RpdmUgYnkga2VlcGluZyBhbiBpbnRlcm5hbFxuICogc3RhdGUuXG4gKlxuICogUHVyZSB0YWJzIHdpbGwgb25seSBjaGFuZ2UgdGhlIGFjdGl2ZSB0YWIgd2hlbiB0aGUgYGFjdGl2ZUlkYCBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICpcbiAqICMjIFN0YXRlZnVsIFRhYnNcbiAqIGBgYGh0bWxcbiAqIDxndHgtdGFicyAodGFiQ2hhbmdlKT1cImdvVG9UYWIoJGV2ZW50KVwiPlxuICogICAgIDxndHgtdGFiIHRpdGxlPVwiRGV0YWlsc1wiPk9wdGlvbmFsIGNvbnRlbnQgaGVyZS48L2d0eC10YWI+XG4gKiAgICAgPGd0eC10YWIgdGl0bGU9XCJPcmRlcnNcIj48L2d0eC10YWI+XG4gKiAgICAgPGd0eC10YWIgdGl0bGU9XCJOb3Rlc1wiPjwvZ3R4LXRhYj5cbiAqIDwvZ3R4LXRhYnM+XG4gKiBgYGBcbiAqXG4gKiAjIyBQdXJlIFRhYnNcbiAqIGBgYGh0bWxcbiAqIDxndHgtdGFicyBwdXJlIFthY3RpdmVJZF09XCJhY3RpdmVUYWJcIj5cbiAqICAgICA8Z3R4LXRhYiB0aXRsZT1cIkRldGFpbHNcIiBpZD1cIjFcIiAoc2VsZWN0KT1cImFjdGl2ZVRhYiA9ICRldmVudFwiPjwvZ3R4LXRhYj5cbiAqICAgICA8Z3R4LXRhYiB0aXRsZT1cIk9yZGVyc1wiIGlkPVwiMlwiIChzZWxlY3QpPVwiYWN0aXZlVGFiID0gJGV2ZW50XCI+PC9ndHgtdGFiPlxuICogICAgIDxndHgtdGFiIHRpdGxlPVwiTm90ZXNcIiBpZD1cIjNcIiAoc2VsZWN0KT1cImFjdGl2ZVRhYiA9ICRldmVudFwiPjwvZ3R4LXRhYj5cbiAqIDwvZ3R4LXRhYnM+XG4gKiBgYGBcbiAqXG4gKiAjIyBXaXRoIGByb3V0ZXJMaW5rYFxuICogQSBndHgtdGFiIGNhbiB0YWtlIGFuIG9wdGlvbmFsIGBbcm91dGVyTGlua11gIGJpbmRpbmcgd2hpY2ggd2lsbCBzZXQgcm91dGVyIGxpbmtzIGZvciB0aGUgdGFicy5cbiAqIGBgYGh0bWxcbiAqIDxndHgtdGFicyBwdXJlIFthY3RpdmVJZF09XCJhY3RpdmVUYWJcIj5cbiAqICAgICA8Z3R4LXRhYiB0aXRsZT1cIkRldGFpbHNcIiBpZD1cIjFcIiBbcm91dGVyTGlua109XCJbJ2N1c3RvbWVyJywgJ2RldGFpbHMnXVwiPjwvZ3R4LXRhYj5cbiAqICAgICA8Z3R4LXRhYiB0aXRsZT1cIk9yZGVyc1wiIGlkPVwiMlwiIFtyb3V0ZXJMaW5rXT1cIlsnY3VzdG9tZXInLCAnb3JkZXJzJ11cIj48L2d0eC10YWI+XG4gKiAgICAgPGd0eC10YWIgdGl0bGU9XCJOb3Rlc1wiIGlkPVwiM1wiIFtyb3V0ZXJMaW5rXT1cIlsnY3VzdG9tZXInLCAnbm90ZXMnXVwiPjwvZ3R4LXRhYj5cbiAqIDwvZ3R4LXRhYnM+XG4gKiBgYGBcbiAqICAqICMjIyMjIFZlcnRpY2FsIFRhYnNcbiAqIEEgZ3R4LXRhYnMgY2FuIHRha2UgYW4gb3B0aW9uYWwgYHZlcnRpY2FsYCBwcm9wZXJ0eSB3aGljaCBhbGxvd3MgdG8gZGlzcGxheSB0YWJzIHZlcnRpY2FsbHkuXG4gKiBgYGBodG1sXG4gKiA8Z3R4LXRhYnMgdmVydGljYWw+XG4gKiAgICAgICAgPGd0eC10YWIgdGl0bGU9XCJEZXRhaWxzXCI+PC9ndHgtdGFiPlxuICogICAgICAgIDxndHgtdGFiIHRpdGxlPVwiT3JkZXJzXCI+PC9ndHgtdGFiPlxuICogICAgICAgIDxndHgtdGFiIHRpdGxlPVwiTm90ZXNcIj48L2d0eC10YWI+XG4gKiA8L2d0eC10YWJzPlxuICogYGBgXG4gKiAgKiAgKiAjIyMjIyBBY3RpdmUgVGFicyB3aXRoIEljb25zXG4gKiBBIGd0eC10YWJzIGNhbiB0YWtlIGFuIG9wdGlvbmFsIGBoaWRlVGl0bGVgIHByb3BlcnR5IHdoaWNoIGFsbG93cyB0byBoaWRlIHRoZSB0aXRsZSBmb3Igbm9uLWFjdGl2ZSB0YWJzIHdpdGggaWNvbnMuXG4gKiBgYGBodG1sXG4gKiA8Z3R4LXRhYnMgaGlkZVRpdGxlPlxuICogICAgICAgICAgIDxndHgtdGFiIGljb249XCJmb2xkZXJcIiB0aXRsZT1cIlRhYiAxXCI+VGFiIDEgQ29udGVudDwvZ3R4LXRhYj5cbiAqICAgICAgICAgICA8Z3R4LXRhYiBpY29uPVwiY2xvdWRcIiB0aXRsZT1cIlRhYiAyXCI+VGFiIDIgQ29udGVudDwvZ3R4LXRhYj5cbiAqIDwvZ3R4LXRhYnM+XG4gKiBgYGBcbiAqXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZ3R4LXRhYnMnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi90YWJzLnRwbC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBUYWJzIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXG4gICAgQENvbnRlbnRDaGlsZHJlbihUYWIpIHRhYnM6IFF1ZXJ5TGlzdDxUYWI+O1xuXG4gICAgLyoqXG4gICAgICogRmlyZXMgYW4gZXZlbnQgd2hlbmV2ZXIgdGhlIGFjdGl2ZSB0YWIgY2hhbmdlcy4gQXJndW1lbnQgaXMgdGhlIGlkIG9mIHRoZSBzZWxlY3RlZCB0YWIuXG4gICAgICovXG4gICAgQE91dHB1dCgpIHRhYkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICAgLyoqXG4gICAgICogV2hlbiBwcmVzZW50IChvciBzZXQgdG8gdHJ1ZSksIHRhYnMgYXJlIGRpc3BsYXllZCB2ZXJ0aWNhbGx5LlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHNldCB2ZXJ0aWNhbCh2YWw6IGFueSkge1xuICAgICAgICB0aGlzLnZlcnRpY2FsVGFicyA9IGNvZXJjZVRvQm9vbGVhbih2YWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZW4gcHJlc2VudCAob3Igc2V0IHRvIHRydWUpLCBvbmx5IGFjdGl2ZSB0YWJzIHdpdGggaWNvbnMgd2lsbCBzaG93IHRoZSB0aXRsZS5cbiAgICAgKiBOb24tYWN0aXZlIHRhYnMgd2l0aCBpY29ucyB3aWxsIGhpZGUgdGhlIHRpdGxlLCBzaG93IG9ubHkgaWNvbi5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBzZXQgaGlkZVRpdGxlKHZhbDogYW55KSB7XG4gICAgICAgIHRoaXMuc2hvdWxkSGlkZVRpdGxlID0gY29lcmNlVG9Cb29sZWFuKHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGlkIG9mIHRoZSBhY3RpdmUgdGFiLiBTaG91bGQgb25seSBiZSB1c2VkIGluIHB1cmUgKHN0YXRlbGVzcykgbW9kZS5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBhY3RpdmVJZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogV2hlbiBwcmVzZW50LCBzZXRzIHRoZSB0YWJzIHRvIHB1cmUgKHN0YXRlbGVzcykgbW9kZS5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBzZXQgcHVyZSh2YWw6IGFueSkge1xuICAgICAgICB0aGlzLmlzUHVyZSA9IHZhbCAhPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZW4gcHJlc2VudCAob3Igc2V0IHRvIHRydWUpLCB0YWJzIHdoaWNoIGRvIG5vdCBmaXQgaW50byB0aGUgd2lkdGggb2YgdGhlaXIgY29udGFpbmVyIHdpbGwgd3JhcCBvbnRvXG4gICAgICogYSBuZXcgbGluZS4gT3RoZXJ3aXNlLCB0YWJzIHdpbGwgcmVtYWluIG9uIG9uZSBsaW5lIGFuZCB0aGUgY29udGVudHMgd2lsbCBiZSBlbGlkZWQgaWYgYWxsIHRoZSBhdmFpbGFibGVcbiAgICAgKiBzcGFjZSBpcyBmaWxsZWQuXG4gICAgICovXG4gICAgQElucHV0KCkgc2V0IHdyYXAodmFsOiBhbnkpIHtcbiAgICAgICAgdGhpcy50YWJzU2hvdWxkV3JhcCA9IGNvZXJjZVRvQm9vbGVhbih2YWwpO1xuICAgIH1cblxuICAgIHNob3VsZEhpZGVUaXRsZTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHZlcnRpY2FsVGFiczogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHRhYnNTaG91bGRXcmFwOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBpc1B1cmU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIHRhYnNDaGFuZ2VTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICAgIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaXNQdXJlKSB7XG4gICAgICAgICAgICB0aGlzLnRhYnNDaGFuZ2VTdWJzY3JpcHRpb24gPSB0aGlzLnRhYnMuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXRBY3RpdmVUYWIoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBhY3RpdmVUYWJzID0gdGhpcy50YWJzLmZpbHRlcih0YWIgPT4gdGFiLmFjdGl2ZSk7XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGFjdGl2ZSB0YWIgc2V0LCBhY3RpdmF0ZSB0aGUgZmlyc3RcbiAgICAgICAgICAgIGlmIChhY3RpdmVUYWJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMudGFicy5maXJzdC5hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudGFicy5ub3RpZnlPbkNoYW5nZXMoKTtcbiAgICB9XG5cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0QWN0aXZlVGFiKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnRhYnNDaGFuZ2VTdWJzY3JpcHRpb24pIHtcbiAgICAgICAgICAgIHRoaXMudGFic0NoYW5nZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgdGFiIHdpdGggaWQgPT09IHRoaXMuYWN0aXZlSWQgdG8gYWN0aXZlLlxuICAgICAqL1xuICAgIHNldEFjdGl2ZVRhYigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMudGFicykge1xuICAgICAgICAgICAgbGV0IHRhYlRvQWN0aXZhdGUgPSB0aGlzLnRhYnMuZmlsdGVyKHQgPT4gdC5pZCA9PT0gdGhpcy5hY3RpdmVJZClbMF07XG4gICAgICAgICAgICBpZiAodGFiVG9BY3RpdmF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0QXNBY3RpdmUodGFiVG9BY3RpdmF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIHdoZW4gYSB0YWIgbGluayBpcyBjbGlja2VkLlxuICAgICAqL1xuICAgIHNlbGVjdFRhYih0YWI6IFRhYik6IHZvaWQge1xuICAgICAgICBpZiAodGFiLmRpc2FibGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLmlzUHVyZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRBc0FjdGl2ZSh0YWIpO1xuICAgICAgICAgICAgdGhpcy50YWJDaGFuZ2UuZW1pdCh0YWIuaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGFiLnNlbGVjdC5lbWl0KHRhYi5pZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEFzQWN0aXZlKHRhYjogVGFiKTogdm9pZCB7XG4gICAgICAgIHRoaXMudGFicy50b0FycmF5KCkuZm9yRWFjaCh0YWIgPT4gdGFiLmFjdGl2ZSA9IGZhbHNlKTtcbiAgICAgICAgdGFiLmFjdGl2ZSA9IHRydWU7XG4gICAgfVxuXG59XG4iLCI8dWwgY2xhc3M9XCJ0YWItbGlua3NcIiBbY2xhc3MudmVydGljYWxdPVwidmVydGljYWxUYWJzXCIgW2NsYXNzLndyYXBdPVwidGFic1Nob3VsZFdyYXBcIj5cbiAgICA8bGkgY2xhc3M9XCJ0YWItbGlua1wiIHJvbGU9XCJwcmVzZW50YXRpb25cIlxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IHRhYiBvZiB0YWJzXCJcbiAgICAgICAgICAgIFt0aXRsZV09XCJ0YWIudGl0bGVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFRhYih0YWIpXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICBkaXNhYmxlZDogdGFiLmRpc2FibGVkLFxuICAgICAgICAgICAgICAgICdpcy1hY3RpdmUnOiB0YWIuYWN0aXZlLFxuICAgICAgICAgICAgICAgICdoYXMtaWNvbic6ICEhdGFiLmljb24sXG4gICAgICAgICAgICAgICAgJ2ljb24tb25seSc6IHNob3VsZEhpZGVUaXRsZSAmJiAhdGFiLmFjdGl2ZSB8fCAodGFiLmljb24gJiYgIXRhYi50aXRsZSlcbiAgICAgICAgICAgIH1cIj5cbiAgICAgICAgPGEgcm9sZT1cInRhYlwiICpuZ0lmPVwidGFiLnJvdXRlckxpbmsgJiYgIXRhYi5kaXNhYmxlZFwiIFtyb3V0ZXJMaW5rXT1cInRhYi5yb3V0ZXJMaW5rXCI+XG4gICAgICAgICAgICA8aWNvbiAqbmdJZj1cInRhYi5pY29uXCI+e3t0YWIuaWNvbn19PC9pY29uPjxzcGFuIFtjbGFzcy5hbmltYXRlZFRpdGxlXT1cInNob3VsZEhpZGVUaXRsZVwiICpuZ0lmPVwiIXNob3VsZEhpZGVUaXRsZSB8fCB0YWIuYWN0aXZlIHx8ICghdGFiLmFjdGl2ZSAmJiAhdGFiLmljb24pXCI+e3sgdGFiLnRpdGxlIH19PC9zcGFuPjwvYT5cbiAgICAgICAgPGEgcm9sZT1cInRhYlwiICpuZ0lmPVwiIXRhYi5yb3V0ZXJMaW5rIHx8IHRhYi5kaXNhYmxlZFwiPlxuICAgICAgICAgICAgPGljb24gKm5nSWY9XCJ0YWIuaWNvblwiPnt7dGFiLmljb259fTwvaWNvbj48c3BhbiBbY2xhc3MuYW5pbWF0ZWRUaXRsZV09XCJzaG91bGRIaWRlVGl0bGVcIiAqbmdJZj1cIiFzaG91bGRIaWRlVGl0bGUgfHwgdGFiLmFjdGl2ZSB8fCAoIXRhYi5hY3RpdmUgJiYgIXRhYi5pY29uKVwiPnt7IHRhYi50aXRsZSB9fTwvc3Bhbj48L2E+XG4gICAgPC9saT5cbjwvdWw+XG48bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4iXX0=