UNPKG

@junte/ui

Version:

Quality Angular UI components kit

499 lines 53.9 kB
import { __decorate, __metadata, __values } 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'; var DIGIT_MASK_CHAR = '_'; var DIGIT_KEYS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; var DEFAULT_NUMBER = 0; var InputComponent = /** @class */ (function () { function InputComponent(logger, fb) { var _this = this; 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 = function () { return _this.logger.error('value accessor is not registered'); }; this.onTouched = function () { return _this.logger.error('value accessor is not registered'); }; this.registerOnChange = function (fn) { return _this.onChange = fn; }; this.registerOnTouched = function (fn) { return _this.onTouched = fn; }; this.onBlur = function () { return _this.onTouched(); }; } InputComponent_1 = InputComponent; Object.defineProperty(InputComponent.prototype, "withIcon", { get: function () { return !!this.icon; }, enumerable: true, configurable: true }); Object.defineProperty(InputComponent.prototype, "scheme", { set: function (scheme) { this._scheme = scheme || InputScheme.normal; }, enumerable: true, configurable: true }); Object.defineProperty(InputComponent.prototype, "placeholder", { get: function () { return this._placeholder; }, set: function (placeholder) { this._placeholder = placeholder || ''; }, enumerable: true, configurable: true }); Object.defineProperty(InputComponent.prototype, "type", { get: function () { return this._type; }, set: function (type) { this._type = type || InputType.text; }, enumerable: true, configurable: true }); Object.defineProperty(InputComponent.prototype, "size", { set: function (size) { this._size = size || Size.normal; }, enumerable: true, configurable: true }); Object.defineProperty(InputComponent.prototype, "width", { set: function (width) { this._width = width || Width.default; }, enumerable: true, configurable: true }); Object.defineProperty(InputComponent.prototype, "mask", { get: function () { return this._mask; }, set: function (mask) { this._mask = mask; if (!!mask) { this.form.setValue(this.masking(this.inputControl.value || '')); } }, enumerable: true, configurable: true }); InputComponent.prototype.ngOnInit = function () { var _this = this; this.inputControl.valueChanges.subscribe(function (value) { return _this.onChange(!!value ? (_this.type === InputType.number ? +value : value) : null); }); this.formattedControl.valueChanges.pipe(distinctUntilChanged(), filter(function () { return !!_this.maskedInput; }), map(function (formatted) { return !!formatted ? formatted : _this.mask; })).subscribe(function (formatted) { var position = formatted.indexOf(DIGIT_MASK_CHAR); _this.maskedInput.nativeElement.setSelectionRange(position, position); var cleared = { input: null, formatted: null }; for (var 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); } }); }; InputComponent.prototype.masking = function (value) { var e_1, _a; if (value === void 0) { value = null; } var chars = !!value ? value.replace(/\D/gi, '') : ''; var formatted = this.mask; var length = this.mask.split(DIGIT_MASK_CHAR).length - 1; try { for (var chars_1 = __values(chars), chars_1_1 = chars_1.next(); !chars_1_1.done; chars_1_1 = chars_1.next()) { var char = chars_1_1.value; formatted = formatted.replace(DIGIT_MASK_CHAR, char); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (chars_1_1 && !chars_1_1.done && (_a = chars_1.return)) _a.call(chars_1); } finally { if (e_1) throw e_1.error; } } return { input: chars.substr(0, length) || null, formatted: formatted !== this.mask ? formatted : null }; }; InputComponent.prototype.pasteMask = function (event) { event.preventDefault(); var text = event.clipboardData.getData('text'); var data = this.masking(text); this.form.setValue(data); }; InputComponent.prototype.keydownMask = function (event) { var value = this.inputControl.value || ''; var 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); } }; InputComponent.prototype.keydown = function (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(); } }; InputComponent.prototype.keyup = function () { var 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); } }; InputComponent.prototype.writeValue = function (value) { this.form.patchValue(!!this.mask ? this.masking(value) : { input: value }, { emitEvent: false }); }; InputComponent.prototype.setDisabledState = function (disabled) { this.disabled = disabled; }; InputComponent.prototype.setNumber = function (step) { if (this.inputControl.value === '' || this.inputControl.value === null) { this.inputControl.setValue(DEFAULT_NUMBER); } else { var 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); } }; InputComponent.prototype.clear = function (event) { this.inputControl.setValue(null); this.formattedControl.setValue(this.mask); event.stopPropagation(); }; InputComponent.prototype.focus = function () { if (!!this.valueInput) { this.valueInput.nativeElement.focus(); } else if (!!this.maskedInput) { this.maskedInput.nativeElement.focus(); } }; var InputComponent_1; InputComponent.ctorParameters = function () { return [ { 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(function () { return InputComponent_1; }), multi: true } ] }), __metadata("design:paramtypes", [NGXLogger, FormBuilder]) ], InputComponent); return InputComponent; }()); export { InputComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGp1bnRlL3VpLyIsInNvdXJjZXMiOlsibGliL2Zvcm1zL2lucHV0L2lucHV0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFcEUsSUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFDO0FBQzVCLElBQU0sVUFB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OzhDQU1QO0lBYUQ7UUFQQyxXQUFXLENBQUM7WUFDWCxXQUFXLEVBQUUsdURBQXVEO1lBQ3BFLElBQUksRUFBRSxZQUFZO1lBQ2xCLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQztTQUNqRCxDQUFDO1FBQ0QsV0FBVyxDQUFDLG9CQUFvQixDQUFDO1FBQ2pDLEtBQUssRUFBRTs7b0RBQ2lCO0lBT3pCO1FBTEMsV0FBVyxDQUFDO1lBQ1gsV0FBVyxFQUFFLGFBQWE7WUFDMUIsSUFBSSxFQUFFLGNBQWM7U0FDckIsQ0FBQztRQUNELE1BQU0sRUFBRTs7aURBQ3VCO0lBR2hDO1FBREMsV0FBVyxDQUFDLGVBQWUsQ0FBQzs7b0RBQ2hCO0lBTVM7UUFBckIsWUFBWSxDQUFDLE1BQU0sQ0FBQzs7a0RBQWlDO0lBOU8zQyxjQUFjO1FBWDFCLFNBQVMsQ0FBQztZQUNULFFBQVEsRUFBRSxXQUFXO1lBQ3JCLHN4SEFBd0M7WUFDeEMsU0FBUyxFQUFFO2dCQUNUO29CQUNFLE9BQU8sRUFBRSxpQkFBaUI7b0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsY0FBTSxPQUFBLGdCQUFjLEVBQWQsQ0FBYyxDQUFDO29CQUM3QyxLQUFLLEVBQUUsSUFBSTtpQkFDWjthQUNGO1NBQ0YsQ0FBQzt5Q0FpUDRCLFNBQVM7WUFDYixXQUFXO09BalB4QixjQUFjLENBdVgxQjtJQUFELHFCQUFDO0NBQUEsQUF2WEQsSUF1WEM7U0F2WFksY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBGb3JtQnVpbGRlciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBOR1hMb2dnZXIgfSBmcm9tICduZ3gtbG9nZ2VyJztcbmltcG9ydCB7IGZpbHRlciwgbWFwLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEtleSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMva2V5Ym9hcmQnO1xuaW1wb3J0IHsgUHJvcGVydHlBcGkgfSBmcm9tICcuLi8uLi9jb3JlL2RlY29yYXRvcnMvYXBpJztcbmltcG9ydCB7IEZlYXR1cmUgfSBmcm9tICcuLi8uLi9jb3JlL2VudW1zL2ZlYXR1cmUnO1xuaW1wb3J0IHsgU2l6ZSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvc2l6ZSc7XG5pbXBvcnQgeyBTdGF0ZSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvc3RhdGUnO1xuaW1wb3J0IHsgVGV4dEFsaWduLCBUZXh0VHJhbnNmb3JtIH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy90ZXh0JztcbmltcG9ydCB7IFVJIH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy91aSc7XG5pbXBvcnQgeyBXaWR0aCB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvd2lkdGgnO1xuaW1wb3J0IHsgSW5wdXRBdXRvY29tcGxldGUsIElucHV0U2NoZW1lLCBJbnB1dFR5cGUgfSBmcm9tICcuL2VudW1zJztcblxuY29uc3QgRElHSVRfTUFTS19DSEFSID0gJ18nO1xuY29uc3QgRElHSVRfS0VZUyA9IFsnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOSddO1xuY29uc3QgREVGQVVMVF9OVU1CRVIgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdqbnQtaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogJy4vaW5wdXQuZW5jYXBzdWxhdGVkLmh0bWwnLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IElucHV0Q29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIElucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmhvc3QnKVxuICByZWFkb25seSBob3N0ID0gJ2pudC1pbnB1dC1ob3N0JztcblxuICB1aSA9IFVJO1xuICB2aWV3ID0ge3Bhc3N3b3JkOiB7ZGlzcGxheTogZmFsc2V9fTtcblxuICBwcml2YXRlIF9tYXNrOiBzdHJpbmc7XG4gIHByaXZhdGUgX3R5cGU6IElucHV0VHlwZSA9IElucHV0VHlwZS50ZXh0O1xuICBwcml2YXRlIF9wbGFjZWhvbGRlcjogc3RyaW5nID0gJyc7XG5cbiAgaW5wdXRDb250cm9sID0gdGhpcy5mYi5jb250cm9sKG51bGwpO1xuICBmb3JtYXR0ZWRDb250cm9sID0gdGhpcy5mYi5jb250cm9sKG51bGwpO1xuICBmb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgaW5wdXQ6IHRoaXMuaW5wdXRDb250cm9sLFxuICAgIGZvcm1hdHRlZDogdGhpcy5mb3JtYXR0ZWRDb250cm9sXG4gIH0pO1xuXG4gIEBWaWV3Q2hpbGQoJ3ZhbHVlSW5wdXQnLCB7cmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZX0pXG4gIHZhbHVlSW5wdXQ6IEVsZW1lbnRSZWY7XG5cbiAgQFZpZXdDaGlsZCgnbWFza2VkSW5wdXQnLCB7cmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZX0pXG4gIG1hc2tlZElucHV0OiBFbGVtZW50UmVmO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLWZvY3VzZWQnKVxuICBmb2N1c2VkID0gZmFsc2U7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtZGlzYWJsZWQnKVxuICBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXNjaGVtZScpXG4gIF9zY2hlbWU6IElucHV0U2NoZW1lID0gSW5wdXRTY2hlbWUubm9ybWFsO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXNpemUnKVxuICBfc2l6ZTogU2l6ZSA9IFNpemUubm9ybWFsO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXdpZHRoJylcbiAgX3dpZHRoOiBXaWR0aCA9IFdpZHRoLmRlZmF1bHQ7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtd2l0aC1pY29uJylcbiAgZ2V0IHdpdGhJY29uKCkge1xuICAgIHJldHVybiAhIXRoaXMuaWNvbjtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJY29uIGZvciBpbnB1dCcsXG4gICAgdHlwZTogJ3N0cmluZycsXG4gIH0pXG4gIEBJbnB1dCgpXG4gIGljb246IHN0cmluZztcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnTGFiZWwgZm9yIGlucHV0JyxcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgfSlcbiAgQElucHV0KClcbiAgbGFiZWw6IHN0cmluZztcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBmb3IgaW5wdXQnLFxuICAgIHR5cGU6ICdzdHJpbmcnXG4gIH0pXG4gIEBJbnB1dCgpXG4gIG5hbWU6IHN0cmluZyA9IG51bGw7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1RleHQgdHJhbnNmb3JtIGZvciBpbnB1dCcsXG4gICAgcGF0aDogJ3VpLnRleHQudHJhbnNmb3JtJyxcbiAgICBvcHRpb25zOiBbVGV4dFRyYW5zZm9ybS5jYXBpdGFsaXplLCBUZXh0VHJhbnNmb3JtLnVwcGVyY2FzZSwgVGV4dFRyYW5zZm9ybS5sb3dlcmNhc2VdXG4gIH0pXG4gIEBJbnB1dCgpXG4gIHRyYW5zZm9ybTogVGV4dFRyYW5zZm9ybTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnQXV0byBjb21wbGV0ZSBmb3IgaW5wdXQnLFxuICAgIHBhdGg6ICd1aS5pbnB1dC5hdXRvY29tcGxldGUnLFxuICAgIG9wdGlvbnM6IFtJbnB1dEF1dG9jb21wbGV0ZS5vbiwgSW5wdXRBdXRvY29tcGxldGUub2ZmXVxuICB9KVxuICBASW5wdXQoKVxuICBhdXRvY29tcGxldGU6IElucHV0QXV0b2NvbXBsZXRlID0gSW5wdXRBdXRvY29tcGxldGUub2ZmO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCB0ZXh0IGFsaWduJyxcbiAgICBwYXRoOiAndWkudGV4dC5hbGlnbicsXG4gICAgZGVmYXVsdDogVGV4dEFsaWduLmxlZnQsXG4gICAgb3B0aW9uczogW1RleHRBbGlnbi5sZWZ0LCBUZXh0QWxpZ24ucmlnaHRdXG4gIH0pXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXRleHRBbGlnbicpXG4gIEBJbnB1dCgpXG4gIHRleHRBbGlnbjogVGV4dEFsaWduID0gVGV4dEFsaWduLmxlZnQ7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ01pbmltdW0gbnVtYmVyIHZhbHVlIHRoYXQgY2FuIGJlIGVudGVyZWQuIEZvciBpbnB1dCB3aXRoIHR5cGVDb250cm9sID0gbnVtYmVyJyxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgfSlcbiAgQElucHV0KClcbiAgbWluOiBudW1iZXIgPSBudWxsO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdNYXhpbXVtIG51bWJlciB2YWx1ZSB0aGF0IGNhbiBiZSBlbnRlcmVkLiBGb3IgaW5wdXQgd2l0aCB0eXBlQ29udHJvbCA9IG51bWJlcicsXG4gICAgdHlwZTogJ251bWJlcicsXG4gIH0pXG4gIEBJbnB1dCgpXG4gIG1heDogbnVtYmVyID0gbnVsbDtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnU3RlcCBmb3IgZW50ZXJlZCB2YWx1ZS4gRm9yIGlucHV0IHdpdGggdHlwZUNvbnRyb2wgPSBudW1iZXInLFxuICAgIHR5cGU6ICdudW1iZXInLFxuICB9KVxuICBASW5wdXQoKVxuICBzdGVwID0gMTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnVXNlZCB0byBzcGVjaWZ5IHRoYXQgdGhlIGlucHV0IGZpZWxkIGlzIHJlYWQtb25seScsXG4gICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlZmF1bHQ6ICdmYWxzZSdcbiAgfSlcbiAgQElucHV0KClcbiAgcmVhZG9ubHkgPSBmYWxzZTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnSW5wdXQgc2NoZW1lJyxcbiAgICBwYXRoOiAndWkuaW5wdXQuc2NoZW1lJyxcbiAgICBkZWZhdWx0OiBJbnB1dFNjaGVtZS5ub3JtYWwsXG4gICAgb3B0aW9uczogW0lucHV0U2NoZW1lLm5vcm1hbCwgSW5wdXRTY2hlbWUuc3VjY2VzcywgSW5wdXRTY2hlbWUuZmFpbGVkXVxuICB9KVxuICBASW5wdXQoKVxuICBzZXQgc2NoZW1lKHNjaGVtZTogSW5wdXRTY2hlbWUpIHtcbiAgICB0aGlzLl9zY2hlbWUgPSBzY2hlbWUgfHwgSW5wdXRTY2hlbWUubm9ybWFsO1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ0lucHV0IHBsYWNlaG9sZGVyJyxcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgfSlcbiAgQElucHV0KClcbiAgc2V0IHBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9wbGFjZWhvbGRlciA9IHBsYWNlaG9sZGVyIHx8ICcnO1xuICB9XG5cbiAgZ2V0IHBsYWNlaG9sZGVyKCkge1xuICAgIHJldHVybiB0aGlzLl9wbGFjZWhvbGRlcjtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCB0eXBlQ29udHJvbCcsXG4gICAgcGF0aDogJ3VpLmlucHV0LnR5cGUnLFxuICAgIGRlZmF1bHQ6IElucHV0VHlwZS50ZXh0LFxuICAgIG9wdGlvbnM6IFtJbnB1dFR5cGUudGV4dCwgSW5wdXRUeXBlLm51bWJlciwgSW5wdXRUeXBlLnBhc3N3b3JkXVxuICB9KVxuICBASW5wdXQoKVxuICBzZXQgdHlwZSh0eXBlOiBJbnB1dFR5cGUpIHtcbiAgICB0aGlzLl90eXBlID0gdHlwZSB8fCBJbnB1dFR5cGUudGV4dDtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiB0aGlzLl90eXBlO1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ0lucHV0IHNpemUnLFxuICAgIHBhdGg6ICd1aS5zaXplJyxcbiAgICBkZWZhdWx0OiBTaXplLm5vcm1hbCxcbiAgICBvcHRpb25zOiBbU2l6ZS5zbWFsbCwgU2l6ZS5ub3JtYWwsIFNpemUubGFyZ2VdXG4gIH0pXG4gIEBJbnB1dCgpXG4gIHNldCBzaXplKHNpemU6IFNpemUpIHtcbiAgICB0aGlzLl9zaXplID0gc2l6ZSB8fCBTaXplLm5vcm1hbDtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCB3aWR0aCcsXG4gICAgcGF0aDogJ3VpLndpZHRoJyxcbiAgICBkZWZhdWx0OiBXaWR0aC5kZWZhdWx0LFxuICAgIG9wdGlvbnM6IFtXaWR0aC5kZWZhdWx0LCBXaWR0aC5mbHVpZF1cbiAgfSlcbiAgQElucHV0KCkgc2V0IHdpZHRoKHdpZHRoOiBXaWR0aCkge1xuICAgIHRoaXMuX3dpZHRoID0gd2lkdGggfHwgV2lkdGguZGVmYXVsdDtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdJbnB1dCBzdGF0ZScsXG4gICAgcGF0aDogJ3VpLnN0YXRlJyxcbiAgICBvcHRpb25zOiBbU3RhdGUubG9hZGluZywgU3RhdGUud2FybmluZywgU3RhdGUuY2hlY2tlZF1cbiAgfSlcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtc3RhdGUnKVxuICBASW5wdXQoKVxuICBzdGF0ZTogU3RhdGU7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ01heCByb3dzIGZvciBtdWx0aWxpbmUgbW9kZScsXG4gICAgdHlwZTogJ251bWJlcicsXG4gICAgZGVmYXVsdDogNSxcbiAgfSlcbiAgQElucHV0KClcbiAgcm93cyA9IDU7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ01hc2sgcGF0dGVybiB3aGVyZSBfIC0gaXMgZGlnaXQnLFxuICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIGRlZmF1bHQ6IG51bGxcbiAgfSlcbiAgQElucHV0KClcbiAgc2V0IG1hc2sobWFzazogc3RyaW5nKSB7XG4gICAgdGhpcy5fbWFzayA9IG1hc2s7XG4gICAgaWYgKCEhbWFzaykge1xuICAgICAgdGhpcy5mb3JtLnNldFZhbHVlKHRoaXMubWFza2luZyh0aGlzLmlucHV0Q29udHJvbC52YWx1ZSB8fCAnJykpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBtYXNrKCkge1xuICAgIHJldHVybiB0aGlzLl9tYXNrO1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ0J1dHRvbiBmb3IgcmVzZXQgaW5wdXQ7IEFsbG93IG11bHRpcGxlIGxpbmVzIGluIGlucHV0JyxcbiAgICBwYXRoOiAndWkuZmVhdHVyZScsXG4gICAgb3B0aW9uczogW0ZlYXR1cmUuYWxsb3dFbXB0eSwgRmVhdHVyZS5tdWx0aWxpbmVdLFxuICB9KVxuICBASG9zdEJpbmRpbmcoJ2F0dHIuZGF0YS1mZWF0dXJlcycpXG4gIEBJbnB1dCgpXG4gIGZlYXR1cmVzOiBGZWF0dXJlW10gPSBbXTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnQ2xpY2sgZXZlbnQnLFxuICAgIHBhdGg6ICdFdmVudEVtaXR0ZXInXG4gIH0pXG4gIEBPdXRwdXQoKVxuICBjbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci50YWJpbmRleCcpXG4gIHRhYmluZGV4ID0gMTtcblxuICBvbkNoYW5nZTogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB0aGlzLmxvZ2dlci5lcnJvcigndmFsdWUgYWNjZXNzb3IgaXMgbm90IHJlZ2lzdGVyZWQnKTtcbiAgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4gdGhpcy5sb2dnZXIuZXJyb3IoJ3ZhbHVlIGFjY2Vzc29yIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIHJlZ2lzdGVyT25DaGFuZ2UgPSBmbiA9PiB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIHJlZ2lzdGVyT25Ub3VjaGVkID0gZm4gPT4gdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpIG9uQmx1ciA9ICgpID0+IHRoaXMub25Ub3VjaGVkKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBsb2dnZXI6IE5HWExvZ2dlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaW5wdXRDb250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUodmFsdWUgPT5cbiAgICAgIHRoaXMub25DaGFuZ2UoISF2YWx1ZSA/ICh0aGlzLnR5cGUgPT09IElucHV0VHlwZS5udW1iZXIgPyArdmFsdWUgOiB2YWx1ZSkgOiBudWxsKSk7XG5cbiAgICB0aGlzLmZvcm1hdHRlZENvbnRyb2wudmFsdWVDaGFuZ2VzLnBpcGUoXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgZmlsdGVyKCgpID0+ICEhdGhpcy5tYXNrZWRJbnB1dCksXG4gICAgICBtYXAoZm9ybWF0dGVkID0+ICEhZm9ybWF0dGVkID8gZm9ybWF0dGVkIDogdGhpcy5tYXNrKVxuICAgICkuc3Vic2NyaWJlKGZvcm1hdHRlZCA9PiB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGZvcm1hdHRlZC5pbmRleE9mKERJR0lUX01BU0tfQ0hBUik7XG4gICAgICB0aGlzLm1hc2tlZElucHV0Lm5hdGl2ZUVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UocG9zaXRpb24sIHBvc2l0aW9uKTtcblxuICAgICAgbGV0IGNsZWFyZWQgPSB7aW5wdXQ6IG51bGwsIGZvcm1hdHRlZDogbnVsbH07XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWFzay5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5tYXNrLmNoYXJBdChpKSAhPT0gZm9ybWF0dGVkLmNoYXJBdChpKSkge1xuICAgICAgICAgIGNsZWFyZWQgPSB0aGlzLm1hc2tpbmcoZm9ybWF0dGVkLnN1YnN0cihpKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjbGVhcmVkLmlucHV0ICE9PSB0aGlzLmlucHV0Q29udHJvbC52YWx1ZSB8fCBjbGVhcmVkLmZvcm1hdHRlZCAhPT0gdGhpcy5mb3JtYXR0ZWRDb250cm9sLnZhbHVlKSB7XG4gICAgICAgIHRoaXMuZm9ybS5zZXRWYWx1ZShjbGVhcmVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbWFza2luZyh2YWx1ZTogc3RyaW5nID0gbnVsbCk6IHtcbiAgICBpbnB1dDogc3RyaW5nLFxuICAgIGZvcm1hdHRlZDogc3RyaW5nXG4gIH0ge1xuICAgIGNvbnN0IGNoYXJzID0gISF2YWx1ZSA/IHZhbHVlLnJlcGxhY2UoL1xcRC9naSwgJycpIDogJyc7XG4gICAgbGV0IGZvcm1hdHRlZCA9IHRoaXMubWFzaztcbiAgICBjb25zdCBsZW5ndGggPSB0aGlzLm1hc2suc3BsaXQoRElHSVRfTUFTS19DSEFSKS5sZW5ndGggLSAxO1xuICAgIGZvciAobGV0IGNoYXIgb2YgY2h