@millieofzo/ion-intl-tel-input
Version:
This is a continuation of the original project from azzamasghar1 (https://github.com/azzamasghar1/ion-intl-tel-input) which includes new features and some much requested features
743 lines • 96.3 kB
JavaScript
import { Component, ElementRef, EventEmitter, HostBinding, Input, Output, ViewChild, forwardRef, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { IonInput, Platform } from '@ionic/angular';
import { PhoneNumberFormat, PhoneNumberUtil, } from 'google-libphonenumber';
import { IonIntlTelInputService } from './ion-intl-tel-input.service';
import { TranslateService } from '@ngx-translate/core';
import { translationPrefix } from '../data';
import { raf } from '../util/util';
import * as i0 from "@angular/core";
import * as i1 from "@ionic/angular";
import * as i2 from "./ion-intl-tel-input.service";
import * as i3 from "@ngx-translate/core";
import * as i4 from "@angular/common";
import * as i5 from "@angular/forms";
import * as i6 from "@millieofzo/ion-selectable";
import * as i7 from "../pipes/country-placeholder";
/**
* @ignore
*/
/**
* @author Azzam Asghar <azzam.asghar@interstellus.com>
*/
export class IonIntlTelInputComponent {
get hasValueCssClass() {
return this.hasValue();
}
get isEnabled() {
return !this.disabled;
}
constructor(el, platform, ionIntlTelInputService, translate) {
this.el = el;
this.platform = platform;
this.ionIntlTelInputService = ionIntlTelInputService;
this.translate = translate;
this.cssClass = true;
this.isIos = false;
this.isMD = false;
this.hasFocus = false;
/**
* Iso Code of default selected Country.
* See more on.
*
* @default ''
* @memberof IonIntlTelInputComponent
*/
this.defaultCountryiso = '';
/**
* Determines whether to use `00` or `+` as dial code prefix.
* Available attributes are '+' | '00'.
* See more on.
*
* @default +
* @memberof IonIntlTelInputComponent
*/
this.dialCodePrefix = '+';
/**
* Determines whether to select automatic country based on user input.
* See more on.
*
* @default false
* @memberof IonIntlTelInputComponent
*/
this.enableAutoCountrySelect = false;
/**
* Determines whether an example number will be shown as a placeholder in input.
* See more on.
*
* @default true
* @memberof IonIntlTelInputComponent
*/
this.enablePlaceholder = true;
/**
* A fallaback placeholder to be used if no example number is found for a country.
* See more on.
*
* @default ''
* @memberof IonIntlTelInputComponent
*/
this.fallbackPlaceholder = '';
/**
* If a custom placeholder is needed for input.
* If this property is set it will override `enablePlaceholder` and only this placeholder will be shown.
* See more on.
*
* @default ''
* @memberof IonIntlTelInputComponent
*/
this.inputPlaceholder = '';
/**
* Maximum Length for input.
* See more on.
*
* @default '15'
* @memberof IonIntlTelInputComponent
*/
this.maxLength = '15';
/**
* Title of modal opened to select country dial code.
* See more on.
*
* @default 'Select Country'
* @memberof IonIntlTelInputComponent
*/
this.modalTitle = 'Select Country';
/**
* Placeholder for the select dropdown
* See more on.
*
* @default 'Country'
* @memberof IonIntlTelInputComponent
*/
this.dropdownPlaceholder = 'Country';
/**
* CSS class to attach to dial code selectionmodal.
* See more on.
*
* @default ''
* @memberof IonIntlTelInputComponent
*/
this.modalCssClass = '';
/**
* Placeholder for input in dial code selection modal.
* See more on.
*
* @default 'Enter country name'
* @memberof IonIntlTelInputComponent
*/
this.modalSearchPlaceholder = 'Enter country name';
/**
* Text for close button in dial code selection modal.
* See more on.
*
* @default 'Close'
* @memberof IonIntlTelInputComponent
*/
this.modalCloseText = 'Close';
/**
* Slot for close button in dial code selection modal. [Ionic slots](https://ionicframework.com/docs/api/item) are supported
* See more on.
*
* @default 'end'
* @memberof IonIntlTelInputComponent
*/
this.modalCloseButtonSlot = 'end';
/**
* Determines whether dial code selection modal should be searchable or not.
* See more on.
*
* @default 'true'
* @memberof IonIntlTelInputComponent
*/
this.modalCanSearch = true;
/**
* Determines whether dial code selection modal is closed on backdrop click.
* See more on.
*
* @default 'true'
* @memberof IonIntlTelInputComponent
*/
this.modalShouldBackdropClose = true;
/**
* Determines whether input should be focused when dial code selection modal is opened.
* See more on.
*
* @default 'true'
* @memberof IonIntlTelInputComponent
*/
this.modalShouldFocusSearchbar = true;
/**
* Message to show when no countries are found for search in dial code selection modal.
* See more on.
*
* @default 'true'
* @memberof IonIntlTelInputComponent
*/
this.modalSearchFailText = 'No countries found';
/**
* Item icon slot.
* See more on.
*
* @default 'start'
* @memberof IonIntlTelInputComponent
*/
this.modalItemIconSlot = 'start';
/**
* List of iso codes of manually selected countries as string, which will appear in the dropdown.
* **Note**: `onlyCountries` should be a string array of country iso codes.
* See more on.
*
* @default null
* @memberof IonIntlTelInputComponent
*/
this.onlyCountries = [];
/**
* List of iso codes as string of countries, which will appear at the top in dial code selection modal.
* **Note**: `preferredCountries` should be a string array of country iso codes.
* See more on.
*
* @default null
* @memberof IonIntlTelInputComponent
*/
this.preferredCountries = [];
/**
* Determines whether first country should be selected in dial code select or not.
* See more on.
*
* @default true
* @memberof IonIntlTelInputComponent
*/
this.selectFirstCountry = true;
/**
* Determines whether to visually separate dialcode into the drop down element.
* See more on.
*
* @default true
* @memberof IonIntlTelInputComponent
*/
this.separateDialCode = true;
/**
* Fires when the Phone number Input is changed.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.numberChange = new EventEmitter();
/**
* Fires when the Phone number Input is blurred.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.numberBlur = new EventEmitter();
/**
* Fires when the Phone number Input is focused.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.numberFocus = new EventEmitter();
/**
* Fires when the user is typing in Phone number Input.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.numberInput = new EventEmitter();
/**
* Fires when the dial code selection is changed.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.codeChange = new EventEmitter();
/**
* Fires when the dial code selection modal is opened.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.codeOpen = new EventEmitter();
/**
* Fires when the dial code selection modal is closed.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.codeClose = new EventEmitter();
/**
* Fires when a dial code is selected in dial code selection modal.
* See more on.
*
* @memberof IonIntlTelInputComponent
*/
this.codeSelect = new EventEmitter();
this.phoneNumber = '';
this.countries = [];
this.disabled = false;
this.phoneUtil = PhoneNumberUtil.getInstance();
this.translationPrefix = `${translationPrefix}.`;
this.onTouched = () => { };
// eslint-disable-next-line @typescript-eslint/no-unused-vars
this.propagateChange = (_) => { };
this.startsWith = (input, search) => {
return input.substr(0, search.length) === search;
};
this.getClasses = (element) => {
const classList = element.classList;
const classes = [];
for (let i = 0; i < classList.length; i++) {
const item = classList.item(i);
if (item !== null && this.startsWith(item, 'ng-')) {
classes.push(`ion-${item.substr(3)}`);
}
}
return classes;
};
this.setClasses = (element, classes) => {
const classList = element.classList;
[
'ion-valid',
'ion-invalid',
'ion-touched',
'ion-untouched',
'ion-dirty',
'ion-pristine',
].forEach((c) => classList.remove(c));
classes.forEach((c) => classList.add(c));
};
this.setIonicClasses = (element) => {
raf(() => {
const input = element.nativeElement;
const classes = this.getClasses(input);
this.setClasses(input, classes);
const item = input.closest('ion-item');
if (item) {
this.setClasses(item, classes);
}
});
};
this.setItemClass = (element, className, addClass) => {
const input = element.nativeElement;
const item = input.closest('ion-item');
if (item) {
const classList = item.classList;
if (addClass) {
classList.add(className);
}
else {
classList.remove(className);
}
}
};
}
get value() {
return this._value;
}
set value(value) {
if (value !== null) {
this._value = value;
this.setIonicClasses(this.el);
}
}
emitValueChange(change) {
this.propagateChange(change);
}
ngOnInit() {
this.isIos = this.platform.is('ios');
this.isMD = !this.isIos;
this.setItemClass(this.el, 'item-interactive', true);
this.fetchAllCountries();
this.setPreferredCountries();
if (this.onlyCountries.length) {
this.countries = this.countries.filter((country) => this.onlyCountries.includes(country.isoCode));
}
if (this.selectFirstCountry) {
if (this.defaultCountryiso) {
this.setCountry(this.getCountryByIsoCode(this.defaultCountryiso));
}
else {
if (this.preferredCountries.length &&
this.preferredCountries.includes(this.defaultCountryiso)) {
this.setCountry(this.getCountryByIsoCode(this.preferredCountries[0]));
}
else {
this.setCountry(this.countries[0]);
}
}
}
}
ngOnChanges(changes) {
if (this.countries &&
changes['defaulyCountryisoCode'] &&
changes['defaulyCountryisoCode'].currentValue !==
changes['defaulyCountryisoCode'].previousValue) {
this.setCountry(changes['defaulyCountryisoCode'].currentValue);
}
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
writeValue(obj) {
this.fillValues(obj);
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
fillValues(value) {
if (value &&
value !== null &&
typeof value === 'object' &&
!this.isNullOrWhiteSpace(value)) {
this.phoneNumber = value.nationalNumber;
this.setCountry(this.getCountryByIsoCode(value.isoCode));
this.value = value;
}
else if (this.value &&
this.value !== null &&
typeof this.value === 'object' &&
!this.isNullOrWhiteSpace(this.value)) {
this.phoneNumber = this.value.nationalNumber;
this.setCountry(this.getCountryByIsoCode(this.value.isoCode));
}
setTimeout(() => {
this.onNumberChange();
}, 1);
}
hasValue() {
return !this.isNullOrWhiteSpace(this.value);
}
onCodeOpen() {
this.codeOpen.emit();
}
onCodeChange(event) {
if (this.isNullOrWhiteSpace(this.phoneNumber)) {
this.emitValueChange(null);
}
else {
let googleNumber;
try {
googleNumber = this.phoneUtil.parse(this.phoneNumber, this.country.isoCode.toUpperCase());
}
catch (e) {
// Handle parse error if needed
}
const internationallNo = googleNumber
? this.phoneUtil.format(googleNumber, PhoneNumberFormat.INTERNATIONAL)
: '';
const nationalNo = googleNumber
? this.phoneUtil.format(googleNumber, PhoneNumberFormat.NATIONAL)
: '';
const e164Number = googleNumber
? this.phoneUtil.format(googleNumber, PhoneNumberFormat.E164)
: '';
if (this.separateDialCode && internationallNo) {
this.phoneNumber = this.removeDialCode(internationallNo);
}
this.emitValueChange({
e164Number: e164Number,
internationalNumber: internationallNo,
nationalNumber: nationalNo,
isoCode: this.country.isoCode,
dialCode: this.dialCodePrefix + this.country.dialCode,
});
this.codeChange.emit();
}
setTimeout(() => {
this.numberInputEl.setFocus();
}, 400);
}
onCodeClose() {
this.onTouched();
this.setIonicClasses(this.el);
this.hasFocus = false;
this.setItemClass(this.el, 'item-has-focus', false);
this.codeClose.emit();
}
onCodeSearchCountries(event) {
const text = event.text.trim().toLowerCase();
event.component.startSearch();
event.component.items = this.filterCountries(text);
event.component.endSearch();
}
onCodeSelect() {
this.codeSelect.emit();
}
onIonNumberChange(event) {
this.setIonicClasses(this.el);
this.numberChange.emit(event);
}
onIonNumberBlur() {
this.onTouched();
this.setIonicClasses(this.el);
this.hasFocus = false;
this.setItemClass(this.el, 'item-has-focus', false);
this.numberBlur.emit();
}
onIonNumberFocus() {
this.hasFocus = true;
this.setItemClass(this.el, 'item-has-focus', true);
this.numberFocus.emit();
}
onIonNumberInput(event) {
this.numberInput.emit(event);
}
onNumberChange() {
if (!this.phoneNumber) {
this.value = null;
this.emitValueChange(null);
return;
}
if (this.country) {
this.emitValueChange({
e164Number: this.dialCodePrefix + this.country.dialCode + this.phoneNumber,
internationalNumber: this.dialCodePrefix + this.country.dialCode + ' ' + this.phoneNumber,
nationalNumber: this.phoneNumber,
isoCode: this.country.isoCode,
dialCode: this.dialCodePrefix + this.country.dialCode,
});
}
let googleNumber;
try {
googleNumber = this.phoneUtil.parse(this.phoneNumber, this.country.isoCode.toUpperCase());
}
catch (e) {
return;
}
let isoCode = this.country ? this.country.isoCode : null;
// auto select country based on the extension (and areaCode if needed) (e.g select Canada if number starts with +1 416)
if (this.enableAutoCountrySelect) {
isoCode =
googleNumber && googleNumber.getCountryCode()
? this.getCountryIsoCode(googleNumber.getCountryCode(), googleNumber)
: this.country.isoCode;
if (isoCode && isoCode !== this.country.isoCode) {
const newCountry = this.countries.find((country) => country.isoCode === isoCode);
if (newCountry) {
this.country = newCountry;
}
}
}
isoCode = isoCode ? isoCode : this.country ? this.country.isoCode : null;
if (!this.phoneNumber || !isoCode) {
this.emitValueChange(null);
}
else {
const internationallNo = googleNumber
? this.phoneUtil.format(googleNumber, PhoneNumberFormat.INTERNATIONAL)
: '';
const nationalNo = googleNumber
? this.phoneUtil.format(googleNumber, PhoneNumberFormat.NATIONAL)
: '';
const e164Number = googleNumber
? this.phoneUtil.format(googleNumber, PhoneNumberFormat.E164)
: '';
if (this.separateDialCode && internationallNo) {
this.phoneNumber = this.removeDialCode(internationallNo);
}
this.emitValueChange({
e164Number: e164Number,
internationalNumber: internationallNo,
nationalNumber: nationalNo,
isoCode: this.country.isoCode,
dialCode: this.dialCodePrefix + this.country.dialCode,
});
}
}
onNumberKeyDown(event) {
const allowedChars = /^[0-9\+\-\(\)\.\ ]/;
const allowedCtrlChars = /[axcv]/;
const allowedOtherKeys = [
'ArrowLeft',
'ArrowUp',
'ArrowRight',
'ArrowDown',
'Home',
'End',
'Insert',
'Delete',
'Backspace',
'Tab',
];
const isCtrlKey = event.ctrlKey || event.metaKey;
if (!allowedChars.test(event.key) &&
!(isCtrlKey && allowedCtrlChars.test(event.key)) &&
!allowedOtherKeys.includes(event.key)) {
event.preventDefault();
}
}
filterCountries(text) {
return this.countries.filter((country) => {
return (country.name.toLowerCase().indexOf(text) !== -1 ||
country.name.toLowerCase().indexOf(text) !== -1 ||
country.dialCode.toString().toLowerCase().indexOf(text) !== -1);
});
}
getCountryIsoCode(countryCode, googleNumber) {
const rawNumber = googleNumber.values_[2].toString();
const countries = this.countries.filter((country) => country.dialCode === countryCode.toString());
const mainCountry = countries.find((country) => country.areaCodes === undefined);
const secondaryCountries = countries.filter((country) => country.areaCodes !== undefined);
let matchedCountry = mainCountry ? mainCountry.isoCode : null;
secondaryCountries.forEach((country) => {
if (country.areaCodes) {
// Ensure country.areaCodes is defined
country.areaCodes.forEach((areaCode) => {
if (rawNumber.startsWith(areaCode)) {
matchedCountry = country.isoCode;
}
});
}
});
return matchedCountry;
}
async fetchAllCountries() {
this.countries = this.ionIntlTelInputService.getListOfCountries();
}
getCountryByIsoCode(isoCode) {
for (const country of this.countries) {
if (country.isoCode === isoCode) {
return country;
}
}
return null;
}
isNullOrWhiteSpace(value) {
if (value === null || value === undefined) {
return true;
}
if (typeof value === 'string' && value === '') {
return true;
}
if (typeof value === 'object' && Object.keys(value).length === 0) {
return true;
}
return false;
}
removeDialCode(phoneNumber) {
if (this.separateDialCode && phoneNumber) {
phoneNumber = phoneNumber.substr(phoneNumber.indexOf(' ') + 1);
}
return phoneNumber;
}
setCountry(country) {
this.country = country;
this.codeChange.emit(this.country);
}
setPreferredCountries() {
for (const preferredCountryIsoCode of this.preferredCountries) {
const country = this.getCountryByIsoCode(preferredCountryIsoCode);
if (country) {
// Ensure country is defined
country.priority = 1;
}
}
this.countries.sort((a, b) => a.priority > b.priority ? -1 : a.priority < b.priority ? 1 : 0);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: IonIntlTelInputComponent, deps: [{ token: i0.ElementRef }, { token: i1.Platform }, { token: i2.IonIntlTelInputService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: IonIntlTelInputComponent, selector: "ion-intl-tel-input", inputs: { isEnabled: "isEnabled", defaultCountryiso: "defaultCountryiso", dialCodePrefix: "dialCodePrefix", enableAutoCountrySelect: "enableAutoCountrySelect", enablePlaceholder: "enablePlaceholder", fallbackPlaceholder: "fallbackPlaceholder", inputPlaceholder: "inputPlaceholder", maxLength: "maxLength", modalTitle: "modalTitle", dropdownPlaceholder: "dropdownPlaceholder", modalCssClass: "modalCssClass", modalSearchPlaceholder: "modalSearchPlaceholder", modalCloseText: "modalCloseText", modalCloseButtonSlot: "modalCloseButtonSlot", modalCanSearch: "modalCanSearch", modalShouldBackdropClose: "modalShouldBackdropClose", modalShouldFocusSearchbar: "modalShouldFocusSearchbar", modalSearchFailText: "modalSearchFailText", modalItemIconSlot: "modalItemIconSlot", onlyCountries: "onlyCountries", preferredCountries: "preferredCountries", selectFirstCountry: "selectFirstCountry", separateDialCode: "separateDialCode" }, outputs: { numberChange: "numberChange", numberBlur: "numberBlur", numberFocus: "numberFocus", numberInput: "numberInput", codeChange: "codeChange", codeOpen: "codeOpen", codeClose: "codeClose", codeSelect: "codeSelect" }, host: { properties: { "class.ion-intl-tel-input": "this.cssClass", "class.ion-intl-tel-input-ios": "this.isIos", "class.ion-intl-tel-input-md": "this.isMD", "class.has-focus": "this.hasFocus", "class.ion-intl-tel-input-has-value": "this.hasValueCssClass", "class.ion-intl-tel-input-is-enabled": "this.isEnabled" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => IonIntlTelInputComponent),
multi: true,
},
], viewQueries: [{ propertyName: "numberInputEl", first: true, predicate: ["numberInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"ion-intl-tel-input-code\">\r\n <ion-selectable\r\n #codeSelect\r\n [(ngModel)]=\"country\"\r\n [canSearch]=\"modalCanSearch\"\r\n closeButtonText=\"{{ modalCloseText }}\"\r\n closeButtonSlot=\"{{ modalCloseButtonSlot }}\"\r\n [disabled]=\"disabled\"\r\n [hasVirtualScroll]=\"true\"\r\n itemTextField=\"name\"\r\n [items]=\"countries\"\r\n [itemIconSlot]=\"modalItemIconSlot\"\r\n itemValueField=\"isoCode\"\r\n modalCssClass=\"ionic-tel-input-modal {{ modalCssClass }}\"\r\n placeholder=\"{{ dropdownPlaceholder }}\"\r\n searchFailText=\"{{ modalSearchFailText }}\"\r\n searchPlaceholder=\"{{ modalSearchPlaceholder }}\"\r\n [shouldBackdropClose]=\"modalShouldBackdropClose\"\r\n [shouldFocusSearchbar]=\"modalShouldFocusSearchbar\"\r\n (onChange)=\"onCodeChange($event)\"\r\n (onClose)=\"onCodeClose()\"\r\n (onOpen)=\"onCodeOpen()\"\r\n (onSearch)=\"onCodeSearchCountries($event)\"\r\n (onSelect)=\"onCodeSelect()\"\r\n >\r\n <ng-template ionSelectableTitleTemplate>\r\n {{ modalTitle }}\r\n </ng-template>\r\n <ng-template ionSelectableValueTemplate let-country=\"value\">\r\n <span\r\n class=\"fi fi-{{ country.flagClass }}\"\r\n style=\"border-radius: 3px\"\r\n ></span>\r\n <span *ngIf=\"separateDialCode\"\r\n >{{ dialCodePrefix }}{{ country.dialCode }}</span\r\n >\r\n </ng-template>\r\n <ng-template ionSelectableItemTemplate let-country=\"item\">\r\n <span\r\n class=\"ion-margin-end\"\r\n style=\"background-color: lightgray; padding: 5px; border-radius: 5px\"\r\n >\r\n <span\r\n class=\"fi fi-{{ country.flagClass }}\"\r\n style=\"border-radius: 3px\"\r\n ></span>\r\n </span>\r\n <span class=\"ion-margin-end\">{{ country.name }}</span>\r\n <span *ngIf=\"separateDialCode\"\r\n >{{ dialCodePrefix }}{{ country.dialCode }}</span\r\n >\r\n </ng-template>\r\n <ng-template ionSelectableCloseButtonTemplate>\r\n <ion-icon name=\"close-outline\"></ion-icon>\r\n </ng-template>\r\n <!-- <ng-template ionSelectableItemEndTemplate let-country=\"item\">\r\n <span class=\"fi fi-{{country.flagClass}}\"></span>\r\n </ng-template> -->\r\n </ion-selectable>\r\n</div>\r\n\r\n<div class=\"ion-intl-tel-input-number\">\r\n <ion-input\r\n #numberInput\r\n [(ngModel)]=\"phoneNumber\"\r\n autocomplete=\"off\"\r\n [disabled]=\"disabled\"\r\n [attr.maxLength]=\"maxLength\"\r\n type=\"tel\"\r\n (ionBlur)=\"onIonNumberBlur()\"\r\n (ionChange)=\"onIonNumberChange($event)\"\r\n (ionFocus)=\"onIonNumberFocus()\"\r\n (ionInput)=\"onIonNumberInput($event)\"\r\n (keydown)=\"onNumberKeyDown($event)\"\r\n (ngModelChange)=\"onNumberChange()\"\r\n placeholder=\"{{\r\n country\r\n | countryPlaceholder\r\n : enablePlaceholder\r\n : inputPlaceholder\r\n : separateDialCode\r\n : fallbackPlaceholder\r\n }}\"\r\n >\r\n </ion-input>\r\n</div>\r\n", styles: [":host{width:100%;display:flex;align-items:flex-end}:host .ion-intl-tel-input-code{position:relative}:host .ion-intl-tel-input-number{flex:1}:host .ionic-selectable-label-default,:host .ionic-selectable-label-fixed{max-width:100%}:host .ionic-selectable:not(:host .ionic-selectable-label-stacked):not(:host .ionic-selectable-label-floating) ::ng-deep .ionic-selectable-inner .ionic-selectable-value{padding-top:10px;padding-bottom:10px}:host .ionic-selectable:not(:host .ionic-selectable-label-stacked):not(:host .ionic-selectable-label-floating) ::ng-deep .ionic-selectable-icon-inner{top:17px}:host .fi{margin-right:5px;border-radius:3px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar,ion-range" }, { kind: "component", type: i6.IonSelectableComponent, selector: "ion-selectable", inputs: ["items", "isEnabled", "shouldBackdropClose", "modalCssClass", "modalEnterAnimation", "modalLeaveAnimation", "isConfirmButtonEnabled", "hasConfirmButton", "itemValueField", "itemTextField", "groupValueField", "groupTextField", "canSearch", "isOnSearchEnabled", "canClear", "hasInfiniteScroll", "hasVirtualScroll", "virtualScrollApproxItemHeight", "searchPlaceholder", "placeholder", "isMultiple", "searchFailText", "clearButtonText", "addButtonText", "confirmButtonText", "closeButtonText", "shouldFocusSearchbar", "headerColor", "groupColor", "closeButtonSlot", "itemIconSlot", "searchDebounce", "disabledItems", "shouldStoreItemValue", "canSaveItem", "canDeleteItem", "canAddItem", "virtualScrollHeaderFn"], outputs: ["itemsChange", "onChange", "onSearch", "onSearchFail", "onSearchSuccess", "onInfiniteScroll", "onOpen", "onClose", "onSelect", "onClear", "onSaveItem", "onDeleteItem", "onAddItem"] }, { kind: "pipe", type: i7.CountryPlaceholder, name: "countryPlaceholder" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: IonIntlTelInputComponent, decorators: [{
type: Component,
args: [{ selector: 'ion-intl-tel-input', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => IonIntlTelInputComponent),
multi: true,
},
], template: "<div class=\"ion-intl-tel-input-code\">\r\n <ion-selectable\r\n #codeSelect\r\n [(ngModel)]=\"country\"\r\n [canSearch]=\"modalCanSearch\"\r\n closeButtonText=\"{{ modalCloseText }}\"\r\n closeButtonSlot=\"{{ modalCloseButtonSlot }}\"\r\n [disabled]=\"disabled\"\r\n [hasVirtualScroll]=\"true\"\r\n itemTextField=\"name\"\r\n [items]=\"countries\"\r\n [itemIconSlot]=\"modalItemIconSlot\"\r\n itemValueField=\"isoCode\"\r\n modalCssClass=\"ionic-tel-input-modal {{ modalCssClass }}\"\r\n placeholder=\"{{ dropdownPlaceholder }}\"\r\n searchFailText=\"{{ modalSearchFailText }}\"\r\n searchPlaceholder=\"{{ modalSearchPlaceholder }}\"\r\n [shouldBackdropClose]=\"modalShouldBackdropClose\"\r\n [shouldFocusSearchbar]=\"modalShouldFocusSearchbar\"\r\n (onChange)=\"onCodeChange($event)\"\r\n (onClose)=\"onCodeClose()\"\r\n (onOpen)=\"onCodeOpen()\"\r\n (onSearch)=\"onCodeSearchCountries($event)\"\r\n (onSelect)=\"onCodeSelect()\"\r\n >\r\n <ng-template ionSelectableTitleTemplate>\r\n {{ modalTitle }}\r\n </ng-template>\r\n <ng-template ionSelectableValueTemplate let-country=\"value\">\r\n <span\r\n class=\"fi fi-{{ country.flagClass }}\"\r\n style=\"border-radius: 3px\"\r\n ></span>\r\n <span *ngIf=\"separateDialCode\"\r\n >{{ dialCodePrefix }}{{ country.dialCode }}</span\r\n >\r\n </ng-template>\r\n <ng-template ionSelectableItemTemplate let-country=\"item\">\r\n <span\r\n class=\"ion-margin-end\"\r\n style=\"background-color: lightgray; padding: 5px; border-radius: 5px\"\r\n >\r\n <span\r\n class=\"fi fi-{{ country.flagClass }}\"\r\n style=\"border-radius: 3px\"\r\n ></span>\r\n </span>\r\n <span class=\"ion-margin-end\">{{ country.name }}</span>\r\n <span *ngIf=\"separateDialCode\"\r\n >{{ dialCodePrefix }}{{ country.dialCode }}</span\r\n >\r\n </ng-template>\r\n <ng-template ionSelectableCloseButtonTemplate>\r\n <ion-icon name=\"close-outline\"></ion-icon>\r\n </ng-template>\r\n <!-- <ng-template ionSelectableItemEndTemplate let-country=\"item\">\r\n <span class=\"fi fi-{{country.flagClass}}\"></span>\r\n </ng-template> -->\r\n </ion-selectable>\r\n</div>\r\n\r\n<div class=\"ion-intl-tel-input-number\">\r\n <ion-input\r\n #numberInput\r\n [(ngModel)]=\"phoneNumber\"\r\n autocomplete=\"off\"\r\n [disabled]=\"disabled\"\r\n [attr.maxLength]=\"maxLength\"\r\n type=\"tel\"\r\n (ionBlur)=\"onIonNumberBlur()\"\r\n (ionChange)=\"onIonNumberChange($event)\"\r\n (ionFocus)=\"onIonNumberFocus()\"\r\n (ionInput)=\"onIonNumberInput($event)\"\r\n (keydown)=\"onNumberKeyDown($event)\"\r\n (ngModelChange)=\"onNumberChange()\"\r\n placeholder=\"{{\r\n country\r\n | countryPlaceholder\r\n : enablePlaceholder\r\n : inputPlaceholder\r\n : separateDialCode\r\n : fallbackPlaceholder\r\n }}\"\r\n >\r\n </ion-input>\r\n</div>\r\n", styles: [":host{width:100%;display:flex;align-items:flex-end}:host .ion-intl-tel-input-code{position:relative}:host .ion-intl-tel-input-number{flex:1}:host .ionic-selectable-label-default,:host .ionic-selectable-label-fixed{max-width:100%}:host .ionic-selectable:not(:host .ionic-selectable-label-stacked):not(:host .ionic-selectable-label-floating) ::ng-deep .ionic-selectable-inner .ionic-selectable-value{padding-top:10px;padding-bottom:10px}:host .ionic-selectable:not(:host .ionic-selectable-label-stacked):not(:host .ionic-selectable-label-floating) ::ng-deep .ionic-selectable-icon-inner{top:17px}:host .fi{margin-right:5px;border-radius:3px}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.Platform }, { type: i2.IonIntlTelInputService }, { type: i3.TranslateService }], propDecorators: { cssClass: [{
type: HostBinding,
args: ['class.ion-intl-tel-input']
}], isIos: [{
type: HostBinding,
args: ['class.ion-intl-tel-input-ios']
}], isMD: [{
type: HostBinding,
args: ['class.ion-intl-tel-input-md']
}], hasFocus: [{
type: HostBinding,
args: ['class.has-focus']
}], hasValueCssClass: [{
type: HostBinding,
args: ['class.ion-intl-tel-input-has-value']
}], isEnabled: [{
type: HostBinding,
args: ['class.ion-intl-tel-input-is-enabled']
}, {
type: Input,
args: ['isEnabled']
}], defaultCountryiso: [{
type: Input
}], dialCodePrefix: [{
type: Input
}], enableAutoCountrySelect: [{
type: Input
}], enablePlaceholder: [{
type: Input
}], fallbackPlaceholder: [{
type: Input
}], inputPlaceholder: [{
type: Input
}], maxLength: [{
type: Input
}], modalTitle: [{
type: Input
}], dropdownPlaceholder: [{
type: Input
}], modalCssClass: [{
type: Input
}], modalSearchPlaceholder: [{
type: Input
}], modalCloseText: [{
type: Input
}], modalCloseButtonSlot: [{
type: Input
}], modalCanSearch: [{
type: Input
}], modalShouldBackdropClose: [{
type: Input
}], modalShouldFocusSearchbar: [{
type: Input
}], modalSearchFailText: [{
type: Input
}], modalItemIconSlot: [{
type: Input
}], onlyCountries: [{
type: Input
}], preferredCountries: [{
type: Input
}], selectFirstCountry: [{
type: Input
}], separateDialCode: [{
type: Input
}], numberChange: [{
type: Output
}], numberBlur: [{
type: Output
}], numberFocus: [{
type: Output
}], numberInput: [{
type: Output
}], codeChange: [{
type: Output
}], codeOpen: [{
type: Output
}], codeClose: [{
type: Output
}], codeSelect: [{
type: Output
}], numberInputEl: [{
type: ViewChild,
args: ['numberInput', { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW9uLWludGwtdGVsLWlucHV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvaW9uLWludGwtdGVsLWlucHV0L3NyYy9saWIvaW9uLWludGwtdGVsLWlucHV0L2lvbi1pbnRsLXRlbC1pbnB1dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2lvbi1pbnRsLXRlbC1pbnB1dC9zcmMvbGliL2lvbi1pbnRsLXRlbC1pbnB1dC9pb24taW50bC10ZWwtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBR0wsTUFBTSxFQUVOLFNBQVMsRUFDVCxVQUFVLEdBQ1gsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFcEQsT0FBTyxFQUVMLGlCQUFpQixFQUNqQixlQUFlLEdBQ2hCLE1BQU0sdUJBQXVCLENBQUM7QUFFL0IsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFLdEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzVDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxjQUFjLENBQUM7Ozs7Ozs7OztBQUVuQzs7R0FFRztBQWlCSDs7R0FFRztBQUNILE1BQU0sT0FBTyx3QkFBd0I7SUFlbkMsSUFDSSxnQkFBZ0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUNELElBRUksU0FBUztRQUNYLE9BQU8sQ0FB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QUFLO2dCQVdOLHlCQUF5QjtzQkFEeEIsS0FBSztnQkFXTixtQkFBbUI7c0JBRGxCLEtBQUs7Z0JBV04saUJBQWlCO3NCQURoQixLQUFLO2dCQVlOLGFBQWE7c0JBRFosS0FBSztnQkFZTixrQkFBa0I7c0JBRGpCLEtBQUs7Z0JBV04sa0JBQWtCO3NCQURqQixLQUFLO2dCQVdOLGdCQUFnQjtzQkFEZixLQUFLO2dCQVVHLFlBQVk7c0JBRHBCLE1BQU07Z0JBVUUsVUFBVTtzQkFEbEIsTUFBTTtnQkFVRSxXQUFXO3NCQURuQixNQUFNO2dCQVVFLFdBQVc7c0JBRG5CLE1BQU07Z0JBVUUsVUFBVTtzQkFEbEIsTUFBTTtnQkFVRSxRQUFRO3NCQURoQixNQUFNO2dCQVVFLFNBQVM7c0JBRGpCLE1BQU07Z0JBVUUsVUFBVTtzQkFEbEIsTUFBTTtnQkFHc0MsYUFBYTtzQkFBekQsU0FBUzt1QkFBQyxhQUFhLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSG9zdEJpbmRpbmcsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uSW5pdCxcclxuICBPdXRwdXQsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBWaWV3Q2hpbGQsXHJcbiAgZm9yd2FyZFJlZixcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbmltcG9ydCB7IElvbklucHV0LCBQbGF0Zm9ybSB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcclxuXHJcbmltcG9ydCB7XHJcbiAgUGhvbmVOdW1iZXIsXHJcbiAgUGhvbmVOdW1iZXJGb3JtYXQsXHJcbiAgUGhvbmVOdW1iZXJVdGlsLFxyXG59IGZyb20gJ2dvb2dsZS1saWJwaG9uZW51bWJlcic7XHJcblxyXG5pbXBvcnQgeyBJb25JbnRsVGVsSW5wdXRTZXJ2aWNlIH0gZnJvbSAnLi9pb24taW50bC10ZWwtaW5wdXQuc2VydmljZSc7XHJcbmltcG9ydCB7IENvdW50cnlJIH0gZnJvbSAnLi4vbW9kZWxzL2NvdW50cnkubW9kZWwnO1xyXG5pbXBvcnQgeyBJb25JbnRsVGVsSW5wdXRNb2RlbCB9IGZyb20gJy4uL21vZGVscy9pb24taW50bC10ZWwtaW5wdXQubW9kZWwnO1xyXG4vLyBpbXBvcnQgeyBpb25JbnRsVGVsSW5wdXRWYWxpZGF0b3IgfSBmcm9tICcuLi9pb24taW50bC10ZWwtaW5wdXQuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgSW9uU2VsZWN0YWJsZUNvbXBvbmVudCB9IGZyb20gJ0BtaWxsaWVvZnpvL2lvbi1zZWxlY3RhYmxlJztcclxuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xyXG5pbXBvcnQgeyB0cmFuc2xhdGlvblByZWZpeCB9IGZyb20gJy4uL2RhdGEnO1xyXG5pbXBvcnQgeyByYWYgfSBmcm9tICcuLi91dGlsL3V0aWwnO1xyXG5cclxuLyoqXHJcbiAqIEBpZ25vcmVcclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIC8vIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgLy8gaW1wb3J0czogW0lvblNlbGVjdGFibGVDb21wb25lbnRdLFxyXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogY29tcG9uZW50LXNlbGVjdG9yXHJcbiAgc2VsZWN0b3I6ICdpb24taW50bC10ZWwtaW5wdXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9pb24taW50bC10ZWwtaW5wdXQuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2lvbi1pbnRsLXRlbC1pbnB1dC5jb21wb25lbnQuc2NzcyddLFxyXG4gIHByb3ZpZGVyczogW1xyXG4gICAge1xyXG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gSW9uSW50bFRlbElucHV0Q29tcG9uZW50KSxcclxuICAgICAgbXVsdGk6IHRydWUsXHJcbiAgICB9LFxyXG4gIF0sXHJcbn0pXHJcblxyXG4vKipcclxuICogQGF1dGhvciBBenphbSBBc2doYXIgPGF6emFtLmFzZ2hhckBpbnRlcnN0ZWxsdXMuY29tPlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCwgT25DaGFuZ2VzXHJcbntcclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlvbi1pbnRsLXRlbC1pbnB1dCcpXHJcbiAgY3NzQ2xhc3MgPSB0cnVlO1xyXG5cclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlvbi1pbnRsLXRlbC1pbnB1dC1pb3MnKVxyXG4gIGlzSW9zID0gZmFsc2U7XHJcblxyXG4gIEBIb3N0QmluZGluZygnY2xhc3MuaW9uLWludGwtdGVsLWlucHV0LW1kJylcclxuICBpc01EID0gZmFsc2U7XHJcblxyXG4gIEBIb3N0QmluZGluZygnY2xhc3MuaGFzLWZvY3VzJylcclxuICBoYXNGb2N1cyA9IGZhbHNlO1xyXG5cclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlvbi1pbnRsLXRlbC1pbnB1dC1oYXMtdmFsdWUnKVxyXG4gIGdldCBoYXNWYWx1ZUNzc0NsYXNzKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaGFzVmFsdWUoKTtcclxuICB9XHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5pb24taW50bC10ZWwtaW5wdXQtaXMtZW5hYmxlZCcpXHJcbiAgQElucHV0KCdpc0VuYWJsZWQnKVxyXG4gIGdldCBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gIXRoaXMuZGlzYWJsZWQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJc28gQ29kZSBvZiBkZWZhdWx0IHNlbGVjdGVkIENvdW50cnkuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAZGVmYXVsdCAnJ1xyXG4gICAqIEBtZW1iZXJvZiBJb25JbnRsVGVsSW5wdXRDb21wb25lbnRcclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIGRlZmF1bHRDb3VudHJ5aXNvID0gJyc7XHJcblxyXG4gIC8qKlxyXG4gICAqIERldGVybWluZXMgd2hldGhlciB0byB1c2UgYDAwYCBvciBgK2AgYXMgZGlhbCBjb2RlIHByZWZpeC5cclxuICAgKiBBdmFpbGFibGUgYXR0cmlidXRlcyBhcmUgJysnIHwgJzAwJy5cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBkZWZhdWx0ICtcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBkaWFsQ29kZVByZWZpeDogJysnIHwgJzAwJyA9ICcrJztcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHNlbGVjdCBhdXRvbWF0aWMgY291bnRyeSBiYXNlZCBvbiB1c2VyIGlucHV0LlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgZmFsc2VcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBlbmFibGVBdXRvQ291bnRyeVNlbGVjdCA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW4gZXhhbXBsZSBudW1iZXIgd2lsbCBiZSBzaG93biBhcyBhIHBsYWNlaG9sZGVyIGluIGlucHV0LlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgdHJ1ZVxyXG4gICAqIEBtZW1iZXJvZiBJb25JbnRsVGVsSW5wdXRDb21wb25lbnRcclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIGVuYWJsZVBsYWNlaG9sZGVyID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogQSBmYWxsYWJhY2sgcGxhY2Vob2xkZXIgdG8gYmUgdXNlZCBpZiBubyBleGFtcGxlIG51bWJlciBpcyBmb3VuZCBmb3IgYSBjb3VudHJ5LlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgJydcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBmYWxsYmFja1BsYWNlaG9sZGVyID0gJyc7XHJcblxyXG4gIC8qKlxyXG4gICAqIElmIGEgY3VzdG9tIHBsYWNlaG9sZGVyIGlzIG5lZWRlZCBmb3IgaW5wdXQuXHJcbiAgICogSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgaXQgd2lsbCBvdmVycmlkZSBgZW5hYmxlUGxhY2Vob2xkZXJgIGFuZCBvbmx5IHRoaXMgcGxhY2Vob2xkZXIgd2lsbCBiZSBzaG93bi5cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBkZWZhdWx0ICcnXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgaW5wdXRQbGFjZWhvbGRlciA9ICcnO1xyXG5cclxuICAvKipcclxuICAgKiBNYXhpbXVtIExlbmd0aCBmb3IgaW5wdXQuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAZGVmYXVsdCAnMTUnXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgbWF4TGVuZ3RoID0gJzE1JztcclxuXHJcbiAgLyoqXHJcbiAgICogVGl0bGUgb2YgbW9kYWwgb3BlbmVkIHRvIHNlbGVjdCBjb3VudHJ5IGRpYWwgY29kZS5cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBkZWZhdWx0ICdTZWxlY3QgQ291bnRyeSdcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBtb2RhbFRpdGxlID0gJ1NlbGVjdCBDb3VudHJ5JztcclxuXHJcbiAgLyoqXHJcbiAgICogUGxhY2Vob2xkZXIgZm9yIHRoZSBzZWxlY3QgZHJvcGRvd25cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBkZWZhdWx0ICdDb3VudHJ5J1xyXG4gICAqIEBtZW1iZXJvZiBJb25JbnRsVGVsSW5wdXRDb21wb25lbnRcclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIGRyb3Bkb3duUGxhY2Vob2xkZXIgPSAnQ291bnRyeSc7XHJcblxyXG4gIC8qKlxyXG4gICAqIENTUyBjbGFzcyB0byBhdHRhY2ggdG8gZGlhbCBjb2RlIHNlbGVjdGlvbm1vZGFsLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgJydcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBtb2RhbENzc0NsYXNzID0gJyc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBsYWNlaG9sZGVyIGZvciBpbnB1dCBpbiBkaWFsIGNvZGUgc2VsZWN0aW9uIG1vZGFsLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgJ0VudGVyIGNvdW50cnkgbmFtZSdcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBtb2RhbFNlYXJjaFBsYWNlaG9sZGVyID0gJ0VudGVyIGNvdW50cnkgbmFtZSc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRleHQgZm9yIGNsb3NlIGJ1dHRvbiBpbiBkaWFsIGNvZGUgc2VsZWN0aW9uIG1vZGFsLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgJ0Nsb3NlJ1xyXG4gICAqIEBtZW1iZXJvZiBJb25JbnRsVGVsSW5wdXRDb21wb25lbnRcclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIG1vZGFsQ2xvc2VUZXh0ID0gJ0Nsb3NlJztcclxuXHJcbiAgLyoqXHJcbiAgICogU2xvdCBmb3IgY2xvc2UgYnV0dG9uIGluIGRpYWwgY29kZSBzZWxlY3Rpb24gbW9kYWwuIFtJb25pYyBzbG90c10oaHR0cHM6Ly9pb25pY2ZyYW1ld29yay5jb20vZG9jcy9hcGkvaXRlbSkgYXJlIHN1cHBvcnRlZFxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgJ2VuZCdcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBtb2RhbENsb3NlQnV0dG9uU2xvdDogJ3N0YXJ0JyB8ICdlbmQnIHwgJ3ByaW1hcnknIHwgJ3NlY29uZGFyeScgPSAnZW5kJztcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGRpYWwgY29kZSBzZWxlY3Rpb24gbW9kYWwgc2hvdWxkIGJlIHNlYXJjaGFibGUgb3Igbm90LlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHQgJ3RydWUnXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgbW9kYWxDYW5TZWFyY2ggPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgZGlhbCBjb2RlIHNlbGVjdGlvbiBtb2RhbCBpcyBjbG9zZWQgb24gYmFja2Ryb3AgY2xpY2suXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAZGVmYXVsdCAndHJ1ZSdcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBtb2RhbFNob3VsZEJhY2tkcm9wQ2xvc2UgPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgaW5wdXQgc2hvdWxkIGJlIGZvY3VzZWQgd2hlbiBkaWFsIGNvZGUgc2VsZWN0aW9uIG1vZGFsIGlzIG9wZW5lZC5cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBkZWZhdWx0ICd0cnVlJ1xyXG4gICAqIEBtZW1iZXJvZiBJb25JbnRsVGVsSW5wdXRDb21wb25lbnRcclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIG1vZGFsU2hvdWxkRm9jdXNTZWFyY2hiYXIgPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBNZXNzYWdlIHRvIHNob3cgd2hlbiBubyBjb3VudHJpZXMgYXJlIGZvdW5kIGZvciBzZWFyY2ggaW4gZGlhbCBjb2RlIHNlbGVjdGlvbiBtb2RhbC5cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBkZWZhdWx0ICd0cnVlJ1xyXG4gICAqIEBtZW1iZXJvZiBJb25JbnRsVGVsSW5wdXRDb21wb25lbnRcclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIG1vZGFsU2VhcmNoRmFpbFRleHQgPSAnTm8gY291bnRyaWVzIGZvdW5kJztcclxuXHJcbiAgLyoqXHJcbiAgICogSXRlbSBpY29uIHNsb3QuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAZGVmYXVsdCAnc3RhcnQnXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgbW9kYWxJdGVtSWNvblNsb3QgPSAnc3RhcnQnO1xyXG5cclxuICAvKipcclxuICAgKiBMaXN0IG9mIGlzbyBjb2RlcyBvZiBtYW51YWxseSBzZWxlY3RlZCBjb3VudHJpZXMgYXMgc3RyaW5nLCB3aGljaCB3aWxsIGFwcGVhciBpbiB0aGUgZHJvcGRvd24uXHJcbiAgICogKipOb3RlKio6IGBvbmx5Q291bnRyaWVzYCBzaG91bGQgYmUgYSBzdHJpbmcgYXJyYXkgb2YgY291bnRyeSBpc28gY29kZXMuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAZGVmYXVsdCBudWxsXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgb25seUNvdW50cmllczogQXJyYXk8c3RyaW5nPiA9IFtdO1xyXG5cclxuICAvKipcclxuICAgKiBMaXN0IG9mIGlzbyBjb2RlcyBhcyBzdHJpbmcgb2YgIGNvdW50cmllcywgd2hpY2ggd2lsbCBhcHBlYXIgYXQgdGhlIHRvcCBpbiBkaWFsIGNvZGUgc2VsZWN0aW9uIG1vZGFsLlxyXG4gICAqICoqTm90ZSoqOiBgcHJlZmVycmVkQ291bnRyaWVzYCBzaG91bGQgYmUgYSBzdHJpbmcgYXJyYXkgb2YgY291bnRyeSBpc28gY29kZXMuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAZGVmYXVsdCBudWxsXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgcHJlZmVycmVkQ291bnRyaWVzOiBBcnJheTxzdHJpbmc+ID0gW107XHJcblxyXG4gIC8qKlxyXG4gICAqIERldGVybWluZXMgd2hldGhlciBmaXJzdCBjb3VudHJ5IHNob3VsZCBiZSBzZWxlY3RlZCBpbiBkaWFsIGNvZGUgc2VsZWN0IG9yIG5vdC5cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBkZWZhdWx0IHRydWVcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZWxlY3RGaXJzdENvdW50cnkgPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdG8gdmlzdWFsbHkgc2VwYXJhdGUgZGlhbGNvZGUgaW50byB0aGUgZHJvcCBkb3duIGVsZW1lbnQuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAZGVmYXVsdCB0cnVlXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2VwYXJhdGVEaWFsQ29kZSA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIFBob25lIG51bWJlciBJbnB1dCBpcyBjaGFuZ2VkLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIHJlYWRvbmx5IG51bWJlckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RXZlbnQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIFBob25lIG51bWJlciBJbnB1dCBpcyBibHVycmVkLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIHJlYWRvbmx5IG51bWJlckJsdXIgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIFBob25lIG51bWJlciBJbnB1dCBpcyBmb2N1c2VkLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIHJlYWRvbmx5IG51bWJlckZvY3VzID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAvKipcclxuICAgKiBGaXJlcyB3aGVuIHRoZSB1c2VyIGlzIHR5cGluZyBpbiBQaG9uZSBudW1iZXIgSW5wdXQuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgcmVhZG9ubHkgbnVtYmVySW5wdXQgPSBuZXcgRXZlbnRFbWl0dGVyPEtleWJvYXJkRXZlbnQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIGRpYWwgY29kZSBzZWxlY3Rpb24gaXMgY2hhbmdlZC5cclxuICAgKiBTZWUgbW9yZSBvbi5cclxuICAgKlxyXG4gICAqIEBtZW1iZXJvZiBJb25JbnRsVGVsSW5wdXRDb21wb25lbnRcclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICByZWFkb25seSBjb2RlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIGRpYWwgY29kZSBzZWxlY3Rpb24gbW9kYWwgaXMgb3BlbmVkLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIHJlYWRvbmx5IGNvZGVPcGVuID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIGRpYWwgY29kZSBzZWxlY3Rpb24gbW9kYWwgaXMgY2xvc2VkLlxyXG4gICAqIFNlZSBtb3JlIG9uLlxyXG4gICAqXHJcbiAgICogQG1lbWJlcm9mIElvbkludGxUZWxJbnB1dENvbXBvbmVudFxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIHJlYWRvbmx5IGNvZGVDbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAvKipcclxuICAgKiBGaXJlcyB3aGVuIGEgZGlhbCBjb2RlIGlzIHNlbGVjdGVkIGluIGRpYWwgY29kZSBzZWxlY3Rpb24gbW9kYWwuXHJcbiAgICogU2VlIG1vcmUgb24uXHJcbiAgICpcclxuICAgKiBAbWVtYmVyb2YgSW9uSW50bFRlbElucHV0Q29tcG9uZW50XHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgcmVhZG9ubHkgY29kZVNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICBAVmlld0NoaWxkKCdudW1iZXJJbnB1dCcsIHsgc3RhdGljOiBmYWxzZSB9KSBudW1iZXJJbnB1dEVsITogSW9uSW5wdXQ7XHJcblxyXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogdmFyaWFibGUtbmFtZVxyXG4gIHByaXZhdGUgX3ZhbHVlITogSW9uSW50bFRlbElucHV0TW9kZWw7XHJcblxyXG4gIGNvdW50cnkhOiBDb3VudHJ5STtcclxuICBwaG9uZU51bWJlciA9ICcnO1xyXG4gIGNvdW50cmllczogQ291bnRyeUlbXSA9IFtdO1xyXG4gIGRpc2FibGVkID0gZmFsc2U7XHJcbiAgcGhvbmVVdGlsOiBhbnkgPSBQaG9uZU51bWJlclV0aWwuZ2V0SW5zdGFuY2UoKTtcclxuXHJcbiAgdHJhbnNsYXRpb25QcmVmaXggPSBgJHt0cmFuc2xhdGlvblByZWZpeH0uYDtcclxuXHJcbiAgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4ge307XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xyXG4gIHByb3BhZ2F0ZUNoYW5nZSA9IChfOiBJb25JbnRsVGVsSW5wdXRNb2RlbCB8IG51bGwpID0+IHt9O1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXHJcbiAgICBwcml2YXRlIHBsYXRmb3JtOiBQbGF0Zm9ybSxcclxuICAgIHByaXZhdGUgaW9uSW50bFRlbElucHV0U2VydmljZTogSW9uSW50bFRlbElucHV0U2VydmljZSxcclxuICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlXHJcbiAgKSB7fVxyXG5cclxuICBnZXQgdmFsdWUoKTogSW9uSW50bFRlbElucHV0TW9kZWwgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl92YWx1ZTtcclxuICB9XHJcblxyXG4gIHNldCB2YWx1ZSh2YWx1ZTogSW9uSW50bFRlbElucHV0TW9kZWwgfCBudWxsKSB7XHJcbiAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcclxuICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcclxuICAgICAgdGhpcy5zZXRJb25pY0NsYXNzZXModGhpcy5lbCk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGVtaXRWYWx1ZUNoYW5nZShjaGFuZ2U6IElvbkludGxUZWxJbnB1dE1vZGVsIHwgbnVsbCkge1xyXG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UoY2hhbmdlKTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5pc0lvcyA9IHRoaXMucGxhdGZvcm0uaXMoJ2lvcycpO1xyXG4gICAgdGhpcy5pc01EID0gIXRoaXMuaXNJb3M7XHJcbiAgICB0aGlzLnNldEl0ZW1DbGFzcyh0aGlzLmVsLCAnaXRlbS1pbnRlcmFjdGl2ZScsIHRydWUpO1xyXG5cclxuICAgIHRoaXMuZmV0Y2hBbGxDb3VudHJpZXMoKTtcclxuICAgIHRoaXMuc2V0UHJlZmVycmVkQ291bnRyaWVzKCk7XHJcblxyXG4gICAgaWYgKHRoaXMub25seUNvdW50cmllcy5sZW5ndGgpIHtcclxuICAgICAgdGhpcy5jb3VudHJpZXMgPSB0aGlzLmNvdW50cmllcy5maWx0ZXIoKGNvdW50cnk6IENvdW50cnlJKSA9PlxyXG4gICAgICAgIHRoaXMub25seUNvdW50cmllcy5pbmNsdWRlcyhjb3VudHJ5Lmlzb0NvZGUpXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc2VsZWN0Rmlyc3RDb3VudHJ5KSB7XHJcbiAgICAgIGlmICh0aGlzLmRlZmF1bHRDb3VudHJ5aXNvKSB7XHJcbiAgICAgICAgdGhpcy5zZXRDb3VudHJ5KFxyXG4gICAgICAgICAgdGhpcy5nZXRDb3VudHJ5QnlJc29Db2RlKHRoaXMuZGVmYXVsdENvdW50cnlpc28pIGFzIENvdW50cnlJXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICB0aGlzLnByZWZlcnJlZENvdW50cmllcy5sZW5ndGggJiZcclxuICAgICAgICAgIHRoaXMucHJlZmVycmVkQ291bnRyaWVzLmluY2x1ZGVzKHRoaXMuZGVmYXVsdENvdW50cnlpc28pXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICB0aGlzLnNldENvdW50cnkoXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0Q291bnRyeUJ5SXNvQ29kZSh0aGlzLnByZWZlcnJlZENvdW50cmllc1swXSkgYXMgQ291bnRyeUlcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuc2V0Q291bnRyeSh0aGlzLmNvdW50cmllc1swXSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMuY291bnRyaWVzICYmXHJcbiAgICAgIGNoYW5nZXNbJ2RlZmF1bHlDb3VudHJ5aXNvQ29kZSddICYmXHJcbiAgICAgIGNoYW5nZXNbJ2RlZmF1bHlDb3VudHJ5aXNvQ29kZSddLmN1cnJlbnRWYWx1ZSAhPT1cclxuICAgICAgICBjaGFuZ2VzWydkZWZhdWx5Q291bnRyeWlzb0NvZGUnXS5wcmV2aW91c1ZhbHVlXHJcbiAgICApIHtcclxuICAgICAgdGhpcy5zZXRDb3VudHJ5KGNoYW5nZXNbJ2RlZmF1bHlDb3VudHJ5aXNvQ29kZSddLmN1cnJlbnRWYWx1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMucHJvcGFnYXRlQ2hhbmdlID0gZm47XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xyXG4gIH1cclxuXHJcbiAgd3JpdGVWYWx1ZShvYmo6IElvbkludGxUZWxJbnB1dE1vZGVsKTogdm9pZCB7XHJcbiAgICB0aGlzLmZpbGxWYWx1ZXMob2JqKTtcclxuICB9XHJcblxyXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XHJcbiAgfVxyXG5cclxuICBmaWxsVmFsdWVzKHZhbHVlOiBJb25JbnRsVGVsSW5wdXRNb2RlbCkge1xyXG4gICAgaWYgKFxyXG4gICAgICB2YWx1ZSAmJlxyXG4gICAgICB2YWx1ZSAhPT0gbnVsbCAmJlxyXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXHJcbiAgICAgICF0aGlzLmlzTnVsbE9yV2hpdGVTcGFjZSh2YWx1ZSlcclxuICAgICkge1xyXG4gICAgICB0aGlzLnBob25lTnVtYmVyID0gdmFsdWUubmF0aW9uYWxOdW1iZXI7XHJcbiAgICAgIHRoaXMuc2V0Q291bnRyeSh0aGlzLmdldENvdW50cnlCeUlzb0NvZGUodmFsdWUuaXNvQ29kZSkgYXMgQ291bnRyeUkpO1xyXG4gICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICB0aGlzLnZhbHVlICYmXHJcbiAgICAgIHRoaXMudmFsdWUgIT09IG51bGwgJiZcclxuICAgICAgdHlwZW9mIHRoaXMudmFsdWUgPT09ICdvYmplY3QnICYmXHJcbiAgICAgICF0aGlzLmlzTnVsbE9yV2hpdGVTcGFjZSh0aGlzLnZhbHVlKVxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMucGhvbmVOdW1iZXIgPSB0aGlzLnZhbHVlLm5hdGlvbmFsTnVtYmVyO1xyXG4gICAgICB0aGlzLnNldENvdW50cnkodGhpcy5nZXRDb3VudHJ5QnlJc29Db2RlKHRoaXMudmFsdWUuaXNvQ29kZSkgYXMgQ291bnRyeUkpO1xyXG4gICAgfVxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMub25OdW1iZXJDaGFuZ2UoKTtcclxuICAgIH0sIDEpO1xyXG4gIH1cclxuXHJcbiAgaGFzVmFsdWUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gIXRoaXMuaXNOdWxsT3JXaGl0ZVNwYWNlKHRoaXMudmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgb25Db2RlT3BlbigpIHtcclxuICAgIHRoaXMuY29kZU9wZW4uZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgb25Db2RlQ2hhbmdlKGV2ZW50OiB7IGNvbXBvbmVudDogSW9uU2VsZWN0YWJsZUNvbXBvbmVudDsgdmFsdWU6IGFueSB9KTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5pc051bGxPcldoaXRlU3BhY2UodGhpcy5waG9uZU51bWJlcikpIHtcclxuICAgICAgdGhpcy5lbWl0VmFsdWVDaGFuZ2UobnVsbCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsZXQgZ29vZ2xlTnVtYmVyOiBQaG9uZU51bWJlciB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgZ29vZ2xlTnVtYmVyID0gdGhpcy5waG9uZVV0aWwucGFyc2UoXHJcbiAgICAgICAgICB0aGlzLnBob25lTnVtYmVyLFxyXG4gICAgICAgICAgdGhpcy5jb3VudHJ5Lmlzb0NvZGUudG9VcHBlckNhc2UoKVxyXG4gICAgICAgICk7XHJcbiAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAvLyBIYW5kbGUgcGFyc2UgZXJyb3IgaWYgbmVlZGVkXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IGludGVybmF0aW9uYWxsTm8gPSBnb29nbGVOdW1iZXJcclxuICAgICAgICA/IHRoaXMucGhvbmVVdGlsLmZvcm1hdChnb29nbGVOdW1iZXIsIFBob25lTnVtYmVyRm9ybWF0LklOVEVSTkFUSU9OQUwpXHJcbiAgICAgICAgOiAnJztcclxuICAgICAgY29uc3QgbmF0aW9uYWxObyA9IGdvb2dsZU51bWJlclxyXG4gICAgICAgID8gdGhpcy5waG9uZVV0aWwuZm9ybWF0KGdvb2dsZU51bWJlciwgUGhvbmVOdW1iZXJGb3JtYXQuTkFUSU9OQUwpXHJcbiAgICAgICAgOiAnJztcclxuXHJcbiAgICAgIGNvbnN0IGUxNjROdW1iZXIgPSBnb29nbGVOdW1iZXJcclxuICAgICAgICA/IHRoaXMucGhvbmVVdGlsLmZvcm1hdChnb29nbGVOdW1iZXIsIFBob25lTnVtYmVyRm9ybWF0LkUxNjQpXHJcbiAgICAgICAgOiAnJztcclxuXHJcbiAgICAgIGlmICh0aGlzLnNlcGFyYXRlRGlhbENvZGUgJiYgaW50ZXJuYXRpb25hbGxObykge1xyXG4gICAgICAgIHRoaXMucGhvbmVOdW1iZXIgPSB0aGlzLnJlbW92ZURpYWxDb2RlKGludGVybmF0aW9uYWxsTm8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmVtaXRWYWx1ZUNoYW5nZSh7XHJcbiAgICAgICAgZTE2NE51bWJlcjogZTE2NE51bWJlcixcclxuICAgICAgICBpbnRlcm5hdGlvbmFsTnVtYmVyOiBpbnRlcm5hdGlvbmFsbE5vLFxyXG4gICAgICAgIG5hdGlvbmFsTnVtYmVyOiBuYXRpb25hbE5vLFxyXG4gICAgICAgIGlzb0NvZGU6IHRoaXMuY291bnRyeS5pc29Db2RlLFxyXG4gICAgICAgIGRpYWxDb2RlOiB0aGlzLmRpYWxDb2RlUHJlZml4ICsgdGhpcy5jb3VudHJ5LmRpYWxDb2RlLFxyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5jb2RlQ2hhbmdlLmVtaXQoKTtcclxuICAgIH1cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB0aGlzLm51bWJlcklucHV0RWwuc2V0Rm9jdXMoKTtcclxuICAgIH0sIDQwMCk7XHJcbiAgfVxyXG5cclxuICBvbkNvZGVDbG9zZSgpIHtcclxuICAgIHRoaXMub25Ub3VjaGVkKCk7XHJcbiAgICB0aGlzLnNldElvbmljQ2xhc3Nlcyh0aGlzLmVsKTtcclxuICAgIHRoaXMuaGFzRm9jdXMgPSBmYWxzZTtcclxuICAgIHRoaXMuc2V0SXRlbUNsYXNzKHRoaXMuZWwsICdpdGVtLWhhcy1mb2N1cycsIGZhbHNlKTtcclxuICAgIHRoaXMuY29kZUNsb3NlLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbkNvZGVTZWFyY2hDb3VudHJpZXMoZXZlbnQ6IHtcclxuICAgIGNvbXBvbmVudDogSW9uU2VsZWN0YWJsZUNvbXBvbmVudDtcclxuICAgIHRleHQ6IHN0cmluZztcclxuICB9KTogdm9pZCB7XHJcbiAgICBjb25zdCB0ZXh0ID0gZXZlbnQudGV4dC50cmltKCkudG9Mb3dlckNhc2UoKTtcclxuICAgIGV2ZW50LmNvbXBvbmVudC5zdGFydFNlYXJjaCgpO1xyXG5cclxuICAgIGV2ZW50LmNvbXBvbmVudC5pdGVtcyA9IHRoaXMuZmlsdGVyQ291bnRyaWVzKHRleHQpO1xyXG4gICAgZXZlbnQuY29tcG9uZW50LmVuZFNlYXJjaCgpO1xyXG4gIH1cclxuXHJcbiAgb25Db2RlU2VsZWN0KCkge1xyXG4gICAgdGhpcy5jb2RlU2VsZWN0LmVtaXQoKTtcclxuICB9XHJcblxyXG4gIG9uSW9uTnVtYmVyQ2hhbmdlKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5zZXRJb25pY0NsYXNzZXModGhpcy5lbCk7XHJcbiAgICB0aGlzLm51bWJlckNoYW5nZS5lbWl0KGV2ZW50KTtcclxuICB9XHJcblxyXG4gIG9uSW9uTnVtYmVyQmx1cigpIHtcclxuICAgIHRoaXMub25Ub3VjaGVkKCk7XHJcbiAgICB0aGlzLnNldElvbmljQ2xhc3Nlcyh0aGlzLmVsKTtcclxuICAgIHRoaXMuaGFzRm9jdXMgPSBmYWxzZTtcclxuICAgIHRoaXMuc2V0SXRlbUNsYXNzKHRoaXMuZWwsICdpdGVtLWhhcy1mb2N1cycsIGZhbHNlKTtcclxuICAgIHRoaXMubnVtYmVyQmx1ci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBvbklvbk51bWJlckZvY3VzKCkge1xyXG4gICAgdGhpcy5oYXNGb2N1cyA9IHRydWU7XHJcbiAgICB0aGlzLnNldEl0ZW1DbGFzcyh0aGlzLmVsLCAnaXRlbS1oYXMtZm9jdXMnLCB0cnVlKTtcclxuICAgIHRoaXMubnVtYmVyRm9jdXMuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgb25Jb25OdW1iZXJJbnB1dChldmVudCkge1xyXG4gICAgdGhpcy5udW1iZXJJbnB1dC5lbWl0KGV2ZW50KTtcclxuICB9XHJcblxyXG4gIG9uTnVtYmVyQ2hhbmdlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnBob25lTnVtYmVyKSB7XHJcbiAgICAgIHRoaXMudmFsdWUgPSBudWxsO1xyXG4gICAgICB0aGlzLmVtaXRWYWx1ZUNoYW5nZShudWxsKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuY291bnRyeSkge1xyXG4gICAgICB0aGlzLmVtaXRWYWx1ZUNoYW5nZSh7XHJcbiAgICAgICAgZTE2NE51bWJlcjpcclxuICAgICAgICAgIHRoaXMuZGlhbENvZGVQcmVmaXggKyB0aGlzLmNvdW50cnkuZGlhbENvZGUgKyB0aGlzLnBob25lTnVtYmVyLFxyXG4gICAgICAgIGludGVybmF0aW9uYWxOdW1iZXI6XHJcbiAgICAgICAgICB0aGlzLmRpYWxDb2RlUHJlZml4ICsgdGhpcy5jb3VudHJ5LmRpYWxDb2RlICsgJyAnICsgdGhpcy5waG9uZU51bWJlcixcclxuICAgICAgICBuYXRpb25hbE51bWJlcjogdGhpcy5waG9uZU51bWJlcixcclxuICAgICAgICBpc29Db2RlOiB0aGlzLmNvdW50cnkuaXNvQ29kZSxcclxuICAgICAgICBkaWFsQ29kZTogdGhpcy5kaWFsQ29kZVByZWZpeCArIHRoaXMuY291bnRyeS5kaWFsQ29kZSxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBsZXQgZ29vZ2xlTnVtYmVyOiBQaG9uZU51bWJlciB8IHVuZGVmaW5lZDtcclxuICAgIHRyeSB7XHJcbiAgICAgIGdvb2dsZU51bWJlciA9IHRoaXMucGhvbmVVdGlsLnBhcnNlKFxyXG4gICAgICAgIHRoaXMucGhvbmVOdW1iZXIsXHJcbiAgICAgICAgdGhpcy5jb3VudHJ5Lmlzb0NvZGUudG9VcHBlckNhc2UoKVxyXG4gICAgICApO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGlzb0NvZGU6IHN0cmluZyB8IG51bGwgPSB0aGlzLmNvdW50cnkgPyB0aGlzLmNvdW50cnkuaXNvQ29kZSA6IG51bGw7XHJcbiAgICAvLyBhdXRvIHNlbGVjdCBjb3VudHJ5IGJhc2VkIG9uIHRoZSBleHRlbnNpb24gKGFuZCBhcmVhQ29kZSBpZiBuZWVkZWQpIChlLmcgc2VsZWN0IENhbmFkYSBpZiBudW1iZXIgc3RhcnRzIHdpdGggKzEgNDE2KVxyXG4gICAgaWYgKHRoaXMuZW5hYmxlQXV0b0NvdW50cnlTZWxlY3QpIHtcclxuICAgICAgaXNvQ29kZSA9XHJcbiAgICAgICAgZ29vZ2xlTnVtYmVyICYmIGdvb2dsZU51bWJlci5nZXRDb3VudHJ5Q29kZSgpXHJcbiAgICAgICAgICA/IHRoaXMuZ2V0Q291bnRyeUlzb0NvZGUoZ29vZ2xlTnVtYmVyLmdldENvdW50cnlDb2RlKCksIGdvb2dsZU51bWJlcilcclxuICAgICAgICAgIDogdGhpcy5jb3VudHJ5Lmlzb0NvZGU7XHJcblxyXG4gICAgICBpZiAoaXNvQ29kZSAmJiBpc29Db2RlICE9PSB0aGlzLmNvdW50cnkuaXNvQ29kZSkge1xyXG4gICAgICAgIGNvbnN0IG5ld0NvdW50cnkgPSB0aGlzLmNvdW50cmllcy5maW5kKFxyXG4gICAgICAgICAgKGNvdW50cnk6IENvdW50cnlJKSA9PiBjb3VudHJ5Lmlzb0NvZGUgPT09IGlzb0NvZGVcclxuICAgICAgICApO1xyXG4gICAgICAgIGlmIChuZXdDb3VudHJ5KSB7XHJcbiAgICAgICAgICB0aGlzLmNvdW50cnkgPSBuZXdDb3VudHJ5O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaXNvQ29kZSA9IGlzb0NvZGUgPyBpc29Db2RlIDogdGhpcy5jb3VudHJ5ID8gdGhpcy5jb3VudHJ5Lmlzb0NvZGUgOiBudWxsO1xyXG5cclxuICAgIGlmICghdGhpcy5waG9uZU51bWJlciB8fCAhaXNvQ29kZSkge1xyXG4gICAgICB0aGlzLmVtaXRWYWx1ZUNoYW5nZShudWxsKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGludGVybmF0aW9uYWxsTm8gPSBnb29nbGVOdW1iZXJcclxuICAgICAgICA/IHRoaXMucGhvbmVVdGlsLmZvcm1hdChnb29nbGVOdW1iZXIsIFBob25lTnVtYmVyRm9ybWF0LklOVEVSTkFUSU9OQUwpXHJcbiAgICAgICAgOiAnJztcclxuICAgICAgY29uc3QgbmF0aW9uYWxObyA9IGdvb2dsZU51bWJlclxyXG4gICAgICAgID8gdGhpcy5waG9uZVV0aWwuZm9ybWF0KGdvb2dsZU51bWJlciwgUGhvbmVOdW1iZXJGb3JtYXQuTkFUSU9OQUwpXHJcbiAgICAgICAgOiAnJztcclxuXHJcbiAgICAgIGNvbnN0IGUxNjROdW1iZXIgPSBnb29nbGVOdW1iZXJcclxuICAgICAgICA/IHRoaXMucGhvbmVVdGlsLmZvcm1hdChnb29nbGVOdW1iZXIsIFBob25lTnVtYmVyRm9ybWF0LkUxNjQpXHJcbiAgICAgICAgOiAnJztcclxuXHJcbiAgICAgIGlmICh0aGlzLnNlcGFyYXRlRGlhbENvZGUgJiYgaW50ZXJuYXRpb25hbGxObykge1xyXG4gICAgICAgIHRoaXMucGhvbmVOdW1iZXIgPSB0aGlzLnJlbW92ZURpYWxDb2RlKGludGVybmF0aW9uYWxsTm8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmVtaXRWYWx1ZUNoYW5nZSh7XHJcbiAgICAgICAgZTE2NE51bWJlcjogZTE2NE51bWJlcixcclxuICAgICAgICBpbnRlcm5hdGlvbmFsTnVtYmVyOiBpbnRlcm5hdGlvbmFsbE5vLFxyXG4gICAgICAgIG5hdGlvbmFsTnVtYmVyOiBuYXRpb25hbE5vLFxyXG4gICAgICAgIGlzb0NvZGU6IHRoaXMuY291bnRyeS5pc29Db2RlLFxyXG4gICAgICAgIGRpYWxDb2RlOiB0aGlzLmRpYWxDb2RlUHJlZml4ICsgdGhpcy5jb3VudHJ5LmRpYWxDb2RlLFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uTnVtYmVyS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgY29uc3QgYWxsb3dlZENoYXJzID0gL15bMC05XFwrXFwtXFwoXFwpXFwuXFwgXS87XHJcbiAgICBjb25zdCBhbGxvd2VkQ3RybENoYXJzID0gL1theGN2XS87XHJcbiAgICBjb25zdCBhbGxvd2VkT3RoZXJLZXlzID0gW1xyXG4gICAgICAnQXJyb3dMZWZ0JyxcclxuICAgICAgJ0Fycm93VXAnLFxyXG4gICAgICAnQXJyb3dSaWdodCcsXHJcbiAgICAgICdBcnJvd0Rvd24nLFxyXG4gICAgICAnSG9tZScsXHJcbiAgICAgICdFbmQnLFxyXG4gICAgICAnSW5zZXJ0JyxcclxuICAgICAgJ0RlbGV0ZScsXHJcbiAgICAgICdCYWNrc3BhY2UnLFxyXG4gICAgICAnVGFiJyxcclxuICAgIF07XHJcblxyXG4gICAgY29uc3QgaXNDdHJsS2V5ID0gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5O1xyXG5cclxuICAgIGlmIChcclxuICAgICAgIWFsbG93ZWRDaGFycy50ZXN0KGV2ZW50LmtleSkgJiZcclxuICAgICAgIShpc0N0cmxLZXkgJiYgYWxsb3dlZEN0cmxDaGFycy50ZXN0KGV2ZW50LmtleSkpICYmXHJcbiAgICAgICFhbGxvd2VkT3RoZXJLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSlcclxuICAgICkge1xyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBmaWx0ZXJDb3VudHJpZXModGV4dDogc3RyaW5nKTogQ291bnRyeUlbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5jb3VudHJpZXMuZmlsdGVyKChjb3VudHJ5KSA9PiB7XHJcbiAgICAgIHJldHVybiAoXHJcbiAgICAgICAgY291bnRyeS5uYW1lLnRvTG93ZXJDYXNlKCkuaW5kZXhPZih0ZXh0KSAhPT0gLTEgfHxcclxuICAgICAgICBjb3VudHJ5Lm5hbWUudG9Mb3dlckNhc2UoKS5pbmRleE9mKHRleHQpICE9PSAtMSB8fFxyXG4gICAgICAgIGNvdW50cnkuZGlhbENvZGUudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLmluZGV4T2YodGV4dCkgIT09IC0xXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Q291bnRyeUlzb0NvZGUoXHJcbiAgICBjb3VudHJ5Q29kZTogbnVtYmVyIHwgdW5kZWZpbmVkLFxyXG4gICAgZ29vZ2xlTnVtYmVyOiBQaG9uZU51bWJlclxyXG4gICk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgcmF3TnVtYmVyID0gKGdvb2dsZU51bWJlciBhcyBhbnkpLnZhbHVlc19bMl0udG9TdHJpbmcoKTtcclxuXHJcbiAgICBjb25zdCBjb3VudHJpZXMgPSB0aGlzLmNvdW50cmllcy5maWx0ZXIoXHJcbiAgICAgIChjb3VudHJ5OiBDb3VudHJ5SSkgPT5cclxuICAgICAgICBjb3VudHJ5LmRpYWxDb2RlID09PSAoY291bnRyeUNvZGUgYXMgbnVtYmVyKS50b1N0cmluZygpXHJcbiAgICApO1xyXG4gICAgY29uc3QgbWFpbkNvdW50cnkgPSBjb3VudHJpZXMuZmluZChcclxuICAgICAgKGNvdW50cnk6IENvdW50cnlJKSA9PiBjb3VudHJ5LmFyZWFDb2RlcyA9PT0gdW5kZWZpbmVkXHJcbiAgICApO1xyXG4gICAgY29uc3Qgc2Vjb25kYXJ5Q291bnRyaWVzID0gY291bnRyaWVzLmZpbHRlcihcclxuICAgICAgKGNvdW50cnk6IENvdW50cnlJKSA9PiBjb3VudHJ5LmFyZWFDb2RlcyAhPT0gdW5kZWZpbmVkXHJcbiAgICApO1xyXG5cclxuICAgIGxldCBtYXRjaGVkQ291bnRyeSA9IG1haW5Db3VudHJ5ID8gbWFpbkNvdW50cnkuaXNvQ29kZSA6IG51bGw7XHJcblxyXG4gICAgc2Vjb25kYXJ5Q291bnRyaWVzLmZvckVhY2goKGNvdW50cnkpID0+IHtcclxuICAgICAgaWYgKGNvdW50cnkuYXJlYUNvZGVzKSB7XHJcbiAgICAgICAgLy8gRW5zdXJlIGNvdW50cnkuYXJlYUNvZGVzIGlzIGRlZmluZWRcclxuICAgICAgICBjb3VudHJ5LmFyZWFDb2Rlcy5mb3JFYWNoKChhcmVhQ29kZSkgPT4ge1xyXG4gICAgICAgICAgaWYgKHJhd051bWJlci5zdGFydHNXaXRoKGFyZWFDb2RlKSkge1xyXG4gICAgICAgICAgICBtYXRjaGVkQ291bnRyeSA9IGNvdW50cnkuaXNvQ29kZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIG1hdGNoZWRDb3VudHJ5O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFsbENvdW50cmllcygpIHtcclxuICAgIHRoaXMuY291bnRyaWVzID0gdGhpcy5pb25JbnRsVGVsSW5wdXRTZXJ2aWNlLmdldExpc3RPZkNvdW50cmllcygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRDb3VudHJ5QnlJc29Db2RlKGlzb0NvZGU6IHN0cmluZyk6IENvdW50cnlJIHwgdW5kZWZpbmVkIHtcclxuICAgIGZvciAoY29uc3QgY291bnRyeSBvZiB0aGlzLmNvdW50cmllcykge1xyXG4gICAgICBpZiAoY291bnRyeS5pc29Db2RlID09PSBpc29Db2RlKSB7XHJcbiAgICAgICAgcmV0dXJuIGNvdW50cnk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpc051bGxPcldoaXRlU3BhY2UodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZSA9PT0gJycpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZW1vdmVEaWFsQ29kZShwaG9uZU51bWJlcjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLnNlcGFyYXRlRGlhbENvZGUgJiYgcGhvbmVOdW1iZXIpIHtcclxuICAgICAgcGhvbmVOdW1iZXIgPSBwaG9uZU51bWJlci5zdWJzdHIocGhvbmVOdW1iZXIuaW5kZXhPZignICcpICsgMSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGhvbmVOdW1iZXI7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNldENvdW50cnkoY291bnRyeTogQ291bnRyeUkpOiB2b2lkIHtcclxuICAgIHRoaXMuY291bnRyeSA9IGNvdW50cnk7XHJcbiAgICB0aGlzLmNvZGVDaGFuZ2UuZW1pdCh0aGlzLmNvdW50cnkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZXRQcmVmZXJyZWRDb3VudHJpZXMoKTogdm9pZCB7XHJcbiAgICBmb3IgKGNvbnN0IHByZWZlcnJlZENvdW50cnlJc29Db2RlIG9mIHRoaXMucHJlZmVycmVkQ291bnRyaWVzKSB7XHJcbiAgICAgIGNvbnN0IGNvdW50cnkgPSB0aGlzLmdldENvdW50cnlCeUlzb0NvZGUocHJlZmVycmVkQ291bnRyeUlzb0NvZGUpO1xyXG4gICAgICBpZiAoY291bnRyeSkge1xyXG4gICAgICAgIC8vIEVuc3VyZSBjb3VudHJ5IGlzIGRlZmluZWRcclxuICAgICAgICBjb3VudHJ5LnByaW9yaXR5ID0gMTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5jb3VudHJpZXMuc29ydCgoYSwgYikgPT5cclxuICAgICAgYS5wcmlvcml0eSA+IGIucHJpb3JpdHkgPyAtMSA6IGEucHJpb3JpdHkgPCBiLnByaW9yaXR5ID8gMSA6IDBcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0YXJ0c1dpdGggPSAoaW5wdXQ6IHN0cmluZywgc2VhcmNoOiBzdHJpbmcpOiBib29sZWFuID0+IHtcclxuICAgIHJldHVybiBpbnB1dC5zdWJzdHIoMCwgc2VhcmNoLmxlbmd0aCkgPT09IHNlYXJjaDtcclxuICB9O1xyXG5cclxuICBwcml2YXRlIGdldENsYXNzZXMgPSAoZWxlbWVudDogSFRNTEVsZW1lbnQpID0+IHtcclxuICAgIGNvbnN0IGNsYXNzTGlzdCA9IGVsZW1lbnQuY2xhc3NMaXN0O1xyXG4gICAgY29uc3QgY2xhc3NlcyA9IFtdO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjbGFzc0xpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgY29uc3QgaXRlbSA9IGNsYXNzTGlzdC5pdGVtKGkpO1xyXG4gICAgICBpZiAoaXRlbSAhPT0gbnVsbCAmJiB0aGlzLnN0YXJ0c1dpdGgoaXRlbSwgJ25nLScpKSB7XHJcbiAgICAgICAgY2xhc3Nlcy5wdXNoKGBpb24tJHtpdGVtLnN1YnN0cigzKX1gKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNsYXNzZXM7XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBzZXRDbGFzc2VzID0gKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBjbGFzc2VzOiBzdHJpbmdbXSkgPT4ge1xyXG4gICAgY29uc3QgY2xhc3NMaXN0ID0gZWxlbWVudC5jbGFzc0xpc3Q7XHJcbiAgICBbXHJcbiAgICAgICdpb24tdmFsaWQnLFxyXG4gICAgICAnaW9uLWludmFsaWQnLFxyXG4gICAgICAnaW9uLXRvdWNoZWQnLFxyXG4gICAgICAnaW9uLXVudG91Y2hlZCcsXHJcbiAgICAgICdpb24tZGlydHknLFxyXG4gICAgICAnaW9uLXByaXN0aW5lJyxcclxuICAgIF0uZm9yRWFjaCgoYykgPT4gY2xhc3NMaXN0LnJlbW92ZShjKSk7XHJcblxyXG4gICAgY2xhc3Nlcy5mb3JFYWNoKChjKSA9PiBjbGFzc0xpc3QuYWRkKGMpKTtcclxuICB9O1xyXG5cclxuICBwcml2YXRlIHNldElvbmljQ2xhc3NlcyA9IChlbGVtZW50OiBFbGVtZW50UmVmKSA9PiB7XHJcbiAgICByYWYoKCkgPT4ge1xyXG4gICAgICBjb25zdCBpbnB1dCA9IGVsZW1lbnQubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgY29uc3QgY2xhc3NlcyA9IHRoaXMuZ2V0Q2xhc3NlcyhpbnB1dCk7XHJcbiAgICAgIHRoaXMuc2V0Q2xhc3NlcyhpbnB1dCwgY2xhc3Nlcyk7XHJcblxyXG4gICAgICBjb25zdCBpdGVtID0gaW5wdXQuY2xvc2VzdCgnaW9uLWl0ZW0nKTtcclxuICAgICAgaWYgKGl0ZW0pIHtcclxuICAgICAgICB0aGlzLnNldENsYXNzZXMoaXRlbSwgY2xhc3Nlcyk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgc2V0SXRlbUNsYXNzID0gKFxyXG4gICAgZWxlbWVudDogRWxlbWVudFJlZixcclxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxyXG4gICAgYWRkQ2xhc3M6IGJvb2xlYW5cclxuICApID0+IHtcclxuICAgIGNvbnN0IGlucHV0ID0gZWxlbWVudC5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xyXG4gICAgY29uc3QgaXRlbSA9IGlucHV0LmNsb3Nlc3QoJ2lvbi1pdGVtJyk7XHJcbiAgICBpZiAoaXRlbSkge1xyXG4gICAgICBjb25zdCBjbGFzc0xpc3QgPSBpdGVtLmNsYXNzTGlzdDtcclxuICAgICAgaWYgKGFkZENsYXNzKSB7XHJcbiAgICAgICAgY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImlvbi1pbnRsLXRlbC1pbnB1dC1jb2RlXCI+XHJcbiAgPGlvbi1zZWxlY3RhYmxlXHJcbiAgICAjY29kZVNlbGVjdFxyXG4gICAgWyhuZ01vZGVsKV09XCJjb3VudHJ5XCJcclxuICAgIFtjYW5TZWFyY2hdPVwibW9kYWxDYW5TZWFyY2hcIlxyXG4gICAgY2xvc2VCdXR0b25UZXh0PVwie3sgbW9kYWxDbG9zZVRleHQgfX1cIlxyXG4gICAgY2xvc2VCdXR0b25TbG90PVwie3sgbW9kYWxDbG9zZUJ1dHRvblNsb3QgfX1cIlxyXG4gICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcclxuICAgIFtoYXNWaXJ0dWFsU2Nyb2xsXT1cInRydWVcIlxyXG4gICAgaXRlbVRleHRGaWVsZD1cIm5hbWVcIlxyXG4gICAgW2l0ZW1zXT1cImNvdW50cmllc1wiXHJcbiAgICBbaXRlbUljb25TbG90XT1cIm1vZGFsSXRlbUljb25TbG90XCJcclxuICAgIGl0ZW1WYWx1ZUZpZWxkPVwiaXNvQ29kZVwiXHJcbiAgICBtb2RhbENzc0NsYXNzPVwiaW9uaWMtdGVsLWlucHV0LW1vZGFsIHt7IG1vZGFsQ3NzQ2xhc3MgfX1cIlxyXG4gICAgcGxhY2Vob2xkZXI9XCJ7eyBkcm9wZG93blBsYWNlaG9sZGVyIH19XCJcclxuICAgIHNlYXJjaEZhaWxUZXh0PVwie3sgbW9kYWxTZWFyY2hGYWlsVGV4dCB9fVwiXHJcbiAgICBzZWFyY2hQbGFjZWhvbGRlcj1cInt7IG1vZGFsU2VhcmNoUGxhY2Vob2xkZXIgfX1cIlxyXG4gICAgW3Nob3VsZEJhY2tkcm9wQ2xvc2VdPVwibW9kYWxTaG91bGRCYWNrZHJvcENsb3NlXCJcclxuICAgIFtzaG91bGRGb2N1c1NlYXJjaGJhcl09XCJtb2RhbFNob3VsZEZvY3VzU2VhcmNoYmFyXCJcclxuICAgIChvbkNoYW5nZSk9XCJvbkNvZGVDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAob25DbG9zZSk9XCJvbkNvZGVDbG9zZSgpXCJcclxuICAgIChvbk9wZW4pPVwib25Db2RlT3BlbigpXCJcclxuICAgIChvblNlYXJjaCk9XCJvbkNvZGVTZWFyY2hDb3VudHJpZXMoJGV2ZW50KVwiXHJcbiAgICAob25TZWxlY3QpPVwib25Db2RlU2VsZWN0KClcIlxyXG4gID5cclxuICAgIDxuZy10ZW1wbGF0ZSBpb25TZWxlY3RhYmxlVGl0bGVUZW1wbGF0ZT5cclxuICAgICAge3sgbW9kYWxUaXRsZSB9fVxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgIDxuZy10ZW1wbGF0ZSBpb25TZWxlY3RhYmxlVmFsdWVUZW1wbGF0ZSBsZXQtY291bnRyeT1cInZhbHVlXCI+XHJcbiAgICAgIDxzcGFuXHJcbiAgICAgICAgY2xhc3M9XCJmaSBmaS17eyBjb3VudHJ5LmZsYWdDbGFzcyB9fVwiXHJcbiAgICAgICAgc3R5bGU9XCJib3JkZXItcmFkaXVzOiAzcHhcIlxyXG4gICAgICA+PC9zcGFuPlxyXG4gICAgICA8c3BhbiAqbmdJZj1cInNlcGFyYXRlRGlhbENvZGVcIlxyXG4gICAgICAgID57eyBkaWFsQ29kZVByZWZpeCB9fXt7IGNvdW50cnkuZGlhbENvZGUgfX08L3NwYW5cclxuICAgICAgPlxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgIDxuZy10ZW1wbGF0ZSBpb25TZWxlY3RhYmxlSXRlbVRlbXBsYXRlIGxldC1jb3VudHJ5PVwiaXRlbVwiPlxyXG4gICAgICA8c3BhblxyXG4gICAgICAgIGNsYXNzPVwiaW9uLW1hcmdpbi1lbmRcIlxyXG4gICAgICAgIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmF5OyBwYWRkaW5nOiA1cHg7IGJvcmRlci1yYWRpdXM6IDVweFwiXHJcbiAgICAgID5cclxuICAgICAgICA8c3BhblxyXG4gICAgICAgICAgY2xhc3M9XCJmaSBmaS17eyBjb3VudHJ5LmZsYWdDbGFzcyB9fVwiXHJcbiAgICAgICAgICBzdHlsZT1cImJvcmRlci1yYWRpdXM6IDNweFwiXHJcbiAgICAgICAgPjwvc3Bhbj5cclxuICAgICAgPC9zcGFuPlxyXG4gICAgICA8c3BhbiBjbGFzcz1cImlvbi1tYXJnaW4tZW5kXCI+e3sgY291bnRyeS5uYW1lIH19PC9zcGFuPlxyXG4gICAgICA8c3BhbiAqbmdJZj1cInNlcGFyYXRlRGlhbENvZGVcIlxyXG4gICAgICAgID57eyBkaWFsQ29kZVByZWZpeCB9fXt7IGNvdW50cnkuZGlhbENvZGUgfX08L3NwYW5cclxuICAgICAgPlxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgIDxuZy10ZW1wbGF0ZSBpb25TZWxlY3RhYmxlQ2xvc2VCdXR0b25UZW1wbGF0ZT5cclxuICAgICAgPGlvbi1pY29uIG5hbWU9XCJjbG9zZS1vdXRsaW5lXCI+PC9pb24taWNvbj5cclxuICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICA8IS0tIDxuZy10ZW1wbGF0ZSBpb25TZWxlY3RhYmxlSXRlbUVuZFRlbXBsYXRlIGxldC1jb3VudHJ5PVwiaXRlbVwiPlxyXG4gICAgICA8c3BhbiBjbGFzcz1cImZpIGZpLXt7Y291bnRyeS5mbGFnQ2xhc3N9fVwiPjwvc3Bhbj5cclxuICAgIDwvbmctdGVtcGxhdGU+IC0tPlxyXG4gIDwvaW9uLXNlbGVjdGFibGU+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cImlvbi1pbnRsLXRlbC1pbnB1dC1udW1iZXJcIj5cclxuICA8aW9uLWlucHV0XHJcbiAgICAjbnVtYmVySW5wdXRcclxuICAgIFsobmdNb2RlbCldPVwicGhvbmVOdW1iZXJcIlxyXG4gICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcclxuICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXHJcbiAgICBbYXR0ci5tYXhMZW5ndGhdPVwibWF4TGVuZ3RoXCJcclxuICAgIHR5cGU9XCJ0ZWxcIlxyXG4gICAgKGlvbkJsdXIpPVwib25Jb25OdW1iZXJCbHVyKClcIlxyXG4gICAgKGlvbkNoYW5nZSk9XCJvbklvbk51bWJlckNoYW5nZSgkZXZlbnQpXCJcclxuICAgIChpb25Gb2N1cyk9XCJvbklvbk51bWJlckZvY3VzKClcIlxyXG4gICAgKGlvbklucHV0KT1cIm9uSW9uTnVtYmVySW5wdXQoJGV2ZW50KVwiXHJcbiAgICAoa2V5ZG93bik9XCJvbk51bWJlcktleURvd24oJGV2ZW50KVwiXHJcbiAgICAobmdNb2RlbENoYW5nZSk9XCJvbk51bWJlckNoYW5nZSgpXCJcclxuICAgIHBsYWNlaG9sZGVyPVwie3tcclxuICAgICAgY291bnRyeVxyXG4gICAgICAgIHwgY291bnRyeVBsYWNlaG9sZGVyXHJcbiAgICAgICAgICA6IGVuYWJsZVBsYWNlaG9sZGVyXHJcbiAgICAgICAgICA6IGlucHV0UGxhY2Vob2xkZXJcclxuICAgICAgICAgIDogc2VwYXJhdGVEaWFsQ29kZVxyXG4gICAgICAgICAgOiBmYWxsYmFja1BsYWNlaG9sZGVyXHJcbiAgICB9fVwiXHJcbiAgPlxyXG4gIDwvaW9uLWlucHV0PlxyXG48L2Rpdj5cclxuIl19