ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
181 lines • 28.6 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Component, ElementRef, forwardRef, Inject, Injector, Optional, ViewEncapsulation } from '@angular/core';
import { Validators } from '@angular/forms';
import { BooleanInputConverter, NumberInputConverter } from '../../../decorators/input-converter';
import { OIntegerPipe } from '../../../pipes/o-integer.pipe';
import { Util } from '../../../util/util';
import { OFormValue } from '../../form/o-form-value';
import { OFormComponent } from '../../form/o-form.component';
import { OFormDataComponent } from '../../o-form-data-component.class';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/flex";
import * as i3 from "@angular/forms";
import * as i4 from "../../../directives/o-mat-error.directive";
import * as i5 from "@angular/material/button";
import * as i6 from "@angular/material/icon";
import * as i7 from "@angular/material/input";
import * as i8 from "@angular/material/form-field";
import * as i9 from "@angular/material/tooltip";
import * as i10 from "../../../pipes/o-translate.pipe";
import * as i11 from "../../form/o-form.component";
const INPUT_TYPE_TEXT = 'text';
const INPUT_TYPE_NUMBER = 'number';
export const DEFAULT_INPUTS_O_INTEGER_INPUT = [
'min',
'max',
'step',
'grouping',
'thousandSeparator : thousand-separator',
'olocale : locale'
];
export class OIntegerInputComponent extends OFormDataComponent {
constructor(form, elRef, injector) {
super(form, elRef, injector);
this.inputType = INPUT_TYPE_NUMBER;
this.step = 1;
this.grouping = false;
this._defaultSQLTypeKey = 'INTEGER';
this.inputType = INPUT_TYPE_TEXT;
this.setComponentPipe();
}
initialize() {
super.initialize();
this.initializeStep();
}
setComponentPipe() {
this.componentPipe = new OIntegerPipe(this.injector);
}
ngOnInit() {
super.ngOnInit();
this.pipeArguments = {
grouping: this.grouping,
thousandSeparator: this.thousandSeparator,
locale: this.olocale
};
if (this.step === undefined) {
this.step = 1;
}
}
ngAfterViewInit() {
super.ngAfterViewInit();
}
setData(value) {
super.setData(value);
setTimeout(() => {
this.setPipeValue();
}, 0);
}
setValue(val, options) {
super.setValue(val, options);
this.setPipeValue();
}
innerOnFocus(event) {
event.preventDefault();
event.stopPropagation();
if (this.isReadOnly) {
return;
}
super.innerOnFocus(event);
this.setNumberDOMValue(this.getValue());
if (this.selectAllOnClick) {
this.selectValue();
}
}
innerOnBlur(event) {
if (event) {
event.stopPropagation();
event.preventDefault();
}
if (this.isReadOnly) {
return;
}
this.setPipeValue();
const formControl = this.getControl();
if (formControl) {
formControl.updateValueAndValidity({ emitEvent: false });
}
super.innerOnBlur(event);
}
setPipeValue() {
if (typeof this.pipeArguments !== 'undefined' && !this.isEmpty()) {
const parsedValue = this.componentPipe.transform(this.getValue(), this.pipeArguments);
this.setTextDOMValue(parsedValue);
}
}
isEmpty() {
if (this.value instanceof OFormValue) {
if (this.value.value !== undefined) {
return false;
}
}
return true;
}
getInputEl() {
let inputElement;
if (this.elRef.nativeElement.tagName === 'INPUT') {
inputElement = this.elRef.nativeElement;
}
else {
inputElement = this.elRef.nativeElement.getElementsByTagName('INPUT')[0];
}
return inputElement;
}
setNumberDOMValue(val) {
this.setInputTypeAndValue(INPUT_TYPE_NUMBER, val);
}
setTextDOMValue(val) {
this.setInputTypeAndValue(INPUT_TYPE_TEXT, val);
}
resolveValidators() {
const validators = super.resolveValidators();
if (Util.isDefined(this.min)) {
validators.push(Validators.min(this.min));
}
if (Util.isDefined(this.max)) {
validators.push(Validators.max(this.max));
}
return validators;
}
initializeStep() {
if (this.step <= 0) {
this.step = 1;
console.warn('`step` attribute must be greater than zero');
}
}
setInputTypeAndValue(inputType, value) {
const inputElement = this.getInputEl();
if (Util.isDefined(inputElement)) {
inputElement.type = inputType;
inputElement.value = (value !== undefined) ? value : '';
}
}
}
OIntegerInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OIntegerInputComponent, deps: [{ token: forwardRef(() => OFormComponent), optional: true }, { token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
OIntegerInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OIntegerInputComponent, selector: "o-integer-input", inputs: { min: "min", max: "max", step: "step", grouping: "grouping", thousandSeparator: ["thousand-separator", "thousandSeparator"], olocale: ["locale", "olocale"] }, usesInheritance: true, ngImport: i0, template: "<div [formGroup]=\"getFormGroup()\" [matTooltip]=\"tooltip\" [matTooltipClass]=\"tooltipClass\" [matTooltipPosition]=\"tooltipPosition\"\n [matTooltipShowDelay]=\"tooltipShowDelay\" [matTooltipHideDelay]=\"tooltipHideDelay\">\n <mat-form-field [appearance]=\"appearance\" [floatLabel]=\"floatLabel\" [hideRequiredMarker]=\"hideRequiredMarker\" [class.custom-width]=\"hasCustomWidth\"\n [class.icon-field]=\"showClearButton\" fxFlexFill [subscriptSizing]=\"subscriptSizing\">\n <mat-label *ngIf=\"labelVisible\">{{ olabel | oTranslate }}</mat-label>\n <input matInput [type]=\"inputType\" [id]=\"getAttribute()\" [formControlName]=\"getAttribute()\" [placeholder]=\"placeHolder\"\n (focus)=\"innerOnFocus($event)\" (blur)=\"innerOnBlur($event)\" (change)=\"onChangeEvent($event)\" [readonly]=\"isReadOnly\" [min]=\"min\" [max]=\"max\"\n [step]=\"step\" [required]=\"isRequired\">\n <button type=\"button\" *ngIf=\"showClearButton\" matSuffix mat-icon-button (click)=\"onClickClearValue($event)\">\n <mat-icon svgIcon=\"ontimize:close\"></mat-icon>\n </button>\n <mat-error *oMatError=\"hasError('required')\">\n {{ 'FORM_VALIDATION.REQUIRED' | oTranslate }}\n </mat-error>\n <mat-error *oMatError=\"hasError('min')\">\n {{ 'FORM_VALIDATION.MIN_VALUE' | oTranslate }}: {{ getErrorValue('min', 'min') }}\n </mat-error>\n <mat-error *oMatError=\"hasError('max')\">\n {{ 'FORM_VALIDATION.MAX_VALUE' | oTranslate }}: {{ getErrorValue('max', 'max') }}\n </mat-error>\n <mat-error *ngFor=\"let oError of getActiveOErrors()\">\n {{ oError.text | oTranslate }}\n </mat-error>\n </mat-form-field>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.FlexFillDirective, selector: "[fxFill], [fxFlexFill]" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.OMatErrorDirective, selector: "[oMatError]", inputs: ["oMatError"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "pipe", type: i10.OTranslatePipe, name: "oTranslate" }], encapsulation: i0.ViewEncapsulation.None });
__decorate([
NumberInputConverter(),
__metadata("design:type", Number)
], OIntegerInputComponent.prototype, "min", void 0);
__decorate([
NumberInputConverter(),
__metadata("design:type", Number)
], OIntegerInputComponent.prototype, "max", void 0);
__decorate([
NumberInputConverter(),
__metadata("design:type", Number)
], OIntegerInputComponent.prototype, "step", void 0);
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OIntegerInputComponent.prototype, "grouping", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OIntegerInputComponent, decorators: [{
type: Component,
args: [{ selector: 'o-integer-input', inputs: DEFAULT_INPUTS_O_INTEGER_INPUT, encapsulation: ViewEncapsulation.None, template: "<div [formGroup]=\"getFormGroup()\" [matTooltip]=\"tooltip\" [matTooltipClass]=\"tooltipClass\" [matTooltipPosition]=\"tooltipPosition\"\n [matTooltipShowDelay]=\"tooltipShowDelay\" [matTooltipHideDelay]=\"tooltipHideDelay\">\n <mat-form-field [appearance]=\"appearance\" [floatLabel]=\"floatLabel\" [hideRequiredMarker]=\"hideRequiredMarker\" [class.custom-width]=\"hasCustomWidth\"\n [class.icon-field]=\"showClearButton\" fxFlexFill [subscriptSizing]=\"subscriptSizing\">\n <mat-label *ngIf=\"labelVisible\">{{ olabel | oTranslate }}</mat-label>\n <input matInput [type]=\"inputType\" [id]=\"getAttribute()\" [formControlName]=\"getAttribute()\" [placeholder]=\"placeHolder\"\n (focus)=\"innerOnFocus($event)\" (blur)=\"innerOnBlur($event)\" (change)=\"onChangeEvent($event)\" [readonly]=\"isReadOnly\" [min]=\"min\" [max]=\"max\"\n [step]=\"step\" [required]=\"isRequired\">\n <button type=\"button\" *ngIf=\"showClearButton\" matSuffix mat-icon-button (click)=\"onClickClearValue($event)\">\n <mat-icon svgIcon=\"ontimize:close\"></mat-icon>\n </button>\n <mat-error *oMatError=\"hasError('required')\">\n {{ 'FORM_VALIDATION.REQUIRED' | oTranslate }}\n </mat-error>\n <mat-error *oMatError=\"hasError('min')\">\n {{ 'FORM_VALIDATION.MIN_VALUE' | oTranslate }}: {{ getErrorValue('min', 'min') }}\n </mat-error>\n <mat-error *oMatError=\"hasError('max')\">\n {{ 'FORM_VALIDATION.MAX_VALUE' | oTranslate }}: {{ getErrorValue('max', 'max') }}\n </mat-error>\n <mat-error *ngFor=\"let oError of getActiveOErrors()\">\n {{ oError.text | oTranslate }}\n </mat-error>\n </mat-form-field>\n</div>\n" }]
}], ctorParameters: function () { return [{ type: i11.OFormComponent, decorators: [{
type: Optional
}, {
type: Inject,
args: [forwardRef(() => OFormComponent)]
}] }, { type: i0.ElementRef }, { type: i0.Injector }]; }, propDecorators: { min: [], max: [], step: [], grouping: [] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1pbnRlZ2VyLWlucHV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2lucHV0L2ludGVnZXItaW5wdXQvby1pbnRlZ2VyLWlucHV0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2lucHV0L2ludGVnZXItaW5wdXQvby1pbnRlZ2VyLWlucHV0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQWlCLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQVUsUUFBUSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hJLE9BQU8sRUFBbUMsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLG9CQUFvQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEcsT0FBTyxFQUF3QixZQUFZLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUVuRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7Ozs7Ozs7Ozs7OztBQUV2RSxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUE7QUFDOUIsTUFBTSxpQkFBaUIsR0FBRyxRQUFRLENBQUE7QUFHbEMsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUc7SUFDNUMsS0FBSztJQUNMLEtBQUs7SUFDTCxNQUFNO0lBQ04s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SUFBQyxvQkFBb0IsRUFBRTs7b0RBQ047QUFFakI7SUFBQyxxQkFBcUIsRUFBRTs7d0RBQ1k7NEZBWnpCLHNCQUFzQjtrQkFQbEMsU0FBUzsrQkFDRSxpQkFBaUIsVUFHbkIsOEJBQThCLGlCQUN2QixpQkFBaUIsQ0FBQyxJQUFJOzswQkFzQmxDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQzs0RkFmdEQsR0FBRyxNQUVILEdBQUcsTUFFSCxJQUFJLE1BR00sUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgZm9yd2FyZFJlZiwgSW5qZWN0LCBJbmplY3RvciwgT25Jbml0LCBPcHRpb25hbCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFVudHlwZWRGb3JtQ29udHJvbCwgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IEJvb2xlYW5JbnB1dENvbnZlcnRlciwgTnVtYmVySW5wdXRDb252ZXJ0ZXIgfSBmcm9tICcuLi8uLi8uLi9kZWNvcmF0b3JzL2lucHV0LWNvbnZlcnRlcic7XG5pbXBvcnQgeyBJSW50ZWdlclBpcGVBcmd1bWVudCwgT0ludGVnZXJQaXBlIH0gZnJvbSAnLi4vLi4vLi4vcGlwZXMvby1pbnRlZ2VyLnBpcGUnO1xuaW1wb3J0IHsgRm9ybVZhbHVlT3B0aW9ucyB9IGZyb20gJy4uLy4uLy4uL3R5cGVzL2Zvcm0tdmFsdWUtb3B0aW9ucy50eXBlJztcbmltcG9ydCB7IFV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL3V0aWwnO1xuaW1wb3J0IHsgT0Zvcm1WYWx1ZSB9IGZyb20gJy4uLy4uL2Zvcm0vby1mb3JtLXZhbHVlJztcbmltcG9ydCB7IE9Gb3JtQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vZm9ybS9vLWZvcm0uY29tcG9uZW50JztcbmltcG9ydCB7IE9Gb3JtRGF0YUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL28tZm9ybS1kYXRhLWNvbXBvbmVudC5jbGFzcyc7XG5cbmNvbnN0IElOUFVUX1RZUEVfVEVYVCA9ICd0ZXh0J1xuY29uc3QgSU5QVVRfVFlQRV9OVU1CRVIgPSAnbnVtYmVyJ1xudHlwZSBIVE1MSW5wdXRUeXBlID0gJ3RleHQnIHwgJ251bWJlcidcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfSU5QVVRTX09fSU5URUdFUl9JTlBVVCA9IFtcbiAgJ21pbicsXG4gICdtYXgnLFxuICAnc3RlcCcsXG4gICdncm91cGluZycsXG4gICd0aG91c2FuZFNlcGFyYXRvciA6IHRob3VzYW5kLXNlcGFyYXRvcicsXG4gICdvbG9jYWxlIDogbG9jYWxlJ1xuXTtcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdvLWludGVnZXItaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogJy4vby1pbnRlZ2VyLWlucHV0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vby1pbnRlZ2VyLWlucHV0LmNvbXBvbmVudC5zY3NzJ10sXG4gIGlucHV0czogREVGQVVMVF9JTlBVVFNfT19JTlRFR0VSX0lOUFVULFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIE9JbnRlZ2VySW5wdXRDb21wb25lbnQgZXh0ZW5kcyBPRm9ybURhdGFDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkluaXQge1xuXG4gIGlucHV0VHlwZTogSFRNTElucHV0VHlwZSA9IElOUFVUX1RZUEVfTlVNQkVSO1xuXG4gIEBOdW1iZXJJbnB1dENvbnZlcnRlcigpXG4gIG1pbjogbnVtYmVyO1xuICBATnVtYmVySW5wdXRDb252ZXJ0ZXIoKVxuICBtYXg6IG51bWJlcjtcbiAgQE51bWJlcklucHV0Q29udmVydGVyKClcbiAgc3RlcDogbnVtYmVyID0gMTtcblxuICBAQm9vbGVhbklucHV0Q29udmVydGVyKClcbiAgcHJvdGVjdGVkIGdyb3VwaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIHByb3RlY3RlZCB0aG91c2FuZFNlcGFyYXRvcjogc3RyaW5nO1xuICBwcm90ZWN0ZWQgb2xvY2FsZTogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCBjb21wb25lbnRQaXBlOiBPSW50ZWdlclBpcGU7XG4gIHByb3RlY3RlZCBwaXBlQXJndW1lbnRzOiBJSW50ZWdlclBpcGVBcmd1bWVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gT0Zvcm1Db21wb25lbnQpKSBmb3JtOiBPRm9ybUNvbXBvbmVudCxcbiAgICBlbFJlZjogRWxlbWVudFJlZixcbiAgICBpbmplY3RvcjogSW5qZWN0b3JcbiAgKSB7XG4gICAgc3VwZXIoZm9ybSwgZWxSZWYsIGluamVjdG9yKTtcbiAgICB0aGlzLl9kZWZhdWx0U1FMVHlwZUtleSA9ICdJTlRFR0VSJztcbiAgICB0aGlzLmlucHV0VHlwZSA9IElOUFVUX1RZUEVfVEVYVDtcbiAgICB0aGlzLnNldENvbXBvbmVudFBpcGUoKTtcbiAgfVxuXG4gIGluaXRpYWxpemUoKTogdm9pZCB7XG4gICAgc3VwZXIuaW5pdGlhbGl6ZSgpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZVN0ZXAoKTtcbiAgfVxuXG4gIHNldENvbXBvbmVudFBpcGUoKSB7XG4gICAgdGhpcy5jb21wb25lbnRQaXBlID0gbmV3IE9JbnRlZ2VyUGlwZSh0aGlzLmluamVjdG9yKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG5cbiAgICB0aGlzLnBpcGVBcmd1bWVudHMgPSB7XG4gICAgICBncm91cGluZzogdGhpcy5ncm91cGluZyxcbiAgICAgIHRob3VzYW5kU2VwYXJhdG9yOiB0aGlzLnRob3VzYW5kU2VwYXJhdG9yLFxuICAgICAgbG9jYWxlOiB0aGlzLm9sb2NhbGVcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuc3RlcCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnN0ZXAgPSAxO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBzdXBlci5uZ0FmdGVyVmlld0luaXQoKTtcbiAgfVxuXG4gIHNldERhdGEodmFsdWU6IGFueSkge1xuICAgIHN1cGVyLnNldERhdGEodmFsdWUpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zZXRQaXBlVmFsdWUoKTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIHNldFZhbHVlKHZhbDogYW55LCBvcHRpb25zPzogRm9ybVZhbHVlT3B0aW9ucykge1xuICAgIHN1cGVyLnNldFZhbHVlKHZhbCwgb3B0aW9ucyk7XG4gICAgdGhpcy5zZXRQaXBlVmFsdWUoKTtcbiAgfVxuXG4gIGlubmVyT25Gb2N1cyhldmVudDogRm9jdXNFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKHRoaXMuaXNSZWFkT25seSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzdXBlci5pbm5lck9uRm9jdXMoZXZlbnQpO1xuICAgIHRoaXMuc2V0TnVtYmVyRE9NVmFsdWUodGhpcy5nZXRWYWx1ZSgpKTtcbiAgICBpZiAodGhpcy5zZWxlY3RBbGxPbkNsaWNrKSB7XG4gICAgICB0aGlzLnNlbGVjdFZhbHVlKCk7XG4gICAgfVxuICB9XG5cbiAgaW5uZXJPbkJsdXIoZXZlbnQ/OiBhbnkpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNSZWFkT25seSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNldFBpcGVWYWx1ZSgpO1xuICAgIGNvbnN0IGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wgPSB0aGlzLmdldENvbnRyb2woKTtcbiAgICBpZiAoZm9ybUNvbnRyb2wpIHtcbiAgICAgIGZvcm1Db250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH1cbiAgICBzdXBlci5pbm5lck9uQmx1cihldmVudCk7XG4gIH1cblxuICBzZXRQaXBlVmFsdWUoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnBpcGVBcmd1bWVudHMgIT09ICd1bmRlZmluZWQnICYmICF0aGlzLmlzRW1wdHkoKSkge1xuICAgICAgY29uc3QgcGFyc2VkVmFsdWUgPSB0aGlzLmNvbXBvbmVudFBpcGUudHJhbnNmb3JtKHRoaXMuZ2V0VmFsdWUoKSwgdGhpcy5waXBlQXJndW1lbnRzKTtcbiAgICAgIHRoaXMuc2V0VGV4dERPTVZhbHVlKHBhcnNlZFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgT0Zvcm1WYWx1ZSkge1xuICAgICAgaWYgKHRoaXMudmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZ2V0SW5wdXRFbCgpIHtcbiAgICBsZXQgaW5wdXRFbGVtZW50O1xuICAgIGlmICh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQudGFnTmFtZSA9PT0gJ0lOUFVUJykge1xuICAgICAgaW5wdXRFbGVtZW50ID0gdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnB1dEVsZW1lbnQgPSB0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ0lOUFVUJylbMF07XG4gICAgfVxuICAgIHJldHVybiBpbnB1dEVsZW1lbnQ7XG4gIH1cblxuICBzZXROdW1iZXJET01WYWx1ZSh2YWw6IGFueSkge1xuICAgIHRoaXMuc2V0SW5wdXRUeXBlQW5kVmFsdWUoSU5QVVRfVFlQRV9OVU1CRVIsIHZhbClcbiAgfVxuXG4gIHNldFRleHRET01WYWx1ZSh2YWw6IGFueSkge1xuICAgIHRoaXMuc2V0SW5wdXRUeXBlQW5kVmFsdWUoSU5QVVRfVFlQRV9URVhULCB2YWwpXG4gIH1cblxuICByZXNvbHZlVmFsaWRhdG9ycygpOiBWYWxpZGF0b3JGbltdIHtcbiAgICBjb25zdCB2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdID0gc3VwZXIucmVzb2x2ZVZhbGlkYXRvcnMoKTtcbiAgICBpZiAoVXRpbC5pc0RlZmluZWQodGhpcy5taW4pKSB7XG4gICAgICB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW4odGhpcy5taW4pKTtcbiAgICB9XG4gICAgaWYgKFV0aWwuaXNEZWZpbmVkKHRoaXMubWF4KSkge1xuICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWF4KHRoaXMubWF4KSk7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0b3JzO1xuICB9XG5cbiAgcHJvdGVjdGVkIGluaXRpYWxpemVTdGVwKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0ZXAgPD0gMCkge1xuICAgICAgdGhpcy5zdGVwID0gMTtcbiAgICAgIGNvbnNvbGUud2FybignYHN0ZXBgIGF0dHJpYnV0ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvJyk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHNldElucHV0VHlwZUFuZFZhbHVlKGlucHV0VHlwZTogSFRNTElucHV0VHlwZSwgdmFsdWU6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IGlucHV0RWxlbWVudCA9IHRoaXMuZ2V0SW5wdXRFbCgpO1xuICAgIGlmIChVdGlsLmlzRGVmaW5lZChpbnB1dEVsZW1lbnQpKSB7XG4gICAgICBpbnB1dEVsZW1lbnQudHlwZSA9IGlucHV0VHlwZTtcbiAgICAgIGlucHV0RWxlbWVudC52YWx1ZSA9ICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSA/IHZhbHVlIDogJyc7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IFtmb3JtR3JvdXBdPVwiZ2V0Rm9ybUdyb3VwKClcIiBbbWF0VG9vbHRpcF09XCJ0b29sdGlwXCIgW21hdFRvb2x0aXBDbGFzc109XCJ0b29sdGlwQ2xhc3NcIiBbbWF0VG9vbHRpcFBvc2l0aW9uXT1cInRvb2x0aXBQb3NpdGlvblwiXG4gIFttYXRUb29sdGlwU2hvd0RlbGF5XT1cInRvb2x0aXBTaG93RGVsYXlcIiBbbWF0VG9vbHRpcEhpZGVEZWxheV09XCJ0b29sdGlwSGlkZURlbGF5XCI+XG4gIDxtYXQtZm9ybS1maWVsZCBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCIgW2Zsb2F0TGFiZWxdPVwiZmxvYXRMYWJlbFwiIFtoaWRlUmVxdWlyZWRNYXJrZXJdPVwiaGlkZVJlcXVpcmVkTWFya2VyXCIgW2NsYXNzLmN1c3RvbS13aWR0aF09XCJoYXNDdXN0b21XaWR0aFwiXG4gICAgW2NsYXNzLmljb24tZmllbGRdPVwic2hvd0NsZWFyQnV0dG9uXCIgZnhGbGV4RmlsbCBbc3Vic2NyaXB0U2l6aW5nXT1cInN1YnNjcmlwdFNpemluZ1wiPlxuICAgIDxtYXQtbGFiZWwgKm5nSWY9XCJsYWJlbFZpc2libGVcIj57eyBvbGFiZWwgfCBvVHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgPGlucHV0IG1hdElucHV0IFt0eXBlXT1cImlucHV0VHlwZVwiIFtpZF09XCJnZXRBdHRyaWJ1dGUoKVwiIFtmb3JtQ29udHJvbE5hbWVdPVwiZ2V0QXR0cmlidXRlKClcIiBbcGxhY2Vob2xkZXJdPVwicGxhY2VIb2xkZXJcIlxuICAgICAgKGZvY3VzKT1cImlubmVyT25Gb2N1cygkZXZlbnQpXCIgKGJsdXIpPVwiaW5uZXJPbkJsdXIoJGV2ZW50KVwiIChjaGFuZ2UpPVwib25DaGFuZ2VFdmVudCgkZXZlbnQpXCIgW3JlYWRvbmx5XT1cImlzUmVhZE9ubHlcIiBbbWluXT1cIm1pblwiIFttYXhdPVwibWF4XCJcbiAgICAgIFtzdGVwXT1cInN0ZXBcIiBbcmVxdWlyZWRdPVwiaXNSZXF1aXJlZFwiPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiICpuZ0lmPVwic2hvd0NsZWFyQnV0dG9uXCIgbWF0U3VmZml4IG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwib25DbGlja0NsZWFyVmFsdWUoJGV2ZW50KVwiPlxuICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJvbnRpbWl6ZTpjbG9zZVwiPjwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gICAgPG1hdC1lcnJvciAqb01hdEVycm9yPVwiaGFzRXJyb3IoJ3JlcXVpcmVkJylcIj5cbiAgICAgIHt7ICdGT1JNX1ZBTElEQVRJT04uUkVRVUlSRUQnIHwgb1RyYW5zbGF0ZSB9fVxuICAgIDwvbWF0LWVycm9yPlxuICAgIDxtYXQtZXJyb3IgKm9NYXRFcnJvcj1cImhhc0Vycm9yKCdtaW4nKVwiPlxuICAgICAge3sgJ0ZPUk1fVkFMSURBVElPTi5NSU5fVkFMVUUnIHwgb1RyYW5zbGF0ZSB9fToge3sgZ2V0RXJyb3JWYWx1ZSgnbWluJywgJ21pbicpIH19XG4gICAgPC9tYXQtZXJyb3I+XG4gICAgPG1hdC1lcnJvciAqb01hdEVycm9yPVwiaGFzRXJyb3IoJ21heCcpXCI+XG4gICAgICB7eyAnRk9STV9WQUxJREFUSU9OLk1BWF9WQUxVRScgfCBvVHJhbnNsYXRlIH19OiB7eyBnZXRFcnJvclZhbHVlKCdtYXgnLCAnbWF4JykgfX1cbiAgICA8L21hdC1lcnJvcj5cbiAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBvRXJyb3Igb2YgZ2V0QWN0aXZlT0Vycm9ycygpXCI+XG4gICAgICB7eyBvRXJyb3IudGV4dCB8IG9UcmFuc2xhdGUgfX1cbiAgICA8L21hdC1lcnJvcj5cbiAgPC9tYXQtZm9ybS1maWVsZD5cbjwvZGl2PlxuIl19