@junte/ui
Version:
Quality Angular UI components kit
453 lines • 50.2 kB
JavaScript
var InputComponent_1;
import { __decorate, __metadata } from "tslib";
import { Component, ElementRef, EventEmitter, forwardRef, HostBinding, HostListener, Input, Output, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NGXLogger } from 'ngx-logger';
import { filter, map, distinctUntilChanged } from 'rxjs/operators';
import { Key } from '../../core/enums/keyboard';
import { PropertyApi } from '../../core/decorators/api';
import { Feature } from '../../core/enums/feature';
import { Size } from '../../core/enums/size';
import { State } from '../../core/enums/state';
import { TextAlign, TextTransform } from '../../core/enums/text';
import { UI } from '../../core/enums/ui';
import { Width } from '../../core/enums/width';
import { InputAutocomplete, InputScheme, InputType } from './enums';
const DIGIT_MASK_CHAR = '_';
const DIGIT_KEYS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
const DEFAULT_NUMBER = 0;
let InputComponent = InputComponent_1 = class InputComponent {
constructor(logger, fb) {
this.logger = logger;
this.fb = fb;
this.host = 'jnt-input-host';
this.ui = UI;
this.view = { password: { display: false } };
this._type = InputType.text;
this._placeholder = '';
this.inputControl = this.fb.control(null);
this.formattedControl = this.fb.control(null);
this.form = this.fb.group({
input: this.inputControl,
formatted: this.formattedControl
});
this.focused = false;
this.disabled = false;
this._scheme = InputScheme.normal;
this._size = Size.normal;
this._width = Width.default;
this.name = null;
this.autocomplete = InputAutocomplete.off;
this.textAlign = TextAlign.left;
this.min = null;
this.max = null;
this.step = 1;
this.readonly = false;
this.rows = 5;
this.features = [];
this.click = new EventEmitter();
this.tabindex = 1;
this.onChange = () => this.logger.error('value accessor is not registered');
this.onTouched = () => this.logger.error('value accessor is not registered');
this.registerOnChange = fn => this.onChange = fn;
this.registerOnTouched = fn => this.onTouched = fn;
this.onBlur = () => this.onTouched();
}
get withIcon() {
return !!this.icon;
}
set scheme(scheme) {
this._scheme = scheme || InputScheme.normal;
}
set placeholder(placeholder) {
this._placeholder = placeholder || '';
}
get placeholder() {
return this._placeholder;
}
set type(type) {
this._type = type || InputType.text;
}
get type() {
return this._type;
}
set size(size) {
this._size = size || Size.normal;
}
set width(width) {
this._width = width || Width.default;
}
set mask(mask) {
this._mask = mask;
if (!!mask) {
this.form.setValue(this.masking(this.inputControl.value || ''));
}
}
get mask() {
return this._mask;
}
ngOnInit() {
this.inputControl.valueChanges.subscribe(value => this.onChange(!!value ? (this.type === InputType.number ? +value : value) : null));
this.formattedControl.valueChanges.pipe(distinctUntilChanged(), filter(() => !!this.maskedInput), map(formatted => !!formatted ? formatted : this.mask)).subscribe(formatted => {
const position = formatted.indexOf(DIGIT_MASK_CHAR);
this.maskedInput.nativeElement.setSelectionRange(position, position);
let cleared = { input: null, formatted: null };
for (let i = 0; i < this.mask.length; i++) {
if (this.mask.charAt(i) !== formatted.charAt(i)) {
cleared = this.masking(formatted.substr(i));
break;
}
}
if (cleared.input !== this.inputControl.value || cleared.formatted !== this.formattedControl.value) {
this.form.setValue(cleared);
}
});
}
masking(value = null) {
const chars = !!value ? value.replace(/\D/gi, '') : '';
let formatted = this.mask;
const length = this.mask.split(DIGIT_MASK_CHAR).length - 1;
for (let char of chars) {
formatted = formatted.replace(DIGIT_MASK_CHAR, char);
}
return {
input: chars.substr(0, length) || null,
formatted: formatted !== this.mask ? formatted : null
};
}
pasteMask(event) {
event.preventDefault();
const text = event.clipboardData.getData('text');
const data = this.masking(text);
this.form.setValue(data);
}
keydownMask(event) {
const value = this.inputControl.value || '';
let data;
if (DIGIT_KEYS.includes(event.key)) {
data = this.masking(value + event.key);
}
else if (event.key === Key.backspace) {
data = this.masking(value.substr(0, value.length - 1));
}
else if (event.key === Key.tab
|| event.key === Key.arrowLeft
|| event.key === Key.arrowRight
|| (event.ctrlKey || event.metaKey) && event.key === Key.v) {
return;
}
event.preventDefault();
if (data !== undefined) {
this.form.setValue(data);
}
}
keydown(event) {
if (this.type === InputType.number) {
if (this.inputControl.value && this.inputControl.value.length === 1 && event.key === Key.backspace) {
this.inputControl.setValue(null);
}
}
if (event.key === Key.enter) {
event.preventDefault();
}
}
keyup() {
let value = this.inputControl.value;
if (this.type === InputType.text && !!this.transform && !!value) {
switch (this.transform) {
case TextTransform.capitalize:
value = value.charAt(0).toUpperCase() + value.slice(1);
break;
case TextTransform.lowercase:
value = value.toLowerCase();
break;
case TextTransform.uppercase:
value = value.toUpperCase();
break;
}
this.inputControl.setValue(value);
}
}
writeValue(value) {
this.form.patchValue(!!this.mask ? this.masking(value) : { input: value }, { emitEvent: false });
}
setDisabledState(disabled) {
this.disabled = disabled;
}
setNumber(step) {
if (this.inputControl.value === '' || this.inputControl.value === null) {
this.inputControl.setValue(DEFAULT_NUMBER);
}
else {
let number = +this.inputControl.value + step;
number = this.max !== undefined && this.max !== null ? Math.min(number, this.max) : number;
number = this.min !== undefined && this.min !== null ? Math.max(number, this.min) : number;
this.inputControl.setValue(number);
}
}
clear(event) {
this.inputControl.setValue(null);
this.formattedControl.setValue(this.mask);
event.stopPropagation();
}
focus() {
if (!!this.valueInput) {
this.valueInput.nativeElement.focus();
}
else if (!!this.maskedInput) {
this.maskedInput.nativeElement.focus();
}
}
};
InputComponent.ctorParameters = () => [
{ type: NGXLogger },
{ type: FormBuilder }
];
__decorate([
HostBinding('attr.host'),
__metadata("design:type", Object)
], InputComponent.prototype, "host", void 0);
__decorate([
ViewChild('valueInput', { read: ElementRef, static: false }),
__metadata("design:type", ElementRef)
], InputComponent.prototype, "valueInput", void 0);
__decorate([
ViewChild('maskedInput', { read: ElementRef, static: false }),
__metadata("design:type", ElementRef)
], InputComponent.prototype, "maskedInput", void 0);
__decorate([
HostBinding('attr.data-focused'),
__metadata("design:type", Object)
], InputComponent.prototype, "focused", void 0);
__decorate([
HostBinding('attr.data-disabled'),
__metadata("design:type", Object)
], InputComponent.prototype, "disabled", void 0);
__decorate([
HostBinding('attr.data-scheme'),
__metadata("design:type", String)
], InputComponent.prototype, "_scheme", void 0);
__decorate([
HostBinding('attr.data-size'),
__metadata("design:type", String)
], InputComponent.prototype, "_size", void 0);
__decorate([
HostBinding('attr.data-width'),
__metadata("design:type", String)
], InputComponent.prototype, "_width", void 0);
__decorate([
HostBinding('attr.data-with-icon'),
__metadata("design:type", Object),
__metadata("design:paramtypes", [])
], InputComponent.prototype, "withIcon", null);
__decorate([
PropertyApi({
description: 'Icon for input',
type: 'string',
}),
Input(),
__metadata("design:type", String)
], InputComponent.prototype, "icon", void 0);
__decorate([
PropertyApi({
description: 'Label for input',
type: 'string',
}),
Input(),
__metadata("design:type", String)
], InputComponent.prototype, "label", void 0);
__decorate([
PropertyApi({
description: 'Name for input',
type: 'string'
}),
Input(),
__metadata("design:type", String)
], InputComponent.prototype, "name", void 0);
__decorate([
PropertyApi({
description: 'Text transform for input',
path: 'ui.text.transform',
options: [TextTransform.capitalize, TextTransform.uppercase, TextTransform.lowercase]
}),
Input(),
__metadata("design:type", String)
], InputComponent.prototype, "transform", void 0);
__decorate([
PropertyApi({
description: 'Auto complete for input',
path: 'ui.input.autocomplete',
options: [InputAutocomplete.on, InputAutocomplete.off]
}),
Input(),
__metadata("design:type", String)
], InputComponent.prototype, "autocomplete", void 0);
__decorate([
PropertyApi({
description: 'Input text align',
path: 'ui.text.align',
default: TextAlign.left,
options: [TextAlign.left, TextAlign.right]
}),
HostBinding('attr.data-textAlign'),
Input(),
__metadata("design:type", String)
], InputComponent.prototype, "textAlign", void 0);
__decorate([
PropertyApi({
description: 'Minimum number value that can be entered. For input with typeControl = number',
type: 'number',
}),
Input(),
__metadata("design:type", Number)
], InputComponent.prototype, "min", void 0);
__decorate([
PropertyApi({
description: 'Maximum number value that can be entered. For input with typeControl = number',
type: 'number',
}),
Input(),
__metadata("design:type", Number)
], InputComponent.prototype, "max", void 0);
__decorate([
PropertyApi({
description: 'Step for entered value. For input with typeControl = number',
type: 'number',
}),
Input(),
__metadata("design:type", Object)
], InputComponent.prototype, "step", void 0);
__decorate([
PropertyApi({
description: 'Used to specify that the input field is read-only',
type: 'boolean',
default: 'false'
}),
Input(),
__metadata("design:type", Object)
], InputComponent.prototype, "readonly", void 0);
__decorate([
PropertyApi({
description: 'Input scheme',
path: 'ui.input.scheme',
default: InputScheme.normal,
options: [InputScheme.normal, InputScheme.success, InputScheme.failed]
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], InputComponent.prototype, "scheme", null);
__decorate([
PropertyApi({
description: 'Input placeholder',
type: 'string',
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], InputComponent.prototype, "placeholder", null);
__decorate([
PropertyApi({
description: 'Input typeControl',
path: 'ui.input.type',
default: InputType.text,
options: [InputType.text, InputType.number, InputType.password]
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], InputComponent.prototype, "type", null);
__decorate([
PropertyApi({
description: 'Input size',
path: 'ui.size',
default: Size.normal,
options: [Size.small, Size.normal, Size.large]
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], InputComponent.prototype, "size", null);
__decorate([
PropertyApi({
description: 'Input width',
path: 'ui.width',
default: Width.default,
options: [Width.default, Width.fluid]
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], InputComponent.prototype, "width", null);
__decorate([
PropertyApi({
description: 'Input state',
path: 'ui.state',
options: [State.loading, State.warning, State.checked]
}),
HostBinding('attr.data-state'),
Input(),
__metadata("design:type", String)
], InputComponent.prototype, "state", void 0);
__decorate([
PropertyApi({
description: 'Max rows for multiline mode',
type: 'number',
default: 5,
}),
Input(),
__metadata("design:type", Object)
], InputComponent.prototype, "rows", void 0);
__decorate([
PropertyApi({
description: 'Mask pattern where _ - is digit',
type: 'string',
default: null
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], InputComponent.prototype, "mask", null);
__decorate([
PropertyApi({
description: 'Button for reset input; Allow multiple lines in input',
path: 'ui.feature',
options: [Feature.allowEmpty, Feature.multiline],
}),
HostBinding('attr.data-features'),
Input(),
__metadata("design:type", Array)
], InputComponent.prototype, "features", void 0);
__decorate([
PropertyApi({
description: 'Click event',
path: 'EventEmitter'
}),
Output(),
__metadata("design:type", Object)
], InputComponent.prototype, "click", void 0);
__decorate([
HostBinding('attr.tabindex'),
__metadata("design:type", Object)
], InputComponent.prototype, "tabindex", void 0);
__decorate([
HostListener('blur'),
__metadata("design:type", Object)
], InputComponent.prototype, "onBlur", void 0);
InputComponent = InputComponent_1 = __decorate([
Component({
selector: 'jnt-input',
template: "<form child-of=\"jnt-input-host\" [formGroup]=\"form\">\n <div child-of=\"jnt-input-host\" data-label *ngIf=\"!!label\">{{label}}</div>\n <jnt-stack child-of=\"jnt-input-host\" data-content [orientation]=\"ui.orientation.horizontal\"\n [gutter]=\"ui.gutter.small\" [align]=\"ui.align.center\">\n <jnt-icon child-of=\"jnt-input-host\" data-label-icon *ngIf=\"!!icon && !label && !(features | includes : ui.feature.multiline)\"\n [icon]=\"icon\">\n </jnt-icon>\n\n <input child-of=\"jnt-input-host\" #maskedInput *ngIf=\"!!mask; else inputTemplate\"\n formControlName=\"formatted\"\n type=\"tel\"\n [name]=\"name\"\n (focusin)=\"focused = true\"\n (focusout)=\"focused = false\"\n [placeholder]=\"mask\"\n [readonly]=\"readonly ? readonly : null\"\n [autocomplete]=\"autocomplete\"\n (paste)=\"pasteMask($event)\"\n (keydown)=\"keydownMask($event)\" />\n\n <ng-template #inputTemplate>\n <textarea child-of=\"jnt-input-host\" *ngIf=\"features | includes: ui.feature.multiline; else singleLineTemplate\"\n formControlName=\"input\"\n [placeholder]=\"placeholder\"\n [attr.rows]=\"rows\"\n (focusin)=\"focused = true\"\n (focusout)=\"focused = false\">\n </textarea>\n <ng-template #singleLineTemplate>\n <input child-of=\"jnt-input-host\" #valueInput\n formControlName=\"input\"\n [name]=\"name\"\n [type]=\"type === ui.input.type.password && view.password.display ? ui.input.type.text : type\"\n [placeholder]=\"placeholder\"\n [readonly]=\"readonly ? readonly : null\"\n [autocomplete]=\"autocomplete\"\n [min]=\"min\"\n [max]=\"max\"\n (focusin)=\"focused = true\"\n (focusout)=\"focused = false\"\n (keydown)=\"keydown($event)\"\n (keyup)=\"keyup()\" />\n </ng-template>\n </ng-template>\n\n <div child-of=\"jnt-input-host\" data-loading *ngIf=\"state === ui.state.loading\">\n <jnt-spinner child-of=\"jnt-input-host\" data-spinner></jnt-spinner>\n </div>\n\n <div child-of=\"jnt-input-host\" data-warning *ngIf=\"state === ui.state.warning\">\n <jnt-icon child-of=\"jnt-input-host\" [icon]=\"ui.icons.warning\"></jnt-icon>\n </div>\n\n <div child-of=\"jnt-input-host\" data-checked *ngIf=\"state === ui.state.checked\">\n <jnt-icon child-of=\"jnt-input-host\" [icon]=\"ui.icons.checked\"></jnt-icon>\n </div>\n\n <button child-of=\"jnt-input-host\" data-view *ngIf=\"type === ui.input.type.password\"\n (click)=\"view.password.display = !view.password.display\" tabindex=\"-1\">\n <jnt-icon child-of=\"jnt-input-host\" [icon]=\"view.password.display ? ui.icons.viewHide : ui.icons.view\"></jnt-icon>\n </button>\n\n <button child-of=\"jnt-input-host\" data-reset *ngIf=\"features | includes: ui.feature.allowEmpty\" tabindex=\"-1\"\n (click)=\"clear($event)\">\n <jnt-icon child-of=\"jnt-input-host\" [icon]=\"ui.icons.closeSmall\"></jnt-icon>\n </button>\n\n <div child-of=\"jnt-input-host\" data-arrows *ngIf=\"type === ui.input.type.number\">\n <button child-of=\"jnt-input-host\" [disabled]=\"inputControl.disabled\" (click)=\"setNumber(step || 1)\" tabindex=\"-1\">\n <jnt-icon child-of=\"jnt-input-host\" [icon]=\"ui.icons.smallUp\"></jnt-icon>\n </button>\n <button child-of=\"jnt-input-host\" [disabled]=\"inputControl.disabled\" (click)=\"setNumber(-step || -1)\" tabindex=\"-1\">\n <jnt-icon child-of=\"jnt-input-host\" [icon]=\"ui.icons.smallDown\"></jnt-icon>\n </button>\n </div>\n </jnt-stack>\n</form>",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputComponent_1),
multi: true
}
]
}),
__metadata("design:paramtypes", [NGXLogger,
FormBuilder])
], InputComponent);
export { InputComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGp1bnRlL3VpLyIsInNvdXJjZXMiOlsibGliL2Zvcm1zL2lucHV0L2lucHV0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDeEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9DLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRXBFLE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FBQztBQUM1QixNQUFNLFVB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LENBQUM7UUFDNUMsSUFBSSxJQUFJLENBQUM7UUFFVCxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2xDLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDeEM7YUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLFNBQVMsRUFBRTtZQUN0QyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDeEQ7YUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLEdBQUc7ZUFDM0IsS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsU0FBUztlQUMzQixLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxVQUFVO2VBQzVCLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFO1lBQzVELE9BQU87U0FDUjtRQUNELEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2QixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7WUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDMUI7SUFDSCxDQUFDO0lBRUQsT0FBTyxDQUFDLEtBQW9CO1FBQzFCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsTUFBTSxFQUFFO1lBQ2xDLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxTQUFTLEVBQUU7Z0JBQ2xHLElB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QUFFOzs2Q0FDdUI7QUFHaEM7SUFEQyxXQUFXLENBQUMsZUFBZSxDQUFDOztnREFDaEI7QUFNUztJQUFyQixZQUFZLENBQUMsTUFBTSxDQUFDOzs4Q0FBaUM7QUE5TzNDLGNBQWM7SUFYMUIsU0FBUyxDQUFDO1FBQ1QsUUFBUSxFQUFFLFdBQVc7UUFDckIsc3hIQUF3QztRQUN4QyxTQUFTLEVBQUU7WUFDVDtnQkFDRSxPQUFPLEVBQUUsaUJBQWlCO2dCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGdCQUFjLENBQUM7Z0JBQzdDLEtBQUssRUFBRSxJQUFJO2FBQ1o7U0FDRjtLQUNGLENBQUM7cUNBaVA0QixTQUFTO1FBQ2IsV0FBVztHQWpQeEIsY0FBYyxDQXVYMUI7U0F2WFksY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBGb3JtQnVpbGRlciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBOR1hMb2dnZXIgfSBmcm9tICduZ3gtbG9nZ2VyJztcbmltcG9ydCB7IGZpbHRlciwgbWFwLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEtleSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMva2V5Ym9hcmQnO1xuaW1wb3J0IHsgUHJvcGVydHlBcGkgfSBmcm9tICcuLi8uLi9jb3JlL2RlY29yYXRvcnMvYXBpJztcbmltcG9ydCB7IEZlYXR1cmUgfSBmcm9tICcuLi8uLi9jb3JlL2VudW1zL2ZlYXR1cmUnO1xuaW1wb3J0IHsgU2l6ZSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvc2l6ZSc7XG5pbXBvcnQgeyBTdGF0ZSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvc3RhdGUnO1xuaW1wb3J0IHsgVGV4dEFsaWduLCBUZXh0VHJhbnNmb3JtIH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy90ZXh0JztcbmltcG9ydCB7IFVJIH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy91aSc7XG5pbXBvcnQgeyBXaWR0aCB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvd2lkdGgnO1xuaW1wb3J0IHsgSW5wdXRBdXRvY29tcGxldGUsIElucHV0U2NoZW1lLCBJbnB1dFR5cGUgfSBmcm9tICcuL2VudW1zJztcblxuY29uc3QgRElHSVRfTUFTS19DSEFSID0gJ18nO1xuY29uc3QgRElHSVRfS0VZUyA9IFsnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOSddO1xuY29uc3QgREVGQVVMVF9OVU1CRVIgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdqbnQtaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogJy4vaW5wdXQuZW5jYXBzdWxhdGVkLmh0bWwnLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IElucHV0Q29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIElucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmhvc3QnKVxuICByZWFkb25seSBob3N0ID0gJ2pudC1pbnB1dC1ob3N0JztcblxuICB1aSA9IFVJO1xuICB2aWV3ID0ge3Bhc3N3b3JkOiB7ZGlzcGxheTogZmFsc2V9fTtcblxuICBwcml2YXRlIF9tYXNrOiBzdHJpbmc7XG4gIHByaXZhdGUgX3R5cGU6IElucHV0VHlwZSA9IElucHV0VHlwZS50ZXh0O1xuICBwcml2YXRlIF9wbGFjZWhvbGRlcjogc3RyaW5nID0gJyc7XG5cbiAgaW5wdXRDb250cm9sID0gdGhpcy5mYi5jb250cm9sKG51bGwpO1xuICBmb3JtYXR0ZWRDb250cm9sID0gdGhpcy5mYi5jb250cm9sKG51bGwpO1xuICBmb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgaW5wdXQ6IHRoaXMuaW5wdXRDb250cm9sLFxuICAgIGZvcm1hdHRlZDogdGhpcy5mb3JtYXR0ZWRDb250cm9sXG4gIH0pO1xuXG4gIEBWaWV3Q2hpbGQoJ3ZhbHVlSW5wdXQnLCB7cmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZX0pXG4gIHZhbHVlSW5wdXQ6IEVsZW1lbnRSZWY7XG5cbiAgQFZpZXdDaGlsZCgnbWFza2VkSW5wdXQnLCB7cmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZX0pXG4gIG1hc2tlZElucHV0OiBFbGVtZW50UmVmO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLWZvY3VzZWQnKVxuICBmb2N1c2VkID0gZmFsc2U7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtZGlzYWJsZWQnKVxuICBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXNjaGVtZScpXG4gIF9zY2hlbWU6IElucHV0U2NoZW1lID0gSW5wdXRTY2hlbWUubm9ybWFsO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXNpemUnKVxuICBfc2l6ZTogU2l6ZSA9IFNpemUubm9ybWFsO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXdpZHRoJylcbiAgX3dpZHRoOiBXaWR0aCA9IFdpZHRoLmRlZmF1bHQ7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtd2l0aC1pY29uJylcbiAgZ2V0IHdpdGhJY29uKCkge1xuICAgIHJldHVybiAhIXRoaXMuaWNvbjtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJY29uIGZvciBpbnB1dCcsXG4gICAgdHlwZTogJ3N0cmluZycsXG4gIH0pXG4gIEBJbnB1dCgpXG4gIGljb246IHN0cmluZztcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnTGFiZWwgZm9yIGlucHV0JyxcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgfSlcbiAgQElucHV0KClcbiAgbGFiZWw6IHN0cmluZztcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBmb3IgaW5wdXQnLFxuICAgIHR5cGU6ICdzdHJpbmcnXG4gIH0pXG4gIEBJbnB1dCgpXG4gIG5hbWU6IHN0cmluZyA9IG51bGw7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1RleHQgdHJhbnNmb3JtIGZvciBpbnB1dCcsXG4gICAgcGF0aDogJ3VpLnRleHQudHJhbnNmb3JtJyxcbiAgICBvcHRpb25zOiBbVGV4dFRyYW5zZm9ybS5jYXBpdGFsaXplLCBUZXh0VHJhbnNmb3JtLnVwcGVyY2FzZSwgVGV4dFRyYW5zZm9ybS5sb3dlcmNhc2VdXG4gIH0pXG4gIEBJbnB1dCgpXG4gIHRyYW5zZm9ybTogVGV4dFRyYW5zZm9ybTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnQXV0byBjb21wbGV0ZSBmb3IgaW5wdXQnLFxuICAgIHBhdGg6ICd1aS5pbnB1dC5hdXRvY29tcGxldGUnLFxuICAgIG9wdGlvbnM6IFtJbnB1dEF1dG9jb21wbGV0ZS5vbiwgSW5wdXRBdXRvY29tcGxldGUub2ZmXVxuICB9KVxuICBASW5wdXQoKVxuICBhdXRvY29tcGxldGU6IElucHV0QXV0b2NvbXBsZXRlID0gSW5wdXRBdXRvY29tcGxldGUub2ZmO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCB0ZXh0IGFsaWduJyxcbiAgICBwYXRoOiAndWkudGV4dC5hbGlnbicsXG4gICAgZGVmYXVsdDogVGV4dEFsaWduLmxlZnQsXG4gICAgb3B0aW9uczogW1RleHRBbGlnbi5sZWZ0LCBUZXh0QWxpZ24ucmlnaHRdXG4gIH0pXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXRleHRBbGlnbicpXG4gIEBJbnB1dCgpXG4gIHRleHRBbGlnbjogVGV4dEFsaWduID0gVGV4dEFsaWduLmxlZnQ7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ01pbmltdW0gbnVtYmVyIHZhbHVlIHRoYXQgY2FuIGJlIGVudGVyZWQuIEZvciBpbnB1dCB3aXRoIHR5cGVDb250cm9sID0gbnVtYmVyJyxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgfSlcbiAgQElucHV0KClcbiAgbWluOiBudW1iZXIgPSBudWxsO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdNYXhpbXVtIG51bWJlciB2YWx1ZSB0aGF0IGNhbiBiZSBlbnRlcmVkLiBGb3IgaW5wdXQgd2l0aCB0eXBlQ29udHJvbCA9IG51bWJlcicsXG4gICAgdHlwZTogJ251bWJlcicsXG4gIH0pXG4gIEBJbnB1dCgpXG4gIG1heDogbnVtYmVyID0gbnVsbDtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnU3RlcCBmb3IgZW50ZXJlZCB2YWx1ZS4gRm9yIGlucHV0IHdpdGggdHlwZUNvbnRyb2wgPSBudW1iZXInLFxuICAgIHR5cGU6ICdudW1iZXInLFxuICB9KVxuICBASW5wdXQoKVxuICBzdGVwID0gMTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnVXNlZCB0byBzcGVjaWZ5IHRoYXQgdGhlIGlucHV0IGZpZWxkIGlzIHJlYWQtb25seScsXG4gICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlZmF1bHQ6ICdmYWxzZSdcbiAgfSlcbiAgQElucHV0KClcbiAgcmVhZG9ubHkgPSBmYWxzZTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnSW5wdXQgc2NoZW1lJyxcbiAgICBwYXRoOiAndWkuaW5wdXQuc2NoZW1lJyxcbiAgICBkZWZhdWx0OiBJbnB1dFNjaGVtZS5ub3JtYWwsXG4gICAgb3B0aW9uczogW0lucHV0U2NoZW1lLm5vcm1hbCwgSW5wdXRTY2hlbWUuc3VjY2VzcywgSW5wdXRTY2hlbWUuZmFpbGVkXVxuICB9KVxuICBASW5wdXQoKVxuICBzZXQgc2NoZW1lKHNjaGVtZTogSW5wdXRTY2hlbWUpIHtcbiAgICB0aGlzLl9zY2hlbWUgPSBzY2hlbWUgfHwgSW5wdXRTY2hlbWUubm9ybWFsO1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ0lucHV0IHBsYWNlaG9sZGVyJyxcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgfSlcbiAgQElucHV0KClcbiAgc2V0IHBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9wbGFjZWhvbGRlciA9IHBsYWNlaG9sZGVyIHx8ICcnO1xuICB9XG5cbiAgZ2V0IHBsYWNlaG9sZGVyKCkge1xuICAgIHJldHVybiB0aGlzLl9wbGFjZWhvbGRlcjtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCB0eXBlQ29udHJvbCcsXG4gICAgcGF0aDogJ3VpLmlucHV0LnR5cGUnLFxuICAgIGRlZmF1bHQ6IElucHV0VHlwZS50ZXh0LFxuICAgIG9wdGlvbnM6IFtJbnB1dFR5cGUudGV4dCwgSW5wdXRUeXBlLm51bWJlciwgSW5wdXRUeXBlLnBhc3N3b3JkXVxuICB9KVxuICBASW5wdXQoKVxuICBzZXQgdHlwZSh0eXBlOiBJbnB1dFR5cGUpIHtcbiAgICB0aGlzLl90eXBlID0gdHlwZSB8fCBJbnB1dFR5cGUudGV4dDtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiB0aGlzLl90eXBlO1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ0lucHV0IHNpemUnLFxuICAgIHBhdGg6ICd1aS5zaXplJyxcbiAgICBkZWZhdWx0OiBTaXplLm5vcm1hbCxcbiAgICBvcHRpb25zOiBbU2l6ZS5zbWFsbCwgU2l6ZS5ub3JtYWwsIFNpemUubGFyZ2VdXG4gIH0pXG4gIEBJbnB1dCgpXG4gIHNldCBzaXplKHNpemU6IFNpemUpIHtcbiAgICB0aGlzLl9zaXplID0gc2l6ZSB8fCBTaXplLm5vcm1hbDtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCB3aWR0aCcsXG4gICAgcGF0aDogJ3VpLndpZHRoJyxcbiAgICBkZWZhdWx0OiBXaWR0aC5kZWZhdWx0LFxuICAgIG9wdGlvbnM6IFtXaWR0aC5kZWZhdWx0LCBXaWR0aC5mbHVpZF1cbiAgfSlcbiAgQElucHV0KCkgc2V0IHdpZHRoKHdpZHRoOiBXaWR0aCkge1xuICAgIHRoaXMuX3dpZHRoID0gd2lkdGggfHwgV2lkdGguZGVmYXVsdDtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCBzdGF0ZScsXG4gICAgcGF0aDogJ3VpLnN0YXRlJyxcbiAgICBvcHRpb25zOiBbU3RhdGUubG9hZGluZywgU3RhdGUud2FybmluZywgU3RhdGUuY2hlY2tlZF1cbiAgfSlcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtc3RhdGUnKVxuICBASW5wdXQoKVxuICBzdGF0ZTogU3RhdGU7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ01heCByb3dzIGZvciBtdWx0aWxpbmUgbW9kZScsXG4gICAgdHlwZTogJ251bWJlcicsXG4gICAgZGVmYXVsdDogNSxcbiAgfSlcbiAgQElucHV0KClcbiAgcm93cyA9IDU7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ01hc2sgcGF0dGVybiB3aGVyZSBfIC0gaXMgZGlnaXQnLFxuICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIGRlZmF1bHQ6IG51bGxcbiAgfSlcbiAgQElucHV0KClcbiAgc2V0IG1hc2sobWFzazogc3RyaW5nKSB7XG4gICAgdGhpcy5fbWFzayA9IG1hc2s7XG4gICAgaWYgKCEhbWFzaykge1xuICAgICAgdGhpcy5mb3JtLnNldFZhbHVlKHRoaXMubWFza2luZyh0aGlzLmlucHV0Q29udHJvbC52YWx1ZSB8fCAnJykpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBtYXNrKCkge1xuICAgIHJldHVybiB0aGlzLl9tYXNrO1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ0J1dHRvbiBmb3IgcmVzZXQgaW5wdXQ7IEFsbG93IG11bHRpcGxlIGxpbmVzIGluIGlucHV0JyxcbiAgICBwYXRoOiAndWkuZmVhdHVyZScsXG4gICAgb3B0aW9uczogW0ZlYXR1cmUuYWxsb3dFbXB0eSwgRmVhdHVyZS5tdWx0aWxpbmVdLFxuICB9KVxuICBASG9zdEJpbmRpbmcoJ2F0dHIuZGF0YS1mZWF0dXJlcycpXG4gIEBJbnB1dCgpXG4gIGZlYXR1cmVzOiBGZWF0dXJlW10gPSBbXTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnQ2xpY2sgZXZlbnQnLFxuICAgIHBhdGg6ICdFdmVudEVtaXR0ZXInXG4gIH0pXG4gIEBPdXRwdXQoKVxuICBjbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci50YWJpbmRleCcpXG4gIHRhYmluZGV4ID0gMTtcblxuICBvbkNoYW5nZTogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB0aGlzLmxvZ2dlci5lcnJvcigndmFsdWUgYWNjZXNzb3IgaXMgbm90IHJlZ2lzdGVyZWQnKTtcbiAgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4gdGhpcy5sb2dnZXIuZXJyb3IoJ3ZhbHVlIGFjY2Vzc29yIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIHJlZ2lzdGVyT25DaGFuZ2UgPSBmbiA9PiB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIHJlZ2lzdGVyT25Ub3VjaGVkID0gZm4gPT4gdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpIG9uQmx1ciA9ICgpID0+IHRoaXMub25Ub3VjaGVkKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBsb2dnZXI6IE5HWExvZ2dlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaW5wdXRDb250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUodmFsdWUgPT5cbiAgICAgIHRoaXMub25DaGFuZ2UoISF2YWx1ZSA/ICh0aGlzLnR5cGUgPT09IElucHV0VHlwZS5udW1iZXIgPyArdmFsdWUgOiB2YWx1ZSkgOiBudWxsKSk7XG5cbiAgICB0aGlzLmZvcm1hdHRlZENvbnRyb2wudmFsdWVDaGFuZ2VzLnBpcGUoXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgZmlsdGVyKCgpID0+ICEhdGhpcy5tYXNrZWRJbnB1dCksXG4gICAgICBtYXAoZm9ybWF0dGVkID0+ICEhZm9ybWF0dGVkID8gZm9ybWF0dGVkIDogdGhpcy5tYXNrKVxuICAgICkuc3Vic2NyaWJlKGZvcm1hdHRlZCA9PiB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGZvcm1hdHRlZC5pbmRleE9mKERJR0lUX01BU0tfQ0hBUik7XG4gICAgICB0aGlzLm1hc2tlZElucHV0Lm5hdGl2ZUVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UocG9zaXRpb24sIHBvc2l0aW9uKTtcblxuICAgICAgbGV0IGNsZWFyZWQgPSB7aW5wdXQ6IG51bGwsIGZvcm1hdHRlZDogbnVsbH07XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWFzay5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5tYXNrLmNoYXJBdChpKSAhPT0gZm9ybWF0dGVkLmNoYXJBdChpKSkge1xuICAgICAgICAgIGNsZWFyZWQgPSB0aGlzLm1hc2tpbmcoZm9ybWF0dGVkLnN1YnN0cihpKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjbGVhcmVkLmlucHV0ICE9PSB0aGlzLmlucHV0Q29udHJvbC52YWx1ZSB8fCBjbGVhcmVkLmZvcm1hdHRlZCAhPT0gdGhpcy5mb3JtYXR0ZWRDb250cm9sLnZhbHVlKSB7XG4gICAgICAgIHRoaXMuZm9ybS5zZXRWYWx1ZShjbGVhcmVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbWFza2luZyh2YWx1ZTogc3RyaW5nID0gbnVsbCk6IHtcbiAgICBpbnB1dDogc3RyaW5nLFxuICAgIGZvcm1hdHRlZDogc3RyaW5nXG4gIH0ge1xuICAgIGNvbnN0IGNoYXJzID0gISF2YWx1ZSA/IHZhbHVlLnJlcGxhY2UoL1xcRC9naSwgJycpIDogJyc7XG4gICAgbGV0IGZvcm1hdHRlZCA9IHRoaXMubWFzaztcbiAgICBjb25zdCBsZW5ndGggPSB0aGlzLm1hc2suc3BsaXQoRElHSVRfTUFTS19DSEFSKS5sZW5ndGggLSAxO1xuICAgIGZvciAobGV0IGNoYXIgb2YgY2hhcnMpIHtcbiAgICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5yZXBsYWNlKERJR0lUX01BU0tfQ0hBUiwgY2hhcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0OiBjaGFycy5zdWJzdHIoMCwgbGVuZ3RoKSB8fCBudWxsLFxuICAgICAgZm9ybWF0dGVkOiBmb3JtYXR0ZWQgIT09IHRoaXMubWFzayA/IGZvcm1hdHRlZCA6IG51bGxcbiAgICB9O1xuICB9XG5cbiAgcGFzdGVNYXNrKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgdGV4dCA9IGV2ZW50LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dCcpO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLm1hc2tpbmcodGV4dCk7XG4gICAgdGhpcy5mb3JtLnNldFZhbHVlKGRhdGEpO1xuICB9XG5cbiAga2V5ZG93bk1hc2soZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuaW5wdXRDb250cm9sLnZhbHVlIHx8ICcnO1xuICAgIGxldCBkYXRhO1xuXG4gICAgaWYgKERJR0lUX0tFWVMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAgZGF0YSA9IHRoaXMubWFza2luZyh2YWx1ZSArIGV2ZW50LmtleSk7XG4gICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtleS5iYWNrc3BhY2UpIHtcbiAgICAgIGRhdGEgPSB0aGlzLm1hc2tpbmcodmFsdWUuc3Vic3RyKDAsIHZhbHVlLmxlbmd0aCAtIDEpKTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS2V5LnRhYlxuICAgICAgfHwgZXZlbnQua2V5ID09PSBLZXkuYXJyb3dMZWZ0XG4gICAgICB8fCBldmVudC5rZXkgPT09IEtleS5hcnJvd1JpZ2h0XG4gICAgICB8fCAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSAmJiBldmVudC5rZXkgPT09IEtleS52KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgaWYgKGRhdGEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5mb3JtLnNldFZhbHVlKGRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIGtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICBpZiAodGhpcy50eXBlID09PSBJbnB1dFR5cGUubnVtYmVyKSB7XG4gICAgICBpZiAodGhpcy5pbnB1dENvbnRyb2wudmFsdWUgJiYgdGhpcy5pbnB1dENvbnRyb2wudmFsdWUubGVuZ3RoID09PSAxICYmIGV2ZW50LmtleSA9PT0gS2V5LmJhY2tzcGFjZSkge1xuICAgICAgICB0aGlzLmlucHV0Q29udHJvbC5zZXRWYWx1ZShudWxsKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gS2V5LmVudGVyKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIGtleXVwKCkge1xuICAgIGxldCB2YWx1ZSA9IHRoaXMuaW5wdXRDb250cm9sLnZhbHVlO1xuXG4gICAgaWYgKHRoaXMudHlwZSA9PT0gSW5wdXRUeXBlLnRleHQgJiYgISF0aGlzLnRyYW5zZm9ybSAmJiAhIXZhbHVlKSB7XG4gICAgICBzd2l0Y2ggKHRoaXMudHJhbnNmb3JtKSB7XG4gICAgICAgIGNhc2UgVGV4dFRyYW5zZm9ybS5jYXBpdGFsaXplOlxuICAgICAgICAgIHZhbHVlID0gdmFsdWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB2YWx1ZS5zbGljZSgxKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBUZXh0VHJhbnNmb3JtLmxvd2VyY2FzZTpcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVGV4dFRyYW5zZm9ybS51cHBlcmNhc2U6XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdGhpcy5pbnB1dENvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWUpIHtcbiAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSghIXRoaXMubWFzayA/IHRoaXMubWFza2luZyh2YWx1ZSkgOiB7aW5wdXQ6IHZhbHVlfSwge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoZGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpc2FibGVkID0gZGlzYWJsZWQ7XG4gIH1cblxuICBzZXROdW1iZXIoc3RlcDogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuaW5wdXRDb250cm9sLnZhbHVlID09PSAnJyB8fCB0aGlzLmlucHV0Q29udHJvbC52YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5pbnB1dENvbnRyb2wuc2V0VmFsdWUoREVGQVVMVF9OVU1CRVIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbnVtYmVyID0gK3RoaXMuaW5wdXRDb250cm9sLnZhbHVlICsgc3RlcDtcbiAgICAgIG51bWJlciA9IHRoaXMubWF4ICE9PSB1bmRlZmluZWQgJiYgdGhpcy5tYXggIT09IG51bGwgPyBNYXRoLm1pbihudW1iZXIsIHRoaXMubWF4KSA6IG51bWJlcjtcbiAgICAgIG51bWJlciA9IHRoaXMubWluICE9PSB1bmRlZmluZWQgJiYgdGhpcy5taW4gIT09IG51bGwgPyBNYXRoLm1heChudW1iZXIsIHRoaXMubWluKSA6IG51bWJlcjtcbiAgICAgIHRoaXMuaW5wdXRDb250cm9sLnNldFZhbHVlKG51bWJlcik7XG4gICAgfVxuICB9XG5cbiAgY2xlYXIoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLmlucHV0Q29udHJvbC5zZXRWYWx1ZShudWxsKTtcbiAgICB0aGlzLmZvcm1hdHRlZENvbnRyb2wuc2V0VmFsdWUodGhpcy5tYXNrKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIGZvY3VzKCkge1xuICAgIGlmICghIXRoaXMudmFsdWVJbnB1dCkge