carbon-components-angular
Version:
Next generation components
316 lines • 41.2 kB
JavaScript
import { Component, ContentChildren, EventEmitter, HostBinding, HostListener, Input, Output, ViewChild } from "@angular/core";
import { Subscription } from "rxjs";
import { BaseTabHeader } from "./base-tab-header.component";
import { TabHeaderBase } from "./tab-header.directive";
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";
const VERTICAL_TAB_HEIGHT = 64;
/**
* Vertical tab header group: same children as `cds-tab-header-group`, with
* up/down (and Home/End) keys, gradient overflow, and always-contained type.
*
*
* ```html
* <cds-tabs-vertical-grouped height="400px">
* <cds-tab-header-group-vertical>
* <cds-tab-header [paneReference]="a">A</cds-tab-header>
* <cds-tab-header [paneReference]="b">B</cds-tab-header>
* </cds-tab-header-group-vertical>
* <cds-tab #a>...</cds-tab>
* <cds-tab #b>...</cds-tab>
* </cds-tabs-vertical-grouped>
* ```
*/
export class TabHeaderGroupVertical 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;
/**
* i18n strings for the tab list `aria-label` fallback.
*/
this.translations = this.i18n.get().TABS;
/**
* When `true`, sets each tab panel `tabindex` to `-1` for navigation-style usage.
*/
this.isNavigation = false;
/**
* Fires with tab index when a close control is used (with `dismissable`).
*/
this.tabClose = new EventEmitter();
/**
* Set to 'true' to have tabs automatically activated and have their content displayed when they receive focus.
*/
this.followFocus = true;
this.verticalClass = true;
/**
* Index of the selected tab for keyboard logic
*/
this.currentSelectedTab = 0;
/**
* Focused tab index when `followFocus` is false (manual activation).
*/
this.activeIndex = null;
this.isOverflowingTop = false;
this.isOverflowingBottom = false;
this.selectedSubscriptionTracker = new Subscription();
this.closeSubscriptionTracker = new Subscription();
this.resizeObserver = null;
this.type = "contained";
// Cache a stable reference for add/removeEventListener.
this.boundListScrollHandler = () => this.updateOverflowState();
}
/**
* We use taller rows when any header has a secondary label.
*/
get tallClass() {
return this.hasSecondaryLabelTabs;
}
get hasSecondaryLabelTabs() {
if (!this.tabHeaderQuery) {
return false;
}
return this.tabHeaderQuery
.toArray()
.some((h) => h.secondaryLabel != null && h.secondaryLabel !== "");
}
keyboardInput(event) {
if (!this.tabHeaderQuery) {
return;
}
const tabHeadersArray = this.tabHeaderQuery.toArray();
const enabledHeaders = tabHeadersArray.filter((h) => !h.disabled);
if (enabledHeaders.length === 0) {
return;
}
const referenceIndex = this.followFocus
? this.currentSelectedTab
: (this.activeIndex !== null ? this.activeIndex : this.currentSelectedTab);
const currentEnabledIndex = Math.max(0, enabledHeaders.indexOf(tabHeadersArray[referenceIndex]));
let nextEnabledIndex = currentEnabledIndex;
let handled = false;
if (event.key === "ArrowDown") {
nextEnabledIndex = (currentEnabledIndex + 1) % enabledHeaders.length;
handled = true;
}
else if (event.key === "ArrowUp") {
nextEnabledIndex = (enabledHeaders.length + currentEnabledIndex - 1) % enabledHeaders.length;
handled = true;
}
else if (event.key === "Home") {
nextEnabledIndex = 0;
handled = true;
}
else if (event.key === "End") {
nextEnabledIndex = enabledHeaders.length - 1;
handled = true;
}
if (handled) {
event.preventDefault();
const nextHeader = enabledHeaders[nextEnabledIndex];
const nextIndex = tabHeadersArray.indexOf(nextHeader);
if (this.followFocus) {
nextHeader.selectTab();
this.currentSelectedTab = nextIndex;
}
else {
nextHeader.focus();
this.activeIndex = nextIndex;
}
return;
}
if ((event.key === " " || event.key === "Spacebar") && !this.followFocus) {
const focusIndex = this.activeIndex !== null ? this.activeIndex : this.currentSelectedTab;
tabHeadersArray[focusIndex].selectTab();
this.currentSelectedTab = focusIndex;
}
}
handleBlur(event) {
const relatedTarget = event.relatedTarget;
const container = this.headerContainer?.nativeElement;
if (container && relatedTarget && container.contains(relatedTarget)) {
return;
}
if (!this.followFocus) {
this.activeIndex = this.currentSelectedTab;
}
}
ngOnInit() {
this.resizeObserver = new ResizeObserver(() => {
this.updateOverflowState();
this.changeDetectorRef.detectChanges();
});
this.resizeObserver.observe(this.headerContainer.nativeElement);
this.headerContainer.nativeElement.addEventListener("scroll", this.boundListScrollHandler);
}
ngOnDestroy() {
this.selectedSubscriptionTracker.unsubscribe();
this.closeSubscriptionTracker.unsubscribe();
this.resizeObserver?.unobserve(this.headerContainer.nativeElement);
this.resizeObserver = null;
this.headerContainer.nativeElement.removeEventListener("scroll", this.boundListScrollHandler);
}
ngAfterContentInit() {
// Reallocate trackers because subscriptions are permanently closed after unsubscribe
this.selectedSubscriptionTracker.unsubscribe();
this.closeSubscriptionTracker.unsubscribe();
this.selectedSubscriptionTracker = new Subscription();
this.closeSubscriptionTracker = new Subscription();
this.applyHeaderInputs();
this.wireSubscriptions();
this.tabHeaderQuery.changes.subscribe(() => {
// Re-wire when the projected list changes.
this.selectedSubscriptionTracker.unsubscribe();
this.closeSubscriptionTracker.unsubscribe();
this.selectedSubscriptionTracker = new Subscription();
this.closeSubscriptionTracker = new Subscription();
this.applyHeaderInputs();
this.wireSubscriptions();
this.changeDetectorRef.markForCheck();
});
setTimeout(() => {
const headers = this.tabHeaderQuery.toArray();
const activeIdx = headers.findIndex(h => h.active || h.paneReference?.active);
const initialIndex = activeIdx >= 0 ? activeIdx : 0;
this.currentSelectedTab = initialIndex;
this.activeIndex = initialIndex;
headers[initialIndex]?.selectTab();
this.updateOverflowState();
});
}
ngOnChanges(changes) {
if (this.tabHeaderQuery) {
if (changes.cacheActive) {
this.tabHeaderQuery.toArray().forEach(h => h.cacheActive = this.cacheActive);
}
if (changes.dismissable) {
this.tabHeaderQuery.toArray().forEach(h => h.dismissable = this.dismissable);
}
if (changes.isNavigation) {
this.tabHeaderQuery.toArray()
.forEach(h => h.paneTabIndex = this.isNavigation ? null : 0);
}
}
}
updateOverflowState() {
const element = this.headerContainer?.nativeElement;
if (!element) {
return;
}
const halfTabHeight = VERTICAL_TAB_HEIGHT / 2;
this.isOverflowingBottom =
element.scrollTop + element.clientHeight + halfTabHeight <= element.scrollHeight;
this.isOverflowingTop = element.scrollTop > halfTabHeight;
this.changeDetectorRef.markForCheck();
}
scrollSelectedTabIntoView() {
if (!this.scrollIntoView) {
return;
}
const container = this.headerContainer?.nativeElement;
if (!container) {
return;
}
container.scrollTo({
top: Math.max(0, (this.currentSelectedTab - 1) * VERTICAL_TAB_HEIGHT),
behavior: "smooth"
});
}
applyHeaderInputs() {
this.tabHeaderQuery.toArray().forEach((header) => {
header.cacheActive = this.cacheActive;
header.dismissable = this.dismissable;
header.paneTabIndex = this.isNavigation ? null : 0;
});
}
wireSubscriptions() {
this.tabHeaderQuery.toArray().forEach((header) => {
this.selectedSubscriptionTracker.add(header.selected.subscribe(() => {
this.currentSelectedTab = this.tabHeaderQuery
.toArray()
.indexOf(header);
this.tabHeaderQuery
.toArray()
.filter((h) => h !== header)
.forEach((other) => {
other.active = false;
if (other.paneReference) {
other.paneReference.active = false;
}
});
this.scrollSelectedTabIntoView();
}));
this.closeSubscriptionTracker.add(header.tabClose.subscribe(() => {
const index = this.tabHeaderQuery.toArray().indexOf(header);
this.tabClose.emit(index);
}));
});
}
}
TabHeaderGroupVertical.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TabHeaderGroupVertical, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.EventService }, { token: i0.Renderer2 }, { token: i2.I18n }], target: i0.ɵɵFactoryTarget.Component });
TabHeaderGroupVertical.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TabHeaderGroupVertical, selector: "cds-tab-header-group-vertical, ibm-tab-header-group-vertical", inputs: { translations: "translations", isNavigation: "isNavigation", followFocus: "followFocus" }, outputs: { tabClose: "tabClose" }, host: { listeners: { "keydown": "keyboardInput($event)", "blur": "handleBlur($event)" }, properties: { "class.cds--tabs--vertical": "this.verticalClass", "class.cds--tabs--tall": "this.tallClass" } }, queries: [{ propertyName: "tabHeaderQuery", predicate: TabHeaderBase }], viewQueries: [{ propertyName: "headerContainer", first: true, predicate: ["tabList"], descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
<div *ngIf="isOverflowingTop" class="cds--tab--list-gradient_top"></div>
<div
#tabList
class="cds--tab--list"
role="tablist"
[attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL"
[attr.aria-labelledby]="ariaLabelledby || null">
<ng-container [ngTemplateOutlet]="contentBefore"></ng-container>
<ng-content></ng-content>
<ng-container [ngTemplateOutlet]="contentAfter"></ng-container>
</div>
<div *ngIf="isOverflowingBottom" class="cds--tab--list-gradient_bottom"></div>
`, isInline: true, dependencies: [{ 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: TabHeaderGroupVertical, decorators: [{
type: Component,
args: [{
selector: "cds-tab-header-group-vertical, ibm-tab-header-group-vertical",
template: `
<div *ngIf="isOverflowingTop" class="cds--tab--list-gradient_top"></div>
<div
#tabList
class="cds--tab--list"
role="tablist"
[attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL"
[attr.aria-labelledby]="ariaLabelledby || null">
<ng-container [ngTemplateOutlet]="contentBefore"></ng-container>
<ng-content></ng-content>
<ng-container [ngTemplateOutlet]="contentAfter"></ng-container>
</div>
<div *ngIf="isOverflowingBottom" class="cds--tab--list-gradient_bottom"></div>
`
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.EventService }, { type: i0.Renderer2 }, { type: i2.I18n }]; }, propDecorators: { translations: [{
type: Input
}], isNavigation: [{
type: Input
}], tabClose: [{
type: Output
}], followFocus: [{
type: Input
}], tabHeaderQuery: [{
type: ContentChildren,
args: [TabHeaderBase]
}], headerContainer: [{
type: ViewChild,
args: ["tabList", { static: true }]
}], verticalClass: [{
type: HostBinding,
args: ["class.cds--tabs--vertical"]
}], tallClass: [{
type: HostBinding,
args: ["class.cds--tabs--tall"]
}], keyboardInput: [{
type: HostListener,
args: ["keydown", ["$event"]]
}], handleBlur: [{
type: HostListener,
args: ["blur", ["$event"]]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWhlYWRlci1ncm91cC12ZXJ0aWNhbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGFicy90YWItaGVhZGVyLWdyb3VwLXZlcnRpY2FsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR04sU0FBUyxFQUNULGVBQWUsRUFFZixZQUFZLEVBQ1osV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBSUwsTUFBTSxFQUlOLFNBQVMsRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSXBDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7O0FBRXZELE1BQU0sbUJBQW1CLEdBQUcsRUFBRSxDQUFDO0FBRS9COzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQWtCSCxNQUFNLE9BQU8sc0JBQ1osU0FBUSxhQUFhO0lBbUVyQixZQUNXLFVBQXNCLEVBQ3RCLGlCQUFvQyxFQUNwQyxZQUEwQixFQUMxQixRQUFtQixFQUNuQixJQUFVO1FBRXBCLEtBQUssQ0FBQyxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBTm5ELGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNwQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLFNBQUksR0FBSixJQUFJLENBQU07UUF0RXJCOztXQUVHO1FBQ00saUJBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztRQUU3Qzs7V0FFRztRQUNNLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRTlCOztXQUVHO1FBQ08sYUFB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VDtpQkFDRDt1TUFPUyxZQUFZO3NCQUFwQixLQUFLO2dCQUtHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBS0ksUUFBUTtzQkFBakIsTUFBTTtnQkFLRSxXQUFXO3NCQUFuQixLQUFLO2dCQU0wQixjQUFjO3NCQUE3QyxlQUFlO3VCQUFDLGFBQWE7Z0JBRVUsZUFBZTtzQkFBdEQsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUVJLGFBQWE7c0JBQXRELFdBQVc7dUJBQUMsMkJBQTJCO2dCQWtCRSxTQUFTO3NCQUFsRCxXQUFXO3VCQUFDLHVCQUF1QjtnQkFpQ3BDLGFBQWE7c0JBRFosWUFBWTt1QkFBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBd0RuQyxVQUFVO3NCQURULFlBQVk7dUJBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuXHRBZnRlckNvbnRlbnRJbml0LFxyXG5cdENoYW5nZURldGVjdG9yUmVmLFxyXG5cdENvbXBvbmVudCxcclxuXHRDb250ZW50Q2hpbGRyZW4sXHJcblx0RWxlbWVudFJlZixcclxuXHRFdmVudEVtaXR0ZXIsXHJcblx0SG9zdEJpbmRpbmcsXHJcblx0SG9zdExpc3RlbmVyLFxyXG5cdElucHV0LFxyXG5cdE9uQ2hhbmdlcyxcclxuXHRPbkRlc3Ryb3ksXHJcblx0T25Jbml0LFxyXG5cdE91dHB1dCxcclxuXHRRdWVyeUxpc3QsXHJcblx0UmVuZGVyZXIyLFxyXG5cdFNpbXBsZUNoYW5nZXMsXHJcblx0Vmlld0NoaWxkXHJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgRXZlbnRTZXJ2aWNlIH0gZnJvbSBcImNhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXIvdXRpbHNcIjtcclxuaW1wb3J0IHsgSTE4biB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL2kxOG5cIjtcclxuXHJcbmltcG9ydCB7IEJhc2VUYWJIZWFkZXIgfSBmcm9tIFwiLi9iYXNlLXRhYi1oZWFkZXIuY29tcG9uZW50XCI7XHJcbmltcG9ydCB7IFRhYkhlYWRlckJhc2UgfSBmcm9tIFwiLi90YWItaGVhZGVyLmRpcmVjdGl2ZVwiO1xyXG5cclxuY29uc3QgVkVSVElDQUxfVEFCX0hFSUdIVCA9IDY0O1xyXG5cclxuLyoqXHJcbiAqIFZlcnRpY2FsIHRhYiBoZWFkZXIgZ3JvdXA6IHNhbWUgY2hpbGRyZW4gYXMgYGNkcy10YWItaGVhZGVyLWdyb3VwYCwgd2l0aFxyXG4gKiB1cC9kb3duIChhbmQgSG9tZS9FbmQpIGtleXMsIGdyYWRpZW50IG92ZXJmbG93LCBhbmQgYWx3YXlzLWNvbnRhaW5lZCB0eXBlLlxyXG4gKlxyXG4gKlxyXG4gKiBgYGBodG1sXHJcbiAqIDxjZHMtdGFicy12ZXJ0aWNhbC1ncm91cGVkIGhlaWdodD1cIjQwMHB4XCI+XHJcbiAqICAgPGNkcy10YWItaGVhZGVyLWdyb3VwLXZlcnRpY2FsPlxyXG4gKiAgICAgPGNkcy10YWItaGVhZGVyIFtwYW5lUmVmZXJlbmNlXT1cImFcIj5BPC9jZHMtdGFiLWhlYWRlcj5cclxuICogICAgIDxjZHMtdGFiLWhlYWRlciBbcGFuZVJlZmVyZW5jZV09XCJiXCI+QjwvY2RzLXRhYi1oZWFkZXI+XHJcbiAqICAgPC9jZHMtdGFiLWhlYWRlci1ncm91cC12ZXJ0aWNhbD5cclxuICogICA8Y2RzLXRhYiAjYT4uLi48L2Nkcy10YWI+XHJcbiAqICAgPGNkcy10YWIgI2I+Li4uPC9jZHMtdGFiPlxyXG4gKiA8L2Nkcy10YWJzLXZlcnRpY2FsLWdyb3VwZWQ+XHJcbiAqIGBgYFxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcblx0c2VsZWN0b3I6IFwiY2RzLXRhYi1oZWFkZXItZ3JvdXAtdmVydGljYWwsIGlibS10YWItaGVhZGVyLWdyb3VwLXZlcnRpY2FsXCIsXHJcblx0dGVtcGxhdGU6IGBcclxuXHRcdDxkaXYgKm5nSWY9XCJpc092ZXJmbG93aW5nVG9wXCIgY2xhc3M9XCJjZHMtLXRhYi0tbGlzdC1ncmFkaWVudF90b3BcIj48L2Rpdj5cclxuXHRcdDxkaXZcclxuXHRcdFx0I3RhYkxpc3RcclxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRhYi0tbGlzdFwiXHJcblx0XHRcdHJvbGU9XCJ0YWJsaXN0XCJcclxuXHRcdFx0W2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWwgfHwgdHJhbnNsYXRpb25zLkhFQURFUl9BUklBX0xBQkVMXCJcclxuXHRcdFx0W2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cImFyaWFMYWJlbGxlZGJ5IHx8IG51bGxcIj5cclxuXHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50QmVmb3JlXCI+PC9uZy1jb250YWluZXI+XHJcblx0XHRcdDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuXHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50QWZ0ZXJcIj48L25nLWNvbnRhaW5lcj5cclxuXHRcdDwvZGl2PlxyXG5cdFx0PGRpdiAqbmdJZj1cImlzT3ZlcmZsb3dpbmdCb3R0b21cIiBjbGFzcz1cImNkcy0tdGFiLS1saXN0LWdyYWRpZW50X2JvdHRvbVwiPjwvZGl2PlxyXG5cdGBcclxufSlcclxuZXhwb3J0IGNsYXNzIFRhYkhlYWRlckdyb3VwVmVydGljYWxcclxuXHRleHRlbmRzIEJhc2VUYWJIZWFkZXJcclxuXHRpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG5cdC8qKlxyXG5cdCAqIGkxOG4gc3RyaW5ncyBmb3IgdGhlIHRhYiBsaXN0IGBhcmlhLWxhYmVsYCBmYWxsYmFjay5cclxuXHQgKi9cclxuXHRASW5wdXQoKSB0cmFuc2xhdGlvbnMgPSB0aGlzLmkxOG4uZ2V0KCkuVEFCUztcclxuXHJcblx0LyoqXHJcblx0ICogV2hlbiBgdHJ1ZWAsIHNldHMgZWFjaCB0YWIgcGFuZWwgYHRhYmluZGV4YCB0byBgLTFgIGZvciBuYXZpZ2F0aW9uLXN0eWxlIHVzYWdlLlxyXG5cdCAqL1xyXG5cdEBJbnB1dCgpIGlzTmF2aWdhdGlvbiA9IGZhbHNlO1xyXG5cclxuXHQvKipcclxuXHQgKiBGaXJlcyB3aXRoIHRhYiBpbmRleCB3aGVuIGEgY2xvc2UgY29udHJvbCBpcyB1c2VkICh3aXRoIGBkaXNtaXNzYWJsZWApLlxyXG5cdCAqL1xyXG5cdEBPdXRwdXQoKSB0YWJDbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG5cclxuXHQvKipcclxuXHQgKiBTZXQgdG8gJ3RydWUnIHRvIGhhdmUgdGFicyBhdXRvbWF0aWNhbGx5IGFjdGl2YXRlZCBhbmQgaGF2ZSB0aGVpciBjb250ZW50IGRpc3BsYXllZCB3aGVuIHRoZXkgcmVjZWl2ZSBmb2N1cy5cclxuXHQgKi9cclxuXHRASW5wdXQoKSBmb2xsb3dGb2N1cyA9IHRydWU7XHJcblxyXG5cdC8qKlxyXG5cdCAqIENvbnRlbnRDaGlsZHJlbiBvZiBhbGwgdGhlIHRhYiBoZWFkZXJzIChib3RoIGRpcmVjdGl2ZSBhbmQgY29tcG9uZW50XHJcblx0ICogZm9ybXMg4oCUIHNlZSBgVGFiSGVhZGVyQmFzZWApLlxyXG5cdCAqL1xyXG5cdEBDb250ZW50Q2hpbGRyZW4oVGFiSGVhZGVyQmFzZSkgdGFiSGVhZGVyUXVlcnk6IFF1ZXJ5TGlzdDxUYWJIZWFkZXJCYXNlPjtcclxuXHJcblx0QFZpZXdDaGlsZChcInRhYkxpc3RcIiwgeyBzdGF0aWM6IHRydWUgfSkgaGVhZGVyQ29udGFpbmVyOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcclxuXHJcblx0QEhvc3RCaW5kaW5nKFwiY2xhc3MuY2RzLS10YWJzLS12ZXJ0aWNhbFwiKSB2ZXJ0aWNhbENsYXNzID0gdHJ1ZTtcclxuXHJcblx0LyoqXHJcblx0ICogSW5kZXggb2YgdGhlIHNlbGVjdGVkIHRhYiBmb3Iga2V5Ym9hcmQgbG9naWNcclxuXHQgKi9cclxuXHRjdXJyZW50U2VsZWN0ZWRUYWIgPSAwO1xyXG5cclxuXHQvKipcclxuXHQgKiBGb2N1c2VkIHRhYiBpbmRleCB3aGVuIGBmb2xsb3dGb2N1c2AgaXMgZmFsc2UgKG1hbnVhbCBhY3RpdmF0aW9uKS5cclxuXHQgKi9cclxuXHRhY3RpdmVJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcblxyXG5cdGlzT3ZlcmZsb3dpbmdUb3AgPSBmYWxzZTtcclxuXHRpc092ZXJmbG93aW5nQm90dG9tID0gZmFsc2U7XHJcblxyXG5cdC8qKlxyXG5cdCAqIFdlIHVzZSB0YWxsZXIgcm93cyB3aGVuIGFueSBoZWFkZXIgaGFzIGEgc2Vjb25kYXJ5IGxhYmVsLlxyXG5cdCAqL1xyXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tdGFicy0tdGFsbFwiKSBnZXQgdGFsbENsYXNzKCk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIHRoaXMuaGFzU2Vjb25kYXJ5TGFiZWxUYWJzO1xyXG5cdH1cclxuXHJcblx0Z2V0IGhhc1NlY29uZGFyeUxhYmVsVGFicygpOiBib29sZWFuIHtcclxuXHRcdGlmICghdGhpcy50YWJIZWFkZXJRdWVyeSkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdGhpcy50YWJIZWFkZXJRdWVyeVxyXG5cdFx0XHQudG9BcnJheSgpXHJcblx0XHRcdC5zb21lKChoKSA9PiBoLnNlY29uZGFyeUxhYmVsICE9IG51bGwgJiYgaC5zZWNvbmRhcnlMYWJlbCAhPT0gXCJcIik7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIHNlbGVjdGVkU3Vic2NyaXB0aW9uVHJhY2tlciA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuXHRwcml2YXRlIGNsb3NlU3Vic2NyaXB0aW9uVHJhY2tlciA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuXHJcblx0cHJpdmF0ZSByZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCBudWxsID0gbnVsbDtcclxuXHRwcml2YXRlIGJvdW5kTGlzdFNjcm9sbEhhbmRsZXI6ICgpID0+IHZvaWQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKFxyXG5cdFx0cHJvdGVjdGVkIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXHJcblx0XHRwcm90ZWN0ZWQgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxyXG5cdFx0cHJvdGVjdGVkIGV2ZW50U2VydmljZTogRXZlbnRTZXJ2aWNlLFxyXG5cdFx0cHJvdGVjdGVkIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcblx0XHRwcm90ZWN0ZWQgaTE4bjogSTE4blxyXG5cdCkge1xyXG5cdFx0c3VwZXIoZWxlbWVudFJlZiwgY2hhbmdlRGV0ZWN0b3JSZWYsIGV2ZW50U2VydmljZSwgcmVuZGVyZXIpO1xyXG5cdFx0dGhpcy50eXBlID0gXCJjb250YWluZWRcIjtcclxuXHRcdC8vIENhY2hlIGEgc3RhYmxlIHJlZmVyZW5jZSBmb3IgYWRkL3JlbW92ZUV2ZW50TGlzdGVuZXIuXHJcblx0XHR0aGlzLmJvdW5kTGlzdFNjcm9sbEhhbmRsZXIgPSAoKSA9PiB0aGlzLnVwZGF0ZU92ZXJmbG93U3RhdGUoKTtcclxuXHR9XHJcblxyXG5cdEBIb3N0TGlzdGVuZXIoXCJrZXlkb3duXCIsIFtcIiRldmVudFwiXSlcclxuXHRrZXlib2FyZElucHV0KGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XHJcblx0XHRpZiAoIXRoaXMudGFiSGVhZGVyUXVlcnkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgdGFiSGVhZGVyc0FycmF5ID0gdGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KCk7XHJcblx0XHRjb25zdCBlbmFibGVkSGVhZGVycyA9IHRhYkhlYWRlcnNBcnJheS5maWx0ZXIoKGgpID0+ICFoLmRpc2FibGVkKTtcclxuXHRcdGlmIChlbmFibGVkSGVhZGVycy5sZW5ndGggPT09IDApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHJlZmVyZW5jZUluZGV4ID0gdGhpcy5mb2xsb3dGb2N1c1xyXG5cdFx0XHQ/IHRoaXMuY3VycmVudFNlbGVjdGVkVGFiXHJcblx0XHRcdDogKHRoaXMuYWN0aXZlSW5kZXggIT09IG51bGwgPyB0aGlzLmFjdGl2ZUluZGV4IDogdGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIpO1xyXG5cdFx0Y29uc3QgY3VycmVudEVuYWJsZWRJbmRleCA9IE1hdGgubWF4KDAsIGVuYWJsZWRIZWFkZXJzLmluZGV4T2YodGFiSGVhZGVyc0FycmF5W3JlZmVyZW5jZUluZGV4XSkpO1xyXG5cclxuXHRcdGxldCBuZXh0RW5hYmxlZEluZGV4ID0gY3VycmVudEVuYWJsZWRJbmRleDtcclxuXHRcdGxldCBoYW5kbGVkID0gZmFsc2U7XHJcblxyXG5cdFx0aWYgKGV2ZW50LmtleSA9PT0gXCJBcnJvd0Rvd25cIikge1xyXG5cdFx0XHRuZXh0RW5hYmxlZEluZGV4ID0gKGN1cnJlbnRFbmFibGVkSW5kZXggKyAxKSAlIGVuYWJsZWRIZWFkZXJzLmxlbmd0aDtcclxuXHRcdFx0aGFuZGxlZCA9IHRydWU7XHJcblx0XHR9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gXCJBcnJvd1VwXCIpIHtcclxuXHRcdFx0bmV4dEVuYWJsZWRJbmRleCA9IChlbmFibGVkSGVhZGVycy5sZW5ndGggKyBjdXJyZW50RW5hYmxlZEluZGV4IC0gMSkgJSBlbmFibGVkSGVhZGVycy5sZW5ndGg7XHJcblx0XHRcdGhhbmRsZWQgPSB0cnVlO1xyXG5cdFx0fSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiSG9tZVwiKSB7XHJcblx0XHRcdG5leHRFbmFibGVkSW5kZXggPSAwO1xyXG5cdFx0XHRoYW5kbGVkID0gdHJ1ZTtcclxuXHRcdH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBcIkVuZFwiKSB7XHJcblx0XHRcdG5leHRFbmFibGVkSW5kZXggPSBlbmFibGVkSGVhZGVycy5sZW5ndGggLSAxO1xyXG5cdFx0XHRoYW5kbGVkID0gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoaGFuZGxlZCkge1xyXG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRjb25zdCBuZXh0SGVhZGVyID0gZW5hYmxlZEhlYWRlcnNbbmV4dEVuYWJsZWRJbmRleF07XHJcblx0XHRcdGNvbnN0IG5leHRJbmRleCA9IHRhYkhlYWRlcnNBcnJheS5pbmRleE9mKG5leHRIZWFkZXIpO1xyXG5cclxuXHRcdFx0aWYgKHRoaXMuZm9sbG93Rm9jdXMpIHtcclxuXHRcdFx0XHRuZXh0SGVhZGVyLnNlbGVjdFRhYigpO1xyXG5cdFx0XHRcdHRoaXMuY3VycmVudFNlbGVjdGVkVGFiID0gbmV4dEluZGV4O1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdG5leHRIZWFkZXIuZm9jdXMoKTtcclxuXHRcdFx0XHR0aGlzLmFjdGl2ZUluZGV4ID0gbmV4dEluZGV4O1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoKGV2ZW50LmtleSA9PT0gXCIgXCIgfHwgZXZlbnQua2V5ID09PSBcIlNwYWNlYmFyXCIpICYmICF0aGlzLmZvbGxvd0ZvY3VzKSB7XHJcblx0XHRcdGNvbnN0IGZvY3VzSW5kZXggPSB0aGlzLmFjdGl2ZUluZGV4ICE9PSBudWxsID8gdGhpcy5hY3RpdmVJbmRleCA6IHRoaXMuY3VycmVudFNlbGVjdGVkVGFiO1xyXG5cdFx0XHR0YWJIZWFkZXJzQXJyYXlbZm9jdXNJbmRleF0uc2VsZWN0VGFiKCk7XHJcblx0XHRcdHRoaXMuY3VycmVudFNlbGVjdGVkVGFiID0gZm9jdXNJbmRleDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdEBIb3N0TGlzdGVuZXIoXCJibHVyXCIsIFtcIiRldmVudFwiXSlcclxuXHRoYW5kbGVCbHVyKGV2ZW50OiBGb2N1c0V2ZW50KSB7XHJcblx0XHRjb25zdCByZWxhdGVkVGFyZ2V0ID0gZXZlbnQucmVsYXRlZFRhcmdldCBhcyBOb2RlIHwgbnVsbDtcclxuXHRcdGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuaGVhZGVyQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50O1xyXG5cdFx0aWYgKGNvbnRhaW5lciAmJiByZWxhdGVkVGFyZ2V0ICYmIGNvbnRhaW5lci5jb250YWlucyhyZWxhdGVkVGFyZ2V0KSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRpZiAoIXRoaXMuZm9sbG93Rm9jdXMpIHtcclxuXHRcdFx0dGhpcy5hY3RpdmVJbmRleCA9IHRoaXMuY3VycmVudFNlbGVjdGVkVGFiO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0bmdPbkluaXQoKSB7XHJcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcclxuXHRcdFx0dGhpcy51cGRhdGVPdmVyZmxvd1N0YXRlKCk7XHJcblx0XHRcdHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG5cdFx0fSk7XHJcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5oZWFkZXJDb250YWluZXIubmF0aXZlRWxlbWVudCk7XHJcblx0XHR0aGlzLmhlYWRlckNvbnRhaW5lci5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXHJcblx0XHRcdFwic2Nyb2xsXCIsXHJcblx0XHRcdHRoaXMuYm91bmRMaXN0U2Nyb2xsSGFuZGxlclxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdG5nT25EZXN0cm95KCkge1xyXG5cdFx0dGhpcy5zZWxlY3RlZFN1YnNjcmlwdGlvblRyYWNrZXIudW5zdWJzY3JpYmUoKTtcclxuXHRcdHRoaXMuY2xvc2VTdWJzY3JpcHRpb25UcmFja2VyLnVuc3Vic2NyaWJlKCk7XHJcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyPy51bm9ic2VydmUodGhpcy5oZWFkZXJDb250YWluZXIubmF0aXZlRWxlbWVudCk7XHJcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyID0gbnVsbDtcclxuXHRcdHRoaXMuaGVhZGVyQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcclxuXHRcdFx0XCJzY3JvbGxcIixcclxuXHRcdFx0dGhpcy5ib3VuZExpc3RTY3JvbGxIYW5kbGVyXHJcblx0XHQpO1xyXG5cdH1cclxuXHJcblx0bmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG5cdFx0Ly8gUmVhbGxvY2F0ZSB0cmFja2VycyBiZWNhdXNlIHN1YnNjcmlwdGlvbnMgYXJlIHBlcm1hbmVudGx5IGNsb3NlZCBhZnRlciB1bnN1YnNjcmliZVxyXG5cdFx0dGhpcy5zZWxlY3RlZFN1YnNjcmlwdGlvblRyYWNrZXIudW5zdWJzY3JpYmUoKTtcclxuXHRcdHRoaXMuY2xvc2VTdWJzY3JpcHRpb25UcmFja2VyLnVuc3Vic2NyaWJlKCk7XHJcblx0XHR0aGlzLnNlbGVjdGVkU3Vic2NyaXB0aW9uVHJhY2tlciA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuXHRcdHRoaXMuY2xvc2VTdWJzY3JpcHRpb25UcmFja2VyID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG5cclxuXHRcdHRoaXMuYXBwbHlIZWFkZXJJbnB1dHMoKTtcclxuXHRcdHRoaXMud2lyZVN1YnNjcmlwdGlvbnMoKTtcclxuXHJcblx0XHR0aGlzLnRhYkhlYWRlclF1ZXJ5LmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcclxuXHRcdFx0Ly8gUmUtd2lyZSB3aGVuIHRoZSBwcm9qZWN0ZWQgbGlzdCBjaGFuZ2VzLlxyXG5cdFx0XHR0aGlzLnNlbGVjdGVkU3Vic2NyaXB0aW9uVHJhY2tlci51bnN1YnNjcmliZSgpO1xyXG5cdFx0XHR0aGlzLmNsb3NlU3Vic2NyaXB0aW9uVHJhY2tlci51bnN1YnNjcmliZSgpO1xyXG5cdFx0XHR0aGlzLnNlbGVjdGVkU3Vic2NyaXB0aW9uVHJhY2tlciA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuXHRcdFx0dGhpcy5jbG9zZVN1YnNjcmlwdGlvblRyYWNrZXIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XHJcblx0XHRcdHRoaXMuYXBwbHlIZWFkZXJJbnB1dHMoKTtcclxuXHRcdFx0dGhpcy53aXJlU3Vic2NyaXB0aW9ucygpO1xyXG5cdFx0XHR0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRcdGNvbnN0IGhlYWRlcnMgPSB0aGlzLnRhYkhlYWRlclF1ZXJ5LnRvQXJyYXkoKTtcclxuXHRcdFx0Y29uc3QgYWN0aXZlSWR4ID0gaGVhZGVycy5maW5kSW5kZXgoaCA9PiBoLmFjdGl2ZSB8fCBoLnBhbmVSZWZlcmVuY2U/LmFjdGl2ZSk7XHJcblx0XHRcdGNvbnN0IGluaXRpYWxJbmRleCA9IGFjdGl2ZUlkeCA+PSAwID8gYWN0aXZlSWR4IDogMDtcclxuXHRcdFx0dGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgPSBpbml0aWFsSW5kZXg7XHJcblx0XHRcdHRoaXMuYWN0aXZlSW5kZXggPSBpbml0aWFsSW5kZXg7XHJcblx0XHRcdGhlYWRlcnNbaW5pdGlhbEluZGV4XT8uc2VsZWN0VGFiKCk7XHJcblx0XHRcdHRoaXMudXBkYXRlT3ZlcmZsb3dTdGF0ZSgpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcblx0XHRpZiAodGhpcy50YWJIZWFkZXJRdWVyeSkge1xyXG5cdFx0XHRpZiAoY2hhbmdlcy5jYWNoZUFjdGl2ZSkge1xyXG5cdFx0XHRcdHRoaXMudGFiSGVhZGVyUXVlcnkudG9BcnJheSgpLmZvckVhY2goaCA9PiBoLmNhY2hlQWN0aXZlID0gdGhpcy5jYWNoZUFjdGl2ZSk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKGNoYW5nZXMuZGlzbWlzc2FibGUpIHtcclxuXHRcdFx0XHR0aGlzLnRhYkhlYWRlclF1ZXJ5LnRvQXJyYXkoKS5mb3JFYWNoKGggPT4gaC5kaXNtaXNzYWJsZSA9IHRoaXMuZGlzbWlzc2FibGUpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChjaGFuZ2VzLmlzTmF2aWdhdGlvbikge1xyXG5cdFx0XHRcdHRoaXMudGFiSGVhZGVyUXVlcnkudG9BcnJheSgpXHJcblx0XHRcdFx0XHQuZm9yRWFjaChoID0+IGgucGFuZVRhYkluZGV4ID0gdGhpcy5pc05hdmlnYXRpb24gPyBudWxsIDogMCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCB1cGRhdGVPdmVyZmxvd1N0YXRlKCkge1xyXG5cdFx0Y29uc3QgZWxlbWVudCA9IHRoaXMuaGVhZGVyQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50O1xyXG5cdFx0aWYgKCFlbGVtZW50KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGhhbGZUYWJIZWlnaHQgPSBWRVJUSUNBTF9UQUJfSEVJR0hUIC8gMjtcclxuXHRcdHRoaXMuaXNPdmVyZmxvd2luZ0JvdHRvbSA9XHJcblx0XHRcdGVsZW1lbnQuc2Nyb2xsVG9wICsgZWxlbWVudC5jbGllbnRIZWlnaHQgKyBoYWxmVGFiSGVpZ2h0IDw9IGVsZW1lbnQuc2Nyb2xsSGVpZ2h0O1xyXG5cdFx0dGhpcy5pc092ZXJmbG93aW5nVG9wID0gZWxlbWVudC5zY3JvbGxUb3AgPiBoYWxmVGFiSGVpZ2h0O1xyXG5cdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBzY3JvbGxTZWxlY3RlZFRhYkludG9WaWV3KCkge1xyXG5cdFx0aWYgKCF0aGlzLnNjcm9sbEludG9WaWV3KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuaGVhZGVyQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50O1xyXG5cdFx0aWYgKCFjb250YWluZXIpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0Y29udGFpbmVyLnNjcm9sbFRvKHtcclxuXHRcdFx0dG9wOiBNYXRoLm1heCgwLCAodGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgLSAxKSAqIFZFUlRJQ0FMX1RBQl9IRUlHSFQpLFxyXG5cdFx0XHRiZWhhdmlvcjogXCJzbW9vdGhcIlxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGFwcGx5SGVhZGVySW5wdXRzKCkge1xyXG5cdFx0dGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KCkuZm9yRWFjaCgoaGVhZGVyKSA9PiB7XHJcblx0XHRcdGhlYWRlci5jYWNoZUFjdGl2ZSA9IHRoaXMuY2FjaGVBY3RpdmU7XHJcblx0XHRcdGhlYWRlci5kaXNtaXNzYWJsZSA9IHRoaXMuZGlzbWlzc2FibGU7XHJcblx0XHRcdGhlYWRlci5wYW5lVGFiSW5kZXggPSB0aGlzLmlzTmF2aWdhdGlvbiA/IG51bGwgOiAwO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIHdpcmVTdWJzY3JpcHRpb25zKCkge1xyXG5cdFx0dGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KCkuZm9yRWFjaCgoaGVhZGVyKSA9PiB7XHJcblx0XHRcdHRoaXMuc2VsZWN0ZWRTdWJzY3JpcHRpb25UcmFja2VyLmFkZChcclxuXHRcdFx0XHRoZWFkZXIuc2VsZWN0ZWQuc3Vic2NyaWJlKCgpID0+IHtcclxuXHRcdFx0XHRcdHRoaXMuY3VycmVudFNlbGVjdGVkVGFiID0gdGhpcy50YWJIZWFkZXJRdWVyeVxyXG5cdFx0XHRcdFx0XHQudG9BcnJheSgpXHJcblx0XHRcdFx0XHRcdC5pbmRleE9mKGhlYWRlcik7XHJcblx0XHRcdFx0XHR0aGlzLnRhYkhlYWRlclF1ZXJ5XHJcblx0XHRcdFx0XHRcdC50b0FycmF5KClcclxuXHRcdFx0XHRcdFx0LmZpbHRlcigoaCkgPT4gaCAhPT0gaGVhZGVyKVxyXG5cdFx0XHRcdFx0XHQuZm9yRWFjaCgob3RoZXIpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRvdGhlci5hY3RpdmUgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0XHRpZiAob3RoZXIucGFuZVJlZmVyZW5jZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0b3RoZXIucGFuZVJlZmVyZW5jZS5hY3RpdmUgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0dGhpcy5zY3JvbGxTZWxlY3RlZFRhYkludG9WaWV3KCk7XHJcblx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRcdHRoaXMuY2xvc2VTdWJzY3JpcHRpb25UcmFja2VyLmFkZChcclxuXHRcdFx0XHRoZWFkZXIudGFiQ2xvc2Uuc3Vic2NyaWJlKCgpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IGluZGV4ID0gdGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KCkuaW5kZXhPZihoZWFkZXIpO1xyXG5cdFx0XHRcdFx0dGhpcy50YWJDbG9zZS5lbWl0KGluZGV4KTtcclxuXHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG59XHJcbiJdfQ==