carbon-components-angular
Version:
Next generation components
350 lines • 34.1 kB
JavaScript
import { Component, Input, HostListener, ViewChild, ContentChildren, ViewChildren } from "@angular/core";
import { BaseTabHeader } from "./base-tab-header.component";
import { Tab } from "./tab.component";
import * as i0 from "@angular/core";
import * as i1 from "carbon-components-angular/utils";
import * as i2 from "carbon-components-angular/i18n";
import * as i3 from "@angular/common";
/**
* The `TabHeaders` component contains the `Tab` items and controls scroll functionality
* if content has overflow.
*/
export class TabHeaders extends BaseTabHeader {
constructor(elementRef, changeDetectorRef, eventService, renderer, i18n) {
super(elementRef, changeDetectorRef, eventService, renderer);
this.elementRef = elementRef;
this.changeDetectorRef = changeDetectorRef;
this.eventService = eventService;
this.renderer = renderer;
this.i18n = i18n;
this.translations = this.i18n.get().TABS;
/**
* The index of the first visible tab.
*/
this.firstVisibleTab = 0;
}
// keyboard accessibility
/**
* Controls the keydown events used for tabbing through the headings.
*/
keyboardInput(event) {
let tabsArray = this.tabs.toArray();
if (event.key === "ArrowRight") {
if (this.currentSelectedTab < this.allTabHeaders.length - 1) {
event.preventDefault();
if (this.followFocus) {
this.selectTab(event.target, tabsArray[this.currentSelectedTab + 1], this.currentSelectedTab);
}
this.allTabHeaders.toArray()[this.currentSelectedTab + 1].nativeElement.focus();
}
else {
event.preventDefault();
if (this.followFocus) {
this.selectTab(event.target, tabsArray[0], 0);
}
this.allTabHeaders.first.nativeElement.focus();
}
}
if (event.key === "ArrowLeft") {
if (this.currentSelectedTab > 0) {
event.preventDefault();
if (this.followFocus) {
this.selectTab(event.target, tabsArray[this.currentSelectedTab - 1], this.currentSelectedTab);
}
this.allTabHeaders.toArray()[this.currentSelectedTab - 1].nativeElement.focus();
}
else {
event.preventDefault();
if (this.followFocus) {
this.selectTab(event.target, tabsArray[this.allTabHeaders.length - 1], this.allTabHeaders.length);
}
this.allTabHeaders.toArray()[this.allTabHeaders.length - 1].nativeElement.focus();
}
}
if (event.key === "Home") {
event.preventDefault();
if (this.followFocus) {
this.selectTab(event.target, tabsArray[0], 0);
}
this.allTabHeaders.toArray()[0].nativeElement.focus();
}
if (event.key === "End") {
event.preventDefault();
if (this.followFocus) {
this.selectTab(event.target, tabsArray[this.allTabHeaders.length - 1], this.allTabHeaders.length);
}
this.allTabHeaders.toArray()[this.allTabHeaders.length - 1].nativeElement.focus();
}
if ((event.key === " " || event.key === "Spacebar") && !this.followFocus) {
this.selectTab(event.target, tabsArray[this.currentSelectedTab], this.currentSelectedTab);
}
}
ngOnInit() {
// Update scroll on resize
this.resizeObserver = new ResizeObserver(() => {
// Need to explicitly trigger change detection since this runs outside Angular zone
this.changeDetectorRef.detectChanges();
});
this.resizeObserver.observe(this.headerContainer.nativeElement);
}
ngOnDestroy() {
this.resizeObserver.unobserve(this.headerContainer.nativeElement);
}
ngAfterContentInit() {
if (!this.tabInput) {
this.tabs = this.tabQuery;
}
else {
this.tabs = this.tabInput;
}
this.tabs.forEach(tab => tab.cacheActive = this.cacheActive);
this.tabs.changes.subscribe(() => {
this.setFirstTab();
});
this.setFirstTab();
}
ngOnChanges(changes) {
if (this.tabs && changes.cacheActive) {
this.tabs.forEach(tab => tab.cacheActive = this.cacheActive);
}
}
/**
* Controls manually focusing tabs.
*/
onTabFocus(ref, index) {
this.currentSelectedTab = index;
// reset scroll left because we're already handling it
this.headerContainer.nativeElement.parentElement.scrollLeft = 0;
}
getSelectedTab() {
const selected = this.tabs.find(tab => tab.active);
if (selected) {
return selected;
}
return { headingIsTemplate: false, heading: "" };
}
/**
* Selects `Tab` 'tab' and moves it into view on the view DOM if it is not already.
*/
selectTab(ref, tab, tabIndex) {
if (tab.disabled) {
return;
}
this.currentSelectedTab = tabIndex;
this.tabs.forEach(_tab => _tab.active = false);
tab.active = true;
tab.doSelect();
}
/**
* Determines which `Tab` is initially selected.
*/
setFirstTab() {
setTimeout(() => {
let firstTab = this.tabs.find(tab => tab.active);
if (!firstTab && this.tabs.first) {
firstTab = this.tabs.first;
firstTab.active = true;
}
if (firstTab) {
firstTab.doSelect();
}
});
}
}
TabHeaders.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TabHeaders, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.EventService }, { token: i0.Renderer2 }, { token: i2.I18n }], target: i0.ɵɵFactoryTarget.Component });
TabHeaders.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TabHeaders, selector: "cds-tab-headers, ibm-tab-headers", inputs: { tabInput: ["tabs", "tabInput"], translations: "translations" }, host: { listeners: { "keydown": "keyboardInput($event)" } }, queries: [{ propertyName: "tabQuery", predicate: Tab }], viewQueries: [{ propertyName: "headerContainer", first: true, predicate: ["tabList"], descendants: true, static: true }, { propertyName: "allTabHeaders", predicate: ["tabItem"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
<button
type="button"
(click)="handleOverflowNavClick(-1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(-1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--previous"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': leftOverflowNavButtonHidden
}"
[title]="translations.BUTTON_ARIA_LEFT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M5 8L10 3 10.7 3.7 6.4 8 10.7 12.3 10 13z"></path>
</svg>
</button>
<div
#tabList
class="cds--tab--list"
role="tablist"
[attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL"
(scroll)="handleScroll()">
<ng-container [ngTemplateOutlet]="contentBefore"></ng-container>
<button
*ngFor="let tab of tabs; let i = index;"
#tabItem
role="tab"
[attr.aria-selected]="tab.active"
[attr.tabindex]="(tab.active?0:-1)"
[attr.aria-controls]="tab.id"
[attr.aria-disabled]="tab.disabled"
[ngClass]="{
'cds--tabs__nav-item--selected': tab.active,
'cds--tabs__nav-item--disabled': tab.disabled
}"
class="cds--tabs__nav-item cds--tabs__nav-link"
type="button"
draggable="false"
id="{{tab.id}}-header"
(focus)="onTabFocus(tabItem, i)"
(click)="selectTab(tabItem, tab, i)">
<ng-container *ngIf="!tab.headingIsTemplate">
{{ tab.heading }}
</ng-container>
<ng-template
*ngIf="tab.headingIsTemplate"
[ngTemplateOutlet]="tab.heading"
[ngTemplateOutletContext]="{$implicit: tab.context}">
</ng-template>
</button>
<ng-container [ngTemplateOutlet]="contentAfter"></ng-container>
</div>
<button
type="button"
(click)="handleOverflowNavClick(1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--next"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': rightOverflowNavButtonHidden
}"
[title]="translations.BUTTON_ARIA_RIGHT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M11 8L6 13 5.3 12.3 9.6 8 5.3 3.7 6 3z"></path>
</svg>
</button>
`, isInline: true, dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TabHeaders, decorators: [{
type: Component,
args: [{
selector: "cds-tab-headers, ibm-tab-headers",
template: `
<button
type="button"
(click)="handleOverflowNavClick(-1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(-1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--previous"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': leftOverflowNavButtonHidden
}"
[title]="translations.BUTTON_ARIA_LEFT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M5 8L10 3 10.7 3.7 6.4 8 10.7 12.3 10 13z"></path>
</svg>
</button>
<div
#tabList
class="cds--tab--list"
role="tablist"
[attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL"
(scroll)="handleScroll()">
<ng-container [ngTemplateOutlet]="contentBefore"></ng-container>
<button
*ngFor="let tab of tabs; let i = index;"
#tabItem
role="tab"
[attr.aria-selected]="tab.active"
[attr.tabindex]="(tab.active?0:-1)"
[attr.aria-controls]="tab.id"
[attr.aria-disabled]="tab.disabled"
[ngClass]="{
'cds--tabs__nav-item--selected': tab.active,
'cds--tabs__nav-item--disabled': tab.disabled
}"
class="cds--tabs__nav-item cds--tabs__nav-link"
type="button"
draggable="false"
id="{{tab.id}}-header"
(focus)="onTabFocus(tabItem, i)"
(click)="selectTab(tabItem, tab, i)">
<ng-container *ngIf="!tab.headingIsTemplate">
{{ tab.heading }}
</ng-container>
<ng-template
*ngIf="tab.headingIsTemplate"
[ngTemplateOutlet]="tab.heading"
[ngTemplateOutletContext]="{$implicit: tab.context}">
</ng-template>
</button>
<ng-container [ngTemplateOutlet]="contentAfter"></ng-container>
</div>
<button
type="button"
(click)="handleOverflowNavClick(1, tabs.length)"
(pointerdown)="handleOverflowNavMouseDown(1)"
(pointerup)="handleOverflowNavMouseUp()"
(pointerleave)="handleOverflowNavMouseUp()"
(pointerout)="handleOverflowNavMouseUp()"
class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--next"
[ngClass]="{
'cds--tab--overflow-nav-button--hidden': rightOverflowNavButtonHidden
}"
[title]="translations.BUTTON_ARIA_RIGHT">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M11 8L6 13 5.3 12.3 9.6 8 5.3 3.7 6 3z"></path>
</svg>
</button>
`
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.EventService }, { type: i0.Renderer2 }, { type: i2.I18n }]; }, propDecorators: { tabInput: [{
type: Input,
args: ["tabs"]
}], translations: [{
type: Input
}], headerContainer: [{
type: ViewChild,
args: ["tabList", { static: true }]
}], tabQuery: [{
type: ContentChildren,
args: [Tab]
}], allTabHeaders: [{
type: ViewChildren,
args: ["tabItem"]
}], keyboardInput: [{
type: HostListener,
args: ["keydown", ["$event"]]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWhlYWRlcnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3RhYnMvdGFiLWhlYWRlcnMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTixTQUFTLEVBRVQsS0FBSyxFQUNMLFlBQVksRUFDWixTQUFTLEVBQ1QsZUFBZSxFQUVmLFlBQVksRUFRWixNQUFNLGVBQWUsQ0FBQztBQUl2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDNUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7OztBQUV0Qzs7O0dBR0c7QUEyRkgsTUFBTSxPQUFPLFVBQVcsU0FBUSxhQUFhO0lBZ0M1QyxZQUNXLFVBQXNCLEVBQ3RCLGlCQUFvQyxFQUNwQyxZQUEwQixFQUMxQixRQUFtQixFQUNuQixJQUFVO1FBRXBCLEtBQUssQ0FBQyxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBTm5ELGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNwQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLFNBQUksR0FBSixJQUFJLENBQU07UUE3QlosaUJBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztRQWM3Qzs7V0FFRztRQUNILG9CQUFlLEdBQUcsQ0FBQyxDQUFDO0lBZXBCLENBQUM7SUFFRCx5QkFBeUI7SUFDekI7O09BRUc7SUFFSCxhQUFhLENBQUMsS0FBSztRQUNsQixJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRXBDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxZQUFZLEVBQUU7WUFDL0IsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUM1RCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtvQkFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7aUJBQzlGO2dCQUNELElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUNoRjtpQkFBTTtnQkFDTixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtvQkFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztpQkFDOUM7Z0JBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQy9DO1NBQ0Q7UUFFRCxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssV0FBVyxFQUFFO1lBQzlCLElBQUksSUFBSSxDQUFDLGtCQUFrQixHQUFHLENBQUMsRUFBRTtnQkFDaEMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2lCQUM5RjtnQkFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7YUFDaEY7aUJBQU07Z0JBQ04sS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztpQkFDbEc7Z0JBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7YUFDbEY7U0FDRDtRQUVELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxNQUFNLEVBQUU7WUFDekIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUM5QztZQUNELElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ3REO1FBRUQsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEtBQUssRUFBRTtZQUN4QixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdkIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNyQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDbEc7WUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztTQUNsRjtRQUVELElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUN6RSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1NBQzFGO0lBQ0YsQ0FBQztJQUVELFFBQVE7UUFDUCwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxHQUFHLEVBQUU7WUFDN0MsbUZBQW1GO1lBQ25GLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELFdBQVc7UUFDVixJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRCxrQkFBa0I7UUFDakIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDbkIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1NBQzFCO2FBQU07WUFDTixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7U0FDMUI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDaEMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3BCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDakMsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUU7WUFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUM3RDtJQUNGLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVUsQ0FBQyxHQUFnQixFQUFFLEtBQWE7UUFDekMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztRQUNoQyxzREFBc0Q7UUFDdEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELGNBQWM7UUFDYixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRCxJQUFJLFFBQVEsRUFBRTtZQUNiLE9BQU8sUUFBUSxDQUFDO1NBQ2hCO1FBQ0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDbEQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxDQUFDLEdBQWdCLEVBQUUsR0FBUSxFQUFFLFFBQWdCO1FBQ3JELElBQUksR0FBRyxDQUFDLFFBQVEsRUFBRTtZQUNqQixPQUFPO1NBQ1A7UUFFRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsUUFBUSxDQUFDO1FBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQztRQUMvQyxHQUFHLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNsQixHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVEOztPQUVHO0lBQ08sV0FBVztRQUNwQixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2YsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakQsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDakMsUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO2dCQUMzQixRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQzthQUN2QjtZQUNELElBQUksUUFBUSxFQUFFO2dCQUNiLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQzthQUNwQjtRQUNGLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQzs7dUdBckxXLFVBQVU7MkZBQVYsVUFBVSx3T0FpQkwsR0FBRyxpUkF6R1Y7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFxRlQ7MkZBR1csVUFBVTtrQkExRnRCLFNBQVM7bUJBQUM7b0JBQ1YsUUFBUSxFQUFFLGtDQUFrQztvQkFDNUMsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBcUZUO2lCQUNEO3VNQVFlLFFBQVE7c0JBQXRCLEtBQUs7dUJBQUMsTUFBTTtnQkFFSixZQUFZO3NCQUFwQixLQUFLO2dCQUtrQyxlQUFlO3NCQUF0RCxTQUFTO3VCQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBSWhCLFFBQVE7c0JBQTdCLGVBQWU7dUJBQUMsR0FBRztnQkFZSyxhQUFhO3NCQUFyQyxZQUFZO3VCQUFDLFNBQVM7Z0JBa0J2QixhQUFhO3NCQURaLFlBQVk7dUJBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0Q29tcG9uZW50LFxuXHRRdWVyeUxpc3QsXG5cdElucHV0LFxuXHRIb3N0TGlzdGVuZXIsXG5cdFZpZXdDaGlsZCxcblx0Q29udGVudENoaWxkcmVuLFxuXHRBZnRlckNvbnRlbnRJbml0LFxuXHRWaWV3Q2hpbGRyZW4sXG5cdEVsZW1lbnRSZWYsXG5cdE9uQ2hhbmdlcyxcblx0U2ltcGxlQ2hhbmdlcyxcblx0T25EZXN0cm95LFxuXHRPbkluaXQsXG5cdENoYW5nZURldGVjdG9yUmVmLFxuXHRSZW5kZXJlcjJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEV2ZW50U2VydmljZSB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL3V0aWxzXCI7XG5pbXBvcnQgeyBJMThuIH0gZnJvbSBcImNhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXIvaTE4blwiO1xuXG5pbXBvcnQgeyBCYXNlVGFiSGVhZGVyIH0gZnJvbSBcIi4vYmFzZS10YWItaGVhZGVyLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgVGFiIH0gZnJvbSBcIi4vdGFiLmNvbXBvbmVudFwiO1xuXG4vKipcbiAqIFRoZSBgVGFiSGVhZGVyc2AgY29tcG9uZW50IGNvbnRhaW5zIHRoZSBgVGFiYCBpdGVtcyBhbmQgY29udHJvbHMgc2Nyb2xsIGZ1bmN0aW9uYWxpdHlcbiAqIGlmIGNvbnRlbnQgaGFzIG92ZXJmbG93LlxuICovXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6IFwiY2RzLXRhYi1oZWFkZXJzLCBpYm0tdGFiLWhlYWRlcnNcIixcblx0dGVtcGxhdGU6IGBcblx0XHQ8YnV0dG9uXG5cdFx0XHR0eXBlPVwiYnV0dG9uXCJcblx0XHRcdChjbGljayk9XCJoYW5kbGVPdmVyZmxvd05hdkNsaWNrKC0xLCB0YWJzLmxlbmd0aClcIlxuXHRcdFx0KHBvaW50ZXJkb3duKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VEb3duKC0xKVwiXG5cdFx0XHQocG9pbnRlcnVwKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVybGVhdmUpPVwiaGFuZGxlT3ZlcmZsb3dOYXZNb3VzZVVwKClcIlxuXHRcdFx0KHBvaW50ZXJvdXQpPVwiaGFuZGxlT3ZlcmZsb3dOYXZNb3VzZVVwKClcIlxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRhYi0tb3ZlcmZsb3ctbmF2LWJ1dHRvbiBjZHMtLXRhYi0tb3ZlcmZsb3ctbmF2LWJ1dHRvbi0tcHJldmlvdXNcIlxuXHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHQnY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24tLWhpZGRlbic6IGxlZnRPdmVyZmxvd05hdkJ1dHRvbkhpZGRlblxuXHRcdFx0fVwiXG5cdFx0XHRbdGl0bGVdPVwidHJhbnNsYXRpb25zLkJVVFRPTl9BUklBX0xFRlRcIj5cblx0XHRcdDxzdmdcblx0XHRcdFx0Zm9jdXNhYmxlPVwiZmFsc2VcIlxuXHRcdFx0XHRwcmVzZXJ2ZUFzcGVjdFJhdGlvPVwieE1pZFlNaWQgbWVldFwiXG5cdFx0XHRcdHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuXHRcdFx0XHRmaWxsPVwiY3VycmVudENvbG9yXCJcblx0XHRcdFx0d2lkdGg9XCIxNlwiXG5cdFx0XHRcdGhlaWdodD1cIjE2XCJcblx0XHRcdFx0dmlld0JveD1cIjAgMCAxNiAxNlwiXG5cdFx0XHRcdGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuXHRcdFx0XHQ8cGF0aCBkPVwiTTUgOEwxMCAzIDEwLjcgMy43IDYuNCA4IDEwLjcgMTIuMyAxMCAxM3pcIj48L3BhdGg+XG5cdFx0XHQ8L3N2Zz5cblx0XHQ8L2J1dHRvbj5cblx0XHQ8ZGl2XG5cdFx0XHQjdGFiTGlzdFxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRhYi0tbGlzdFwiXG5cdFx0XHRyb2xlPVwidGFibGlzdFwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbCB8fCB0cmFuc2xhdGlvbnMuSEVBREVSX0FSSUFfTEFCRUxcIlxuXHRcdFx0KHNjcm9sbCk9XCJoYW5kbGVTY3JvbGwoKVwiPlxuXHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50QmVmb3JlXCI+PC9uZy1jb250YWluZXI+XG5cdFx0XHQ8YnV0dG9uXG5cdFx0XHRcdCpuZ0Zvcj1cImxldCB0YWIgb2YgdGFiczsgbGV0IGkgPSBpbmRleDtcIlxuXHRcdFx0XHQjdGFiSXRlbVxuXHRcdFx0XHRyb2xlPVwidGFiXCJcblx0XHRcdFx0W2F0dHIuYXJpYS1zZWxlY3RlZF09XCJ0YWIuYWN0aXZlXCJcblx0XHRcdFx0W2F0dHIudGFiaW5kZXhdPVwiKHRhYi5hY3RpdmU/MDotMSlcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLWNvbnRyb2xzXT1cInRhYi5pZFwiXG5cdFx0XHRcdFthdHRyLmFyaWEtZGlzYWJsZWRdPVwidGFiLmRpc2FibGVkXCJcblx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdCdjZHMtLXRhYnNfX25hdi1pdGVtLS1zZWxlY3RlZCc6IHRhYi5hY3RpdmUsXG5cdFx0XHRcdFx0J2Nkcy0tdGFic19fbmF2LWl0ZW0tLWRpc2FibGVkJzogdGFiLmRpc2FibGVkXG5cdFx0XHRcdH1cIlxuXHRcdFx0XHRjbGFzcz1cImNkcy0tdGFic19fbmF2LWl0ZW0gY2RzLS10YWJzX19uYXYtbGlua1wiXG5cdFx0XHRcdHR5cGU9XCJidXR0b25cIlxuXHRcdFx0XHRkcmFnZ2FibGU9XCJmYWxzZVwiXG5cdFx0XHRcdGlkPVwie3t0YWIuaWR9fS1oZWFkZXJcIlxuXHRcdFx0XHQoZm9jdXMpPVwib25UYWJGb2N1cyh0YWJJdGVtLCBpKVwiXG5cdFx0XHRcdChjbGljayk9XCJzZWxlY3RUYWIodGFiSXRlbSwgdGFiLCBpKVwiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIXRhYi5oZWFkaW5nSXNUZW1wbGF0ZVwiPlxuXHRcdFx0XHRcdHt7IHRhYi5oZWFkaW5nIH19XG5cdFx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGVcblx0XHRcdFx0XHQqbmdJZj1cInRhYi5oZWFkaW5nSXNUZW1wbGF0ZVwiXG5cdFx0XHRcdFx0W25nVGVtcGxhdGVPdXRsZXRdPVwidGFiLmhlYWRpbmdcIlxuXHRcdFx0XHRcdFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiB0YWIuY29udGV4dH1cIj5cblx0XHRcdFx0PC9uZy10ZW1wbGF0ZT5cblx0XHRcdDwvYnV0dG9uPlxuXHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50QWZ0ZXJcIj48L25nLWNvbnRhaW5lcj5cblx0XHQ8L2Rpdj5cblx0XHQ8YnV0dG9uXG5cdFx0XHR0eXBlPVwiYnV0dG9uXCJcblx0XHRcdChjbGljayk9XCJoYW5kbGVPdmVyZmxvd05hdkNsaWNrKDEsIHRhYnMubGVuZ3RoKVwiXG5cdFx0XHQocG9pbnRlcmRvd24pPVwiaGFuZGxlT3ZlcmZsb3dOYXZNb3VzZURvd24oMSlcIlxuXHRcdFx0KHBvaW50ZXJ1cCk9XCJoYW5kbGVPdmVyZmxvd05hdk1vdXNlVXAoKVwiXG5cdFx0XHQocG9pbnRlcmxlYXZlKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVyb3V0KT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdGNsYXNzPVwiY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24gY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24tLW5leHRcIlxuXHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHQnY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24tLWhpZGRlbic6IHJpZ2h0T3ZlcmZsb3dOYXZCdXR0b25IaWRkZW5cblx0XHRcdH1cIlxuXHRcdFx0W3RpdGxlXT1cInRyYW5zbGF0aW9ucy5CVVRUT05fQVJJQV9SSUdIVFwiPlxuXHRcdFx0PHN2Z1xuXHRcdFx0XHRmb2N1c2FibGU9XCJmYWxzZVwiXG5cdFx0XHRcdHByZXNlcnZlQXNwZWN0UmF0aW89XCJ4TWlkWU1pZCBtZWV0XCJcblx0XHRcdFx0eG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG5cdFx0XHRcdGZpbGw9XCJjdXJyZW50Q29sb3JcIlxuXHRcdFx0XHR3aWR0aD1cIjE2XCJcblx0XHRcdFx0aGVpZ2h0PVwiMTZcIlxuXHRcdFx0XHR2aWV3Qm94PVwiMCAwIDE2IDE2XCJcblx0XHRcdFx0YXJpYS1oaWRkZW49XCJ0cnVlXCI+XG5cdFx0XHRcdDxwYXRoIGQ9XCJNMTEgOEw2IDEzIDUuMyAxMi4zIDkuNiA4IDUuMyAzLjcgNiAzelwiPjwvcGF0aD5cblx0XHRcdDwvc3ZnPlxuXHRcdDwvYnV0dG9uPlxuXHRgXG59KVxuXG5leHBvcnQgY2xhc3MgVGFiSGVhZGVycyBleHRlbmRzIEJhc2VUYWJIZWFkZXIgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0IHtcblx0LyoqXG5cdCAqIExpc3Qgb2YgYFRhYmAgY29tcG9uZW50cy5cblx0ICovXG5cdC8vIGRpc2FibGUgdGhlIG5leHQgbGluZSBiZWNhdXNlIHdlIG5lZWQgdG8gcmVuYW1lIHRoZSBpbnB1dFxuXHQvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmVcblx0QElucHV0KFwidGFic1wiKSB0YWJJbnB1dDogUXVlcnlMaXN0PFRhYj47XG5cblx0QElucHV0KCkgdHJhbnNsYXRpb25zID0gdGhpcy5pMThuLmdldCgpLlRBQlM7XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIFVub3JkZXJlZCBMaXN0IGVsZW1lbnQgdGhhdCBob2xkcyB0aGUgYFRhYmAgaGVhZGluZ3MgZnJvbSB0aGUgdmlldyBET00uXG5cdCAqL1xuXHRAVmlld0NoaWxkKFwidGFiTGlzdFwiLCB7IHN0YXRpYzogdHJ1ZSB9KSBoZWFkZXJDb250YWluZXI6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXHQvKipcblx0ICogQ29udGVudENoaWxkIG9mIGFsbCB0aGUgbi10YWJzXG5cdCAqL1xuXHRAQ29udGVudENoaWxkcmVuKFRhYikgdGFiUXVlcnk6IFF1ZXJ5TGlzdDxUYWI+O1xuXHQvKipcblx0ICogc2V0IHRvIHRhYlF1ZXJ5IGlmIHRhYklucHV0IGlzIGVtcHR5XG5cdCAqL1xuXHR0YWJzOiBRdWVyeUxpc3Q8VGFiPjtcblx0LyoqXG5cdCAqIFRoZSBpbmRleCBvZiB0aGUgZmlyc3QgdmlzaWJsZSB0YWIuXG5cdCAqL1xuXHRmaXJzdFZpc2libGVUYWIgPSAwO1xuXHQvKipcblx0ICogVGhlIERPTSBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGBUYWJgIGhlYWRpbmdzIGRpc3BsYXllZC5cblx0ICovXG5cdEBWaWV3Q2hpbGRyZW4oXCJ0YWJJdGVtXCIpIGFsbFRhYkhlYWRlcnM6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPjtcblx0cHJpdmF0ZSByZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXI7XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJvdGVjdGVkIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG5cdFx0cHJvdGVjdGVkIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcblx0XHRwcm90ZWN0ZWQgZXZlbnRTZXJ2aWNlOiBFdmVudFNlcnZpY2UsXG5cdFx0cHJvdGVjdGVkIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG5cdFx0cHJvdGVjdGVkIGkxOG46IEkxOG5cblx0KSB7XG5cdFx0c3VwZXIoZWxlbWVudFJlZiwgY2hhbmdlRGV0ZWN0b3JSZWYsIGV2ZW50U2VydmljZSwgcmVuZGVyZXIpO1xuXHR9XG5cblx0Ly8ga2V5Ym9hcmQgYWNjZXNzaWJpbGl0eVxuXHQvKipcblx0ICogQ29udHJvbHMgdGhlIGtleWRvd24gZXZlbnRzIHVzZWQgZm9yIHRhYmJpbmcgdGhyb3VnaCB0aGUgaGVhZGluZ3MuXG5cdCAqL1xuXHRASG9zdExpc3RlbmVyKFwia2V5ZG93blwiLCBbXCIkZXZlbnRcIl0pXG5cdGtleWJvYXJkSW5wdXQoZXZlbnQpIHtcblx0XHRsZXQgdGFic0FycmF5ID0gdGhpcy50YWJzLnRvQXJyYXkoKTtcblxuXHRcdGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dSaWdodFwiKSB7XG5cdFx0XHRpZiAodGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgPCB0aGlzLmFsbFRhYkhlYWRlcnMubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRpZiAodGhpcy5mb2xsb3dGb2N1cykge1xuXHRcdFx0XHRcdHRoaXMuc2VsZWN0VGFiKGV2ZW50LnRhcmdldCwgdGFic0FycmF5W3RoaXMuY3VycmVudFNlbGVjdGVkVGFiICsgMV0sIHRoaXMuY3VycmVudFNlbGVjdGVkVGFiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmFsbFRhYkhlYWRlcnMudG9BcnJheSgpW3RoaXMuY3VycmVudFNlbGVjdGVkVGFiICsgMV0ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0aWYgKHRoaXMuZm9sbG93Rm9jdXMpIHtcblx0XHRcdFx0XHR0aGlzLnNlbGVjdFRhYihldmVudC50YXJnZXQsIHRhYnNBcnJheVswXSwgMCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5hbGxUYWJIZWFkZXJzLmZpcnN0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkFycm93TGVmdFwiKSB7XG5cdFx0XHRpZiAodGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgPiAwKSB7XG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdGlmICh0aGlzLmZvbGxvd0ZvY3VzKSB7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RUYWIoZXZlbnQudGFyZ2V0LCB0YWJzQXJyYXlbdGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgLSAxXSwgdGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuYWxsVGFiSGVhZGVycy50b0FycmF5KClbdGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgLSAxXS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRpZiAodGhpcy5mb2xsb3dGb2N1cykge1xuXHRcdFx0XHRcdHRoaXMuc2VsZWN0VGFiKGV2ZW50LnRhcmdldCwgdGFic0FycmF5W3RoaXMuYWxsVGFiSGVhZGVycy5sZW5ndGggLSAxXSwgdGhpcy5hbGxUYWJIZWFkZXJzLmxlbmd0aCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5hbGxUYWJIZWFkZXJzLnRvQXJyYXkoKVt0aGlzLmFsbFRhYkhlYWRlcnMubGVuZ3RoIC0gMV0ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChldmVudC5rZXkgPT09IFwiSG9tZVwiKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0aWYgKHRoaXMuZm9sbG93Rm9jdXMpIHtcblx0XHRcdFx0dGhpcy5zZWxlY3RUYWIoZXZlbnQudGFyZ2V0LCB0YWJzQXJyYXlbMF0sIDApO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5hbGxUYWJIZWFkZXJzLnRvQXJyYXkoKVswXS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG5cdFx0fVxuXG5cdFx0aWYgKGV2ZW50LmtleSA9PT0gXCJFbmRcIikge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdGlmICh0aGlzLmZvbGxvd0ZvY3VzKSB7XG5cdFx0XHRcdHRoaXMuc2VsZWN0VGFiKGV2ZW50LnRhcmdldCwgdGFic0FycmF5W3RoaXMuYWxsVGFiSGVhZGVycy5sZW5ndGggLSAxXSwgdGhpcy5hbGxUYWJIZWFkZXJzLmxlbmd0aCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmFsbFRhYkhlYWRlcnMudG9BcnJheSgpW3RoaXMuYWxsVGFiSGVhZGVycy5sZW5ndGggLSAxXS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG5cdFx0fVxuXG5cdFx0aWYgKChldmVudC5rZXkgPT09IFwiIFwiIHx8IGV2ZW50LmtleSA9PT0gXCJTcGFjZWJhclwiKSAmJiAhdGhpcy5mb2xsb3dGb2N1cykge1xuXHRcdFx0dGhpcy5zZWxlY3RUYWIoZXZlbnQudGFyZ2V0LCB0YWJzQXJyYXlbdGhpcy5jdXJyZW50U2VsZWN0ZWRUYWJdLCB0aGlzLmN1cnJlbnRTZWxlY3RlZFRhYik7XG5cdFx0fVxuXHR9XG5cblx0bmdPbkluaXQoKTogdm9pZCB7XG5cdFx0Ly8gVXBkYXRlIHNjcm9sbCBvbiByZXNpemVcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcblx0XHRcdC8vIE5lZWQgdG8gZXhwbGljaXRseSB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb24gc2luY2UgdGhpcyBydW5zIG91dHNpZGUgQW5ndWxhciB6b25lXG5cdFx0XHR0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcblx0XHR9KTtcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5oZWFkZXJDb250YWluZXIubmF0aXZlRWxlbWVudCk7XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpOiB2b2lkIHtcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyLnVub2JzZXJ2ZSh0aGlzLmhlYWRlckNvbnRhaW5lci5uYXRpdmVFbGVtZW50KTtcblx0fVxuXG5cdG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcblx0XHRpZiAoIXRoaXMudGFiSW5wdXQpIHtcblx0XHRcdHRoaXMudGFicyA9IHRoaXMudGFiUXVlcnk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMudGFicyA9IHRoaXMudGFiSW5wdXQ7XG5cdFx0fVxuXG5cdFx0dGhpcy50YWJzLmZvckVhY2godGFiID0+IHRhYi5jYWNoZUFjdGl2ZSA9IHRoaXMuY2FjaGVBY3RpdmUpO1xuXHRcdHRoaXMudGFicy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHR0aGlzLnNldEZpcnN0VGFiKCk7XG5cdFx0fSk7XG5cdFx0dGhpcy5zZXRGaXJzdFRhYigpO1xuXHR9XG5cblx0bmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuXHRcdGlmICh0aGlzLnRhYnMgJiYgY2hhbmdlcy5jYWNoZUFjdGl2ZSkge1xuXHRcdFx0dGhpcy50YWJzLmZvckVhY2godGFiID0+IHRhYi5jYWNoZUFjdGl2ZSA9IHRoaXMuY2FjaGVBY3RpdmUpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDb250cm9scyBtYW51YWxseSBmb2N1c2luZyB0YWJzLlxuXHQgKi9cblx0b25UYWJGb2N1cyhyZWY6IEhUTUxFbGVtZW50LCBpbmRleDogbnVtYmVyKSB7XG5cdFx0dGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgPSBpbmRleDtcblx0XHQvLyByZXNldCBzY3JvbGwgbGVmdCBiZWNhdXNlIHdlJ3JlIGFscmVhZHkgaGFuZGxpbmcgaXRcblx0XHR0aGlzLmhlYWRlckNvbnRhaW5lci5uYXRpdmVFbGVtZW50LnBhcmVudEVsZW1lbnQuc2Nyb2xsTGVmdCA9IDA7XG5cdH1cblxuXHRnZXRTZWxlY3RlZFRhYigpOiBhbnkge1xuXHRcdGNvbnN0IHNlbGVjdGVkID0gdGhpcy50YWJzLmZpbmQodGFiID0+IHRhYi5hY3RpdmUpO1xuXHRcdGlmIChzZWxlY3RlZCkge1xuXHRcdFx0cmV0dXJuIHNlbGVjdGVkO1xuXHRcdH1cblx0XHRyZXR1cm4geyBoZWFkaW5nSXNUZW1wbGF0ZTogZmFsc2UsIGhlYWRpbmc6IFwiXCIgfTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZWxlY3RzIGBUYWJgICd0YWInIGFuZCBtb3ZlcyBpdCBpbnRvIHZpZXcgb24gdGhlIHZpZXcgRE9NIGlmIGl0IGlzIG5vdCBhbHJlYWR5LlxuXHQgKi9cblx0c2VsZWN0VGFiKHJlZjogSFRNTEVsZW1lbnQsIHRhYjogVGFiLCB0YWJJbmRleDogbnVtYmVyKSB7XG5cdFx0aWYgKHRhYi5kaXNhYmxlZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMuY3VycmVudFNlbGVjdGVkVGFiID0gdGFiSW5kZXg7XG5cdFx0dGhpcy50YWJzLmZvckVhY2goX3RhYiA9PiBfdGFiLmFjdGl2ZSA9IGZhbHNlKTtcblx0XHR0YWIuYWN0aXZlID0gdHJ1ZTtcblx0XHR0YWIuZG9TZWxlY3QoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZXRlcm1pbmVzIHdoaWNoIGBUYWJgIGlzIGluaXRpYWxseSBzZWxlY3RlZC5cblx0ICovXG5cdHByb3RlY3RlZCBzZXRGaXJzdFRhYigpIHtcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdGxldCBmaXJzdFRhYiA9IHRoaXMudGFicy5maW5kKHRhYiA9PiB0YWIuYWN0aXZlKTtcblx0XHRcdGlmICghZmlyc3RUYWIgJiYgdGhpcy50YWJzLmZpcnN0KSB7XG5cdFx0XHRcdGZpcnN0VGFiID0gdGhpcy50YWJzLmZpcnN0O1xuXHRcdFx0XHRmaXJzdFRhYi5hY3RpdmUgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGZpcnN0VGFiKSB7XG5cdFx0XHRcdGZpcnN0VGFiLmRvU2VsZWN0KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn1cbiJdfQ==