@visa/nova-angular
Version:
Visa Product Design System Nova Angular library
395 lines • 47.3 kB
JavaScript
/**
* © 2025 Visa
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { ChangeDetectorRef, ContentChildren, Directive, forwardRef, HostBinding, HostListener, Input, QueryList } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { AppReadyService } from '../_utilities/services/app-stable-check.service';
import { UUIDService } from '../_utilities/services/uuid.service';
import { CheckboxDirective } from '../checkbox/checkbox.directive';
import { RadioDirective } from '../radio/radio.directive';
import { ToggleButtonDirective } from '../toggle-button/toggle-button.directive';
import * as i0 from "@angular/core";
import * as i1 from "../_utilities/services/uuid.service";
import * as i2 from "../_utilities/services/app-stable-check.service";
export class ToggleContainerDirective {
get hostClasses() {
return this.class;
}
/**
* Allows multiple buttons to be selected when true. <br />
* To be used with child Button components, not Radio or Checkbox.
* @default false
*/
get multiselect() {
return this._multiselect;
}
set multiselect(value) {
this._multiselect = coerceBooleanProperty(value);
}
/**
* Sets component as disabled when true.
* @default false
*/
get disabled() {
return this._disabled;
}
set disabled(value) {
this._disabled = coerceBooleanProperty(value);
this.informDisabledState();
}
get hostDisabled() {
return this.disabled ? 'disabled' : null;
}
/** Fires when a formControl's disabled state updates. */
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
/**
* Marks component as invalid when true.
* @default false
*/
get invalid() {
return this._invalid;
}
set invalid(value) {
this._invalid = coerceBooleanProperty(value);
}
get ariaInvalid() {
return this.invalid;
}
/**
* Marks component as required when true.
* @default false
*/
get required() {
return this._required;
}
set required(value) {
this._required = coerceBooleanProperty(value);
}
/**
* Value of toggle button.
*/
get value() {
return this._value;
}
set value(value) {
let tempValue = value;
// convert single value to array if multiselect
if ((this.multiselect || this.checkboxes?.length > 0) && tempValue && !Array.isArray(tempValue)) {
tempValue = [tempValue];
}
this._value = tempValue;
if ((this.multiselect && this.value?.length === 0) || !this._value) {
this.clear();
}
else {
this.updateValue(this._value);
}
this.onChange(this.value);
this.onTouched(this.value);
}
updateValue(value) {
if (this.multiselect) {
if (this.buttons?.length > 0) {
// if the active buttons do not reflect the new value..
if (this.buttons.filter((b) => b.active).map((b) => b.value) != this.value) {
// update them
this.buttons.forEach((button) => {
button.active = value.includes(button.value);
});
}
}
else if (this.checkboxes?.length > 0) {
// if the checked checkboxes do not reflect the new value..
if (this.checkboxes.filter((c) => c.checked).map((c) => c.checkboxValue) != value) {
// update them
this.checkboxes.forEach((checkbox) => {
this.updateCheckboxRadioVal(checkbox, value.includes(checkbox.checkboxValue));
});
}
}
}
else {
if (this.buttons?.length > 0) {
// if the active button does not reflect the new value..
if (this.buttons.find((b) => b.active)?.value != value) {
// update it
this.buttons.forEach((button) => {
button.active = button.value === value;
});
}
}
else if (this.radios?.length > 0) {
// if the checked radio does not reflect the new value..
if (this.radios.find((r) => r.checked)?.radioValue != value) {
// update it
this.radios.forEach((radio) => {
this.updateCheckboxRadioVal(radio, radio.radioValue === value);
});
}
}
}
this.onChange(this.value);
}
constructor(uuidService, cdRef, appReadyService) {
this.uuidService = uuidService;
this.cdRef = cdRef;
this.appReadyService = appReadyService;
/**
* Sets custom name.
* @default this.uuidService.getUUID('v-toggle-');
* @builtin true
*/
this.name = this.uuidService.getUUID('v-toggle-');
/**
* Provides custom class(es) for custom styling.
* @default .v-toggle-container
*/
this.class = 'v-toggle-container';
this._multiselect = false;
this._disabled = false;
this._invalid = false;
this._required = false;
this.onChange = (_) => { };
this.onTouched = (_) => { };
}
ngAfterContentInit() {
this.multiselect = this.multiselect ? this.multiselect : this.checkboxes?.length > 0 ? true : false;
if (this.value) {
this.writeValue(this.value);
}
if (this.disabled) {
this.informDisabledState();
}
if (this.buttons && this.buttons.length > 0) {
this.setUpButtons();
this.buttons.changes.subscribe(() => {
this.unsubscribeFromListeners(this.buttons);
this.setUpButtons();
this.cdRef.detectChanges();
});
}
if (this.radios && this.radios.length > 0) {
// single select, using radios
this.setUpRadios();
this.radios.changes.subscribe(() => {
this.unsubscribeFromListeners(this.radios);
this.setUpRadios();
this.cdRef.detectChanges();
});
}
if (this.checkboxes && this.checkboxes.length > 0) {
// multiselect, using checkboxes
this.setUpCheckboxes();
this.checkboxes.changes.subscribe(() => {
this.unsubscribeFromListeners(this.checkboxes);
this.setUpCheckboxes();
this.cdRef.detectChanges();
});
}
}
handleBlur(event) {
this.onTouched(event);
}
setUpButtons() {
this.buttons.forEach((button) => {
button.listeners.push(button.clicked.subscribe(() => {
if (this.multiselect) {
button.active = !button.active;
const tempValue = this.value || [];
if (button.active) {
this.value = [...tempValue, button.value];
}
else {
this.value = tempValue.filter((v) => v !== button.value);
}
}
else {
if (this.value === button.value)
return;
this.buttons.forEach((b) => {
b.active = false;
});
button.active = true;
this.value = button.value;
}
}));
});
// find active buttons and set value
const activeValues = this.buttons.filter((b) => b.active).map((b) => b.value);
if (this.multiselect && this.value !== activeValues) {
this.value = activeValues;
}
else if (!this.multiselect && this.value !== activeValues[0]) {
this.value = activeValues[0];
}
}
setUpRadios() {
this.radios.forEach((radio) => {
radio.radioValue = radio.radioValue ? radio.radioValue : this.uuidService.getUUID('v-radio-');
radio.name = radio.name ? radio.name : this.name;
// find checked radio buttons and set value
radio.listeners.push(radio.clicked.subscribe(() => {
if (this.value !== radio.radioValue) {
this.value = radio.radioValue;
}
}));
});
const activeValues = this.radios.find((r) => r.checked);
if (activeValues && this.value !== activeValues.radioValue) {
this.value = activeValues.radioValue;
}
}
setUpCheckboxes() {
this.checkboxes.forEach((checkbox) => {
checkbox.checkboxValue = checkbox.checkboxValue
? checkbox.checkboxValue
: this.uuidService.getUUID('v-checkbox-');
checkbox.listeners.push(checkbox.clicked.subscribe((event) => {
if (event.target.checked) {
// add value
this.value = [...this.value, checkbox.checkboxValue];
}
else {
// remove value
this.value = this.value.filter((v) => v !== checkbox.checkboxValue);
}
}));
});
// find checked checkboxes and set value
const activeValues = this.checkboxes.filter((c) => c.checked).map((c) => c.checkboxValue);
if (activeValues && this.value !== activeValues) {
this.value = activeValues;
}
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
writeValue(value) {
this.value = value;
}
clear() {
// clear value from radio and visual check
this.radios?.forEach((radio) => {
this.updateCheckboxRadioVal(radio);
});
this.checkboxes?.forEach((checkbox) => {
this.updateCheckboxRadioVal(checkbox);
});
this.buttons?.forEach((button) => {
button.active = false;
});
if (this.multiselect && this.value && this.value.length > 0) {
this.value = [];
}
else if (this.value) {
this.value = null;
}
}
updateCheckboxRadioVal(item, checked = false) {
item.checked = checked;
if (this.appReadyService.isBrowserAndDomAvailable()) {
item.el.nativeElement.checked = checked;
}
}
unsubscribeFromListeners(items) {
items.forEach((item) => {
item.listeners.forEach((sub) => {
sub.unsubscribe();
});
});
}
informDisabledState() {
if (this.buttons) {
this.buttons.forEach((button) => {
button.disabled = this.disabled;
});
}
if (this.radios) {
this.radios.forEach((radio) => {
radio.disabled = this.disabled;
});
}
if (this.checkboxes) {
this.checkboxes.forEach((checkbox) => {
checkbox.disabled = this.disabled;
});
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ToggleContainerDirective, deps: [{ token: i1.UUIDService }, { token: i0.ChangeDetectorRef }, { token: i2.AppReadyService }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ToggleContainerDirective, isStandalone: true, selector: "[v-toggle-container]", inputs: { name: "name", class: "class", multiselect: "multiselect", disabled: "disabled", invalid: "invalid", required: "required", value: "value" }, host: { listeners: { "blur": "handleBlur($event)" }, properties: { "class": "this.hostClasses", "disabled": "this.hostDisabled", "attr.aria-invalid": "this.ariaInvalid" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ToggleContainerDirective),
multi: true
}
], queries: [{ propertyName: "radios", predicate: RadioDirective, descendants: true }, { propertyName: "checkboxes", predicate: CheckboxDirective, descendants: true }, { propertyName: "buttons", predicate: ToggleButtonDirective, descendants: true }], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ToggleContainerDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: '[v-toggle-container]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ToggleContainerDirective),
multi: true
}
]
}]
}], ctorParameters: () => [{ type: i1.UUIDService }, { type: i0.ChangeDetectorRef }, { type: i2.AppReadyService }], propDecorators: { radios: [{
type: ContentChildren,
args: [RadioDirective, { descendants: true }]
}], checkboxes: [{
type: ContentChildren,
args: [CheckboxDirective, { descendants: true }]
}], buttons: [{
type: ContentChildren,
args: [ToggleButtonDirective, { descendants: true }]
}], name: [{
type: Input
}], class: [{
type: Input
}], hostClasses: [{
type: HostBinding,
args: ['class']
}], multiselect: [{
type: Input
}], disabled: [{
type: Input
}], hostDisabled: [{
type: HostBinding,
args: ['disabled']
}], invalid: [{
type: Input
}], ariaInvalid: [{
type: HostBinding,
args: ['attr.aria-invalid']
}], required: [{
type: Input
}], value: [{
type: Input
}], handleBlur: [{
type: HostListener,
args: ['blur', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9nZ2xlLWNvbnRhaW5lci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25vdmEtbGliL3NyYy9saWIvdG9nZ2xlLWNvbnRhaW5lci90b2dnbGUtY29udGFpbmVyLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQWdCLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUUsT0FBTyxFQUVMLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFDTCxTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUNsRixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7O0FBYWpGLE1BQU0sT0FBTyx3QkFBd0I7SUFvQm5DLElBQ0ksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQ0ksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBQ0QsSUFBSSxXQUFXLENBQUMsS0FBbUI7UUFDakMsSUFBSSxDQUFDLFlBQVksR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBR0Q7OztPQUdHO0lBQ0gs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ZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKiovXG5pbXBvcnQgeyBCb29sZWFuSW5wdXQsIGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29udGVudENoaWxkcmVuLFxuICBEaXJlY3RpdmUsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBRdWVyeUxpc3Rcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBBcHBSZWFkeVNlcnZpY2UgfSBmcm9tICcuLi9fdXRpbGl0aWVzL3NlcnZpY2VzL2FwcC1zdGFibGUtY2hlY2suc2VydmljZSc7XG5pbXBvcnQgeyBVVUlEU2VydmljZSB9IGZyb20gJy4uL191dGlsaXRpZXMvc2VydmljZXMvdXVpZC5zZXJ2aWNlJztcbmltcG9ydCB7IENoZWNrYm94RGlyZWN0aXZlIH0gZnJvbSAnLi4vY2hlY2tib3gvY2hlY2tib3guZGlyZWN0aXZlJztcbmltcG9ydCB7IFJhZGlvRGlyZWN0aXZlIH0gZnJvbSAnLi4vcmFkaW8vcmFkaW8uZGlyZWN0aXZlJztcbmltcG9ydCB7IFRvZ2dsZUJ1dHRvbkRpcmVjdGl2ZSB9IGZyb20gJy4uL3RvZ2dsZS1idXR0b24vdG9nZ2xlLWJ1dHRvbi5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2VsZWN0b3I6ICdbdi10b2dnbGUtY29udGFpbmVyXScsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gVG9nZ2xlQ29udGFpbmVyRGlyZWN0aXZlKSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFRvZ2dsZUNvbnRhaW5lckRpcmVjdGl2ZSBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBBZnRlckNvbnRlbnRJbml0IHtcbiAgQENvbnRlbnRDaGlsZHJlbihSYWRpb0RpcmVjdGl2ZSwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KVxuICByYWRpb3M6IFF1ZXJ5TGlzdDxSYWRpb0RpcmVjdGl2ZT47XG4gIEBDb250ZW50Q2hpbGRyZW4oQ2hlY2tib3hEaXJlY3RpdmUsIHsgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgY2hlY2tib3hlczogUXVlcnlMaXN0PENoZWNrYm94RGlyZWN0aXZlPjtcbiAgQENvbnRlbnRDaGlsZHJlbihUb2dnbGVCdXR0b25EaXJlY3RpdmUsIHsgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgYnV0dG9uczogUXVlcnlMaXN0PFRvZ2dsZUJ1dHRvbkRpcmVjdGl2ZT47XG5cbiAgLyoqXG4gICAqIFNldHMgY3VzdG9tIG5hbWUuXG4gICAqIEBkZWZhdWx0IHRoaXMudXVpZFNlcnZpY2UuZ2V0VVVJRCgndi10b2dnbGUtJyk7XG4gICAqIEBidWlsdGluIHRydWVcbiAgICovXG4gIEBJbnB1dCgpIG5hbWU6IHN0cmluZyA9IHRoaXMudXVpZFNlcnZpY2UuZ2V0VVVJRCgndi10b2dnbGUtJyk7XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIGN1c3RvbSBjbGFzcyYjNDA7ZXMmIzQxOyBmb3IgY3VzdG9tIHN0eWxpbmcuXG4gICAqIEBkZWZhdWx0IC52LXRvZ2dsZS1jb250YWluZXJcbiAgICovXG4gIEBJbnB1dCgpIGNsYXNzOiBzdHJpbmcgPSAndi10b2dnbGUtY29udGFpbmVyJztcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpXG4gIGdldCBob3N0Q2xhc3NlcygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNsYXNzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbG93cyBtdWx0aXBsZSBidXR0b25zIHRvIGJlIHNlbGVjdGVkIHdoZW4gdHJ1ZS4gPGJyIC8+XG4gICAqIFRvIGJlIHVzZWQgd2l0aCBjaGlsZCBCdXR0b24gY29tcG9uZW50cywgbm90IFJhZGlvIG9yIENoZWNrYm94LlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IG11bHRpc2VsZWN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9tdWx0aXNlbGVjdDtcbiAgfVxuICBzZXQgbXVsdGlzZWxlY3QodmFsdWU6IEJvb2xlYW5JbnB1dCkge1xuICAgIHRoaXMuX211bHRpc2VsZWN0ID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBfbXVsdGlzZWxlY3Q6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogU2V0cyBjb21wb25lbnQgYXMgZGlzYWJsZWQgd2hlbiB0cnVlLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9kaXNhYmxlZDtcbiAgfVxuICBzZXQgZGlzYWJsZWQodmFsdWU6IEJvb2xlYW5JbnB1dCkge1xuICAgIHRoaXMuX2Rpc2FibGVkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgICB0aGlzLmluZm9ybURpc2FibGVkU3RhdGUoKTtcbiAgfVxuICBfZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQEhvc3RCaW5kaW5nKCdkaXNhYmxlZCcpXG4gIGdldCBob3N0RGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQgPyAnZGlzYWJsZWQnIDogbnVsbDtcbiAgfVxuICAvKiogRmlyZXMgd2hlbiBhIGZvcm1Db250cm9sJ3MgZGlzYWJsZWQgc3RhdGUgdXBkYXRlcy4gICovXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICB9XG4gIC8qKlxuICAgKiBNYXJrcyBjb21wb25lbnQgYXMgaW52YWxpZCB3aGVuIHRydWUuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgaW52YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faW52YWxpZDtcbiAgfVxuICBzZXQgaW52YWxpZCh2YWx1ZTogQm9vbGVhbklucHV0KSB7XG4gICAgdGhpcy5faW52YWxpZCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gIH1cbiAgX2ludmFsaWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtaW52YWxpZCcpXG4gIGdldCBhcmlhSW52YWxpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnZhbGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hcmtzIGNvbXBvbmVudCBhcyByZXF1aXJlZCB3aGVuIHRydWUuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgcmVxdWlyZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlcXVpcmVkO1xuICB9XG4gIHNldCByZXF1aXJlZCh2YWx1ZTogQm9vbGVhbklucHV0KSB7XG4gICAgdGhpcy5fcmVxdWlyZWQgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICB9XG4gIF9yZXF1aXJlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBWYWx1ZSBvZiB0b2dnbGUgYnV0dG9uLlxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IHZhbHVlKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgfVxuICBzZXQgdmFsdWUodmFsdWU6IChzdHJpbmcgfCBudW1iZXIpW10gfCBzdHJpbmcgfCBudW1iZXIgfCBudWxsKSB7XG4gICAgbGV0IHRlbXBWYWx1ZSA9IHZhbHVlO1xuICAgIC8vIGNvbnZlcnQgc2luZ2xlIHZhbHVlIHRvIGFycmF5IGlmIG11bHRpc2VsZWN0XG4gICAgaWYgKCh0aGlzLm11bHRpc2VsZWN0IHx8IHRoaXMuY2hlY2tib3hlcz8ubGVuZ3RoID4gMCkgJiYgdGVtcFZhbHVlICYmICFBcnJheS5pc0FycmF5KHRlbXBWYWx1ZSkpIHtcbiAgICAgIHRlbXBWYWx1ZSA9IFt0ZW1wVmFsdWVdO1xuICAgIH1cbiAgICB0aGlzLl92YWx1ZSA9IHRlbXBWYWx1ZTtcbiAgICBpZiAoKHRoaXMubXVsdGlzZWxlY3QgJiYgKHRoaXMudmFsdWUgYXMgKHN0cmluZyB8IG51bWJlcilbXSk/Lmxlbmd0aCA9PT0gMCkgfHwgIXRoaXMuX3ZhbHVlKSB7XG4gICAgICB0aGlzLmNsZWFyKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlVmFsdWUodGhpcy5fdmFsdWUpO1xuICAgIH1cblxuICAgIHRoaXMub25DaGFuZ2UodGhpcy52YWx1ZSk7XG4gICAgdGhpcy5vblRvdWNoZWQodGhpcy52YWx1ZSk7XG4gIH1cbiAgX3ZhbHVlOiAoc3RyaW5nIHwgbnVtYmVyKVtdIHwgc3RyaW5nIHwgbnVtYmVyIHwgbnVsbDtcblxuICB1cGRhdGVWYWx1ZSh2YWx1ZTogKHN0cmluZyB8IG51bWJlcilbXSB8IHN0cmluZyB8IG51bWJlciB8IG51bGwpIHtcbiAgICBpZiAodGhpcy5tdWx0aXNlbGVjdCkge1xuICAgICAgaWYgKHRoaXMuYnV0dG9ucz8ubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBpZiB0aGUgYWN0aXZlIGJ1dHRvbnMgZG8gbm90IHJlZmxlY3QgdGhlIG5ldyB2YWx1ZS4uXG4gICAgICAgIGlmICh0aGlzLmJ1dHRvbnMuZmlsdGVyKChiKSA9PiBiLmFjdGl2ZSkubWFwKChiKSA9PiBiLnZhbHVlKSAhPSAodGhpcy52YWx1ZSBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdKSkge1xuICAgICAgICAgIC8vIHVwZGF0ZSB0aGVtXG4gICAgICAgICAgdGhpcy5idXR0b25zLmZvckVhY2goKGJ1dHRvbikgPT4ge1xuICAgICAgICAgICAgYnV0dG9uLmFjdGl2ZSA9ICh2YWx1ZSBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdKS5pbmNsdWRlcyhidXR0b24udmFsdWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY2hlY2tib3hlcz8ubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBpZiB0aGUgY2hlY2tlZCBjaGVja2JveGVzIGRvIG5vdCByZWZsZWN0IHRoZSBuZXcgdmFsdWUuLlxuICAgICAgICBpZiAodGhpcy5jaGVja2JveGVzLmZpbHRlcigoYykgPT4gYy5jaGVja2VkKS5tYXAoKGMpID0+IGMuY2hlY2tib3hWYWx1ZSkgIT0gKHZhbHVlIGFzIChzdHJpbmcgfCBudW1iZXIpW10pKSB7XG4gICAgICAgICAgLy8gdXBkYXRlIHRoZW1cbiAgICAgICAgICB0aGlzLmNoZWNrYm94ZXMuZm9yRWFjaCgoY2hlY2tib3gpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ2hlY2tib3hSYWRpb1ZhbChjaGVja2JveCwgKHZhbHVlIGFzIChzdHJpbmcgfCBudW1iZXIpW10pLmluY2x1ZGVzKGNoZWNrYm94LmNoZWNrYm94VmFsdWUpKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5idXR0b25zPy5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIGlmIHRoZSBhY3RpdmUgYnV0dG9uIGRvZXMgbm90IHJlZmxlY3QgdGhlIG5ldyB2YWx1ZS4uXG4gICAgICAgIGlmICh0aGlzLmJ1dHRvbnMuZmluZCgoYikgPT4gYi5hY3RpdmUpPy52YWx1ZSAhPSAodmFsdWUgYXMgc3RyaW5nIHwgbnVtYmVyKSkge1xuICAgICAgICAgIC8vIHVwZGF0ZSBpdFxuICAgICAgICAgIHRoaXMuYnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgICAgICAgIGJ1dHRvbi5hY3RpdmUgPSBidXR0b24udmFsdWUgPT09IHZhbHVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMucmFkaW9zPy5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIGlmIHRoZSBjaGVja2VkIHJhZGlvIGRvZXMgbm90IHJlZmxlY3QgdGhlIG5ldyB2YWx1ZS4uXG4gICAgICAgIGlmICh0aGlzLnJhZGlvcy5maW5kKChyKSA9PiByLmNoZWNrZWQpPy5yYWRpb1ZhbHVlICE9ICh2YWx1ZSBhcyBzdHJpbmcgfCBudW1iZXIpKSB7XG4gICAgICAgICAgLy8gdXBkYXRlIGl0XG4gICAgICAgICAgdGhpcy5yYWRpb3MuZm9yRWFjaCgocmFkaW8pID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ2hlY2tib3hSYWRpb1ZhbChyYWRpbywgcmFkaW8ucmFkaW9WYWx1ZSA9PT0gdmFsdWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMub25DaGFuZ2UodGhpcy52YWx1ZSk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHV1aWRTZXJ2aWNlOiBVVUlEU2VydmljZSxcbiAgICBwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIGFwcFJlYWR5U2VydmljZTogQXBwUmVhZHlTZXJ2aWNlXG4gICkge31cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5tdWx0aXNlbGVjdCA9IHRoaXMubXVsdGlzZWxlY3QgPyB0aGlzLm11bHRpc2VsZWN0IDogdGhpcy5jaGVja2JveGVzPy5sZW5ndGggPiAwID8gdHJ1ZSA6IGZhbHNlO1xuICAgIGlmICh0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLndyaXRlVmFsdWUodGhpcy52YWx1ZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aGlzLmluZm9ybURpc2FibGVkU3RhdGUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuYnV0dG9ucyAmJiB0aGlzLmJ1dHRvbnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZXRVcEJ1dHRvbnMoKTtcblxuICAgICAgdGhpcy5idXR0b25zLmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZUZyb21MaXN0ZW5lcnModGhpcy5idXR0b25zKTtcbiAgICAgICAgdGhpcy5zZXRVcEJ1dHRvbnMoKTtcbiAgICAgICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHRoaXMucmFkaW9zICYmIHRoaXMucmFkaW9zLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIHNpbmdsZSBzZWxlY3QsIHVzaW5nIHJhZGlvc1xuICAgICAgdGhpcy5zZXRVcFJhZGlvcygpO1xuXG4gICAgICB0aGlzLnJhZGlvcy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMudW5zdWJzY3JpYmVGcm9tTGlzdGVuZXJzKHRoaXMucmFkaW9zKTtcbiAgICAgICAgdGhpcy5zZXRVcFJhZGlvcygpO1xuICAgICAgICB0aGlzLmNkUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodGhpcy5jaGVja2JveGVzICYmIHRoaXMuY2hlY2tib3hlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBtdWx0aXNlbGVjdCwgdXNpbmcgY2hlY2tib3hlc1xuICAgICAgdGhpcy5zZXRVcENoZWNrYm94ZXMoKTtcblxuICAgICAgdGhpcy5jaGVja2JveGVzLmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZUZyb21MaXN0ZW5lcnModGhpcy5jaGVja2JveGVzKTtcbiAgICAgICAgdGhpcy5zZXRVcENoZWNrYm94ZXMoKTtcbiAgICAgICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdibHVyJywgWyckZXZlbnQnXSlcbiAgaGFuZGxlQmx1cihldmVudDogRXZlbnQpIHtcbiAgICB0aGlzLm9uVG91Y2hlZChldmVudCk7XG4gIH1cblxuICBzZXRVcEJ1dHRvbnMoKSB7XG4gICAgdGhpcy5idXR0b25zLmZvckVhY2goKGJ1dHRvbikgPT4ge1xuICAgICAgYnV0dG9uLmxpc3RlbmVycy5wdXNoKFxuICAgICAgICBidXR0b24uY2xpY2tlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLm11bHRpc2VsZWN0KSB7XG4gICAgICAgICAgICBidXR0b24uYWN0aXZlID0gIWJ1dHRvbi5hY3RpdmU7XG4gICAgICAgICAgICBjb25zdCB0ZW1wVmFsdWUgPSAodGhpcy52YWx1ZSBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdKSB8fCBbXTtcbiAgICAgICAgICAgIGlmIChidXR0b24uYWN0aXZlKSB7XG4gICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbLi4udGVtcFZhbHVlLCBidXR0b24udmFsdWVdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRlbXBWYWx1ZS5maWx0ZXIoKHYpID0+IHYgIT09IGJ1dHRvbi52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZhbHVlID09PSBidXR0b24udmFsdWUpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMuYnV0dG9ucy5mb3JFYWNoKChiKSA9PiB7XG4gICAgICAgICAgICAgIGIuYWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGJ1dHRvbi5hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IGJ1dHRvbi52YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuICAgIC8vIGZpbmQgYWN0aXZlIGJ1dHRvbnMgYW5kIHNldCB2YWx1ZVxuICAgIGNvbnN0IGFjdGl2ZVZhbHVlcyA9IHRoaXMuYnV0dG9ucy5maWx0ZXIoKGIpID0+IGIuYWN0aXZlKS5tYXAoKGIpID0+IGIudmFsdWUpO1xuICAgIGlmICh0aGlzLm11bHRpc2VsZWN0ICYmIHRoaXMudmFsdWUgIT09IGFjdGl2ZVZhbHVlcykge1xuICAgICAgdGhpcy52YWx1ZSA9IGFjdGl2ZVZhbHVlcztcbiAgICB9IGVsc2UgaWYgKCF0aGlzLm11bHRpc2VsZWN0ICYmIHRoaXMudmFsdWUgIT09IGFjdGl2ZVZhbHVlc1swXSkge1xuICAgICAgdGhpcy52YWx1ZSA9IGFjdGl2ZVZhbHVlc1swXTtcbiAgICB9XG4gIH1cblxuICBzZXRVcFJhZGlvcygpIHtcbiAgICB0aGlzLnJhZGlvcy5mb3JFYWNoKChyYWRpbykgPT4ge1xuICAgICAgcmFkaW8ucmFkaW9WYWx1ZSA9IHJhZGlvLnJhZGlvVmFsdWUgPyByYWRpby5yYWRpb1ZhbHVlIDogdGhpcy51dWlkU2VydmljZS5nZXRVVUlEKCd2LXJhZGlvLScpO1xuICAgICAgcmFkaW8ubmFtZSA9IHJhZGlvLm5hbWUgPyByYWRpby5uYW1lIDogdGhpcy5uYW1lO1xuICAgICAgLy8gZmluZCBjaGVja2VkIHJhZGlvIGJ1dHRvbnMgYW5kIHNldCB2YWx1ZVxuICAgICAgcmFkaW8ubGlzdGVuZXJzLnB1c2goXG4gICAgICAgIHJhZGlvLmNsaWNrZWQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy52YWx1ZSAhPT0gcmFkaW8ucmFkaW9WYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHJhZGlvLnJhZGlvVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgICBjb25zdCBhY3RpdmVWYWx1ZXMgPSB0aGlzLnJhZGlvcy5maW5kKChyKSA9PiByLmNoZWNrZWQpO1xuICAgIGlmIChhY3RpdmVWYWx1ZXMgJiYgdGhpcy52YWx1ZSAhPT0gYWN0aXZlVmFsdWVzLnJhZGlvVmFsdWUpIHtcbiAgICAgIHRoaXMudmFsdWUgPSBhY3RpdmVWYWx1ZXMucmFkaW9WYWx1ZTtcbiAgICB9XG4gIH1cblxuICBzZXRVcENoZWNrYm94ZXMoKSB7XG4gICAgdGhpcy5jaGVja2JveGVzLmZvckVhY2goKGNoZWNrYm94KSA9PiB7XG4gICAgICBjaGVja2JveC5jaGVja2JveFZhbHVlID0gY2hlY2tib3guY2hlY2tib3hWYWx1ZVxuICAgICAgICA/IGNoZWNrYm94LmNoZWNrYm94VmFsdWVcbiAgICAgICAgOiB0aGlzLnV1aWRTZXJ2aWNlLmdldFVVSUQoJ3YtY2hlY2tib3gtJyk7XG4gICAgICBjaGVja2JveC5saXN0ZW5lcnMucHVzaChcbiAgICAgICAgY2hlY2tib3guY2xpY2tlZC5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgaWYgKGV2ZW50LnRhcmdldC5jaGVja2VkKSB7XG4gICAgICAgICAgICAvLyBhZGQgdmFsdWVcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbLi4uKHRoaXMudmFsdWUgYXMgKHN0cmluZyB8IG51bWJlcilbXSksIGNoZWNrYm94LmNoZWNrYm94VmFsdWVdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgdmFsdWVcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSAodGhpcy52YWx1ZSBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdKS5maWx0ZXIoKHYpID0+IHYgIT09IGNoZWNrYm94LmNoZWNrYm94VmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gICAgLy8gZmluZCBjaGVja2VkIGNoZWNrYm94ZXMgYW5kIHNldCB2YWx1ZVxuICAgIGNvbnN0IGFjdGl2ZVZhbHVlcyA9IHRoaXMuY2hlY2tib3hlcy5maWx0ZXIoKGMpID0+IGMuY2hlY2tlZCkubWFwKChjKSA9PiBjLmNoZWNrYm94VmFsdWUpO1xuICAgIGlmIChhY3RpdmVWYWx1ZXMgJiYgdGhpcy52YWx1ZSAhPT0gYWN0aXZlVmFsdWVzKSB7XG4gICAgICB0aGlzLnZhbHVlID0gYWN0aXZlVmFsdWVzO1xuICAgIH1cbiAgfVxuXG4gIG9uQ2hhbmdlID0gKF86IGFueSkgPT4ge307XG5cbiAgb25Ub3VjaGVkID0gKF86IGFueSkgPT4ge307XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KSB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiAoc3RyaW5nIHwgbnVtYmVyKVtdIHwgc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIC8vIGNsZWFyIHZhbHVlIGZyb20gcmFkaW8gYW5kIHZpc3VhbCBjaGVja1xuICAgIHRoaXMucmFkaW9zPy5mb3JFYWNoKChyYWRpbykgPT4ge1xuICAgICAgdGhpcy51cGRhdGVDaGVja2JveFJhZGlvVmFsKHJhZGlvKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2hlY2tib3hlcz8uZm9yRWFjaCgoY2hlY2tib3gpID0+IHtcbiAgICAgIHRoaXMudXBkYXRlQ2hlY2tib3hSYWRpb1ZhbChjaGVja2JveCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmJ1dHRvbnM/LmZvckVhY2goKGJ1dHRvbikgPT4ge1xuICAgICAgYnV0dG9uLmFjdGl2ZSA9IGZhbHNlO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMubXVsdGlzZWxlY3QgJiYgdGhpcy52YWx1ZSAmJiAodGhpcy52YWx1ZSBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdKS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnZhbHVlID0gW107XG4gICAgfSBlbHNlIGlmICh0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVDaGVja2JveFJhZGlvVmFsKGl0ZW06IFJhZGlvRGlyZWN0aXZlIHwgQ2hlY2tib3hEaXJlY3RpdmUsIGNoZWNrZWQ6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGl0ZW0uY2hlY2tlZCA9IGNoZWNrZWQ7XG4gICAgaWYgKHRoaXMuYXBwUmVhZHlTZXJ2aWNlLmlzQnJvd3NlckFuZERvbUF2YWlsYWJsZSgpKSB7XG4gICAgICBpdGVtLmVsLm5hdGl2ZUVsZW1lbnQuY2hlY2tlZCA9IGNoZWNrZWQ7XG4gICAgfVxuICB9XG5cbiAgdW5zdWJzY3JpYmVGcm9tTGlzdGVuZXJzKFxuICAgIGl0ZW1zOiBRdWVyeUxpc3Q8UmFkaW9EaXJlY3RpdmU+IHwgUXVlcnlMaXN0PENoZWNrYm94RGlyZWN0aXZlPiB8IFF1ZXJ5TGlzdDxUb2dnbGVCdXR0b25EaXJlY3RpdmU+XG4gICkge1xuICAgIGl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGl0ZW0ubGlzdGVuZXJzLmZvckVhY2goKHN1YikgPT4ge1xuICAgICAgICBzdWIudW5zdWJzY3JpYmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaW5mb3JtRGlzYWJsZWRTdGF0ZSgpIHtcbiAgICBpZiAodGhpcy5idXR0b25zKSB7XG4gICAgICB0aGlzLmJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XG4gICAgICAgIGJ1dHRvbi5kaXNhYmxlZCA9IHRoaXMuZGlzYWJsZWQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHRoaXMucmFkaW9zKSB7XG4gICAgICB0aGlzLnJhZGlvcy5mb3JFYWNoKChyYWRpbykgPT4ge1xuICAgICAgICByYWRpby5kaXNhYmxlZCA9IHRoaXMuZGlzYWJsZWQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2hlY2tib3hlcykge1xuICAgICAgdGhpcy5jaGVja2JveGVzLmZvckVhY2goKGNoZWNrYm94KSA9PiB7XG4gICAgICAgIGNoZWNrYm94LmRpc2FibGVkID0gdGhpcy5kaXNhYmxlZDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19