UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

233 lines 30.9 kB
import { Component, EventEmitter, inject, Input, Output, ViewChild, } from '@angular/core'; import { FormBuilder, FormControl, Validators } from '@angular/forms'; import { AbstractVariable } from '@iotize/tap/data'; import { CurrentDeviceService, LibError, PendingCallManager, } from '@iotize/ionic'; import { Subject } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "@iotize/ionic"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; import * as i4 from "@ionic/angular"; /** * @deprecated */ export class MonitoringEditTextComponent { loading = false; validationMessages = { required: 'Input is required', minlength: 'Input is too short', maxlength: 'Input is too long', pattern: 'Input does not match pattern', }; subscription; _variable; inputref; pendingCallManager; set inputStream(stream) { this.setStream(stream); } set variable(variable) { this._variable = variable; } label = undefined; input = 'string'; type = 'string'; actions; clearInput = false; clearOnEdit = false; color = 'primary'; disabled = false; inputMode = 'text'; max = undefined; min = undefined; maxLength = undefined; minLength = undefined; name = undefined; pattern = undefined; placeholder = undefined; readonly = false; required = false; set value(v) { this.myControl.setValue(v); } outEvent = new EventEmitter(); myControl = new FormControl('', Validators.compose([ Validators.required, // Validators.maxLength(this.minLength), // Validators.minLength(this.maxLength), // Validators.pattern(this.pattern), ])); formBuilder = inject(FormBuilder); myGroup = this.formBuilder.group({ myControl: this.myControl, }); errorToString(item) { if (item.key in this.validationMessages) { return this.validationMessages[item.key]; } return item.value; } submit() { const newValue = this.myControl.value; if (this.actions) { this.actions.next(newValue); } if (!this._variable) { throw LibError.componentArgumentRequired(this.constructor.name, 'variable'); } this.pendingCallManager .exec(async () => { if (this._variable) { await this.startAction(this._variable.write(newValue).then(() => { this.myControl.setErrors(null); this.outEvent.emit({ type: 'WRITE_SUCCESS', payload: { newValue: newValue, }, }); })); } }) .catch((err) => { this.addFormError.bind(err); throw err; }); } onKeydown(event) { if (event.key === 'Enter') { this.submit(); } else if (event.key === 'Escape') { this.close(); } } ngAfterViewInit() { setTimeout(() => { // if (!this.inputref.nativeElement) { // console.warn('no this.inputref'); // return; // } this.inputref.setFocus(); }, 200); } close() { this.outEvent.emit({ type: 'CLOSE', }); } addFormError(err) { console.warn('Form error', err); this.myControl.setErrors({ write: err.message, }); this.outEvent.emit({ type: 'WRITE_ERROR', payload: { error: err, }, }); } refresh() { if (!this._variable) { throw LibError.componentArgumentRequired(this.constructor.name, 'variable'); } this.startAction(this._variable .read() .then((v) => { this.value = v; }) .catch(this.addFormError.bind(this))).catch((err) => { console.log(err); }); } startAction(actions) { this.setLoading(true); return actions.finally(() => this.setLoading(false)); } setLoading(value) { this.loading = value; if (this.loading) { this.myControl.disable(); } else { this.myControl.enable(); } } setStream(stream) { this.subscription?.unsubscribe(); if (stream) { this.subscription = stream.subscribe({ next: (value) => { this.value = value; }, error: (err) => { this.myControl.setErrors({ refresh: err.message, }); }, }); } } constructor(tapService) { this.pendingCallManager = PendingCallManager.create(tapService); this.loading = false; } ngOnInit() { this.refresh(); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MonitoringEditTextComponent, deps: [{ token: i1.CurrentDeviceService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MonitoringEditTextComponent, selector: "monitoring-edit-text", inputs: { inputStream: "inputStream", variable: "variable", label: "label", input: "input", type: "type", actions: "actions", clearInput: "clearInput", clearOnEdit: "clearOnEdit", color: "color", disabled: "disabled", inputMode: "inputMode", max: "max", min: "min", maxLength: "maxLength", minLength: "minLength", name: "name", pattern: "pattern", placeholder: "placeholder", readonly: "readonly", required: "required", value: "value" }, outputs: { outEvent: "outEvent" }, viewQueries: [{ propertyName: "inputref", first: true, predicate: ["inputref"], descendants: true }], ngImport: i0, template: "<ion-item [formGroup]=\"myGroup\">\n <ion-input\n auto-focus\n (keydown)=\"onKeydown($event)\"\n #inputref\n formControlName=\"myControl\"\n [max]=\"max\"\n [maxlength]=\"maxLength\"\n [min]=\"min\"\n [minlength]=\"minLength\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [type]=\"type\"\n label=\"label\"\n labelPlacement=\"start\"\n >\n </ion-input>\n <ion-buttons>\n <ion-button [disabled]=\"loading\" (click)=\"submit()\">\n <ion-icon name=\"send\" slot=\"start\"></ion-icon>\n <!-- Write -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"refresh()\">\n <ion-icon name=\"refresh\" slot=\"start\"></ion-icon>\n <!-- Refresh -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"close()\">\n <ion-icon name=\"close\" slot=\"start\"></ion-icon>\n </ion-button>\n </ion-buttons>\n <ion-spinner [style.opacity]=\"loading ? 1 : 0\" name=\"lines\"></ion-spinner>\n</ion-item>\n<ion-item\n class=\"validation-errors\"\n *ngIf=\"\n myControl.dirty &&\n myControl.errors &&\n (myControl.errors | keyvalue).length > 0\n \"\n>\n <!-- {{ myControl.errors | json}} -->\n <ng-container *ngFor=\"let item of myControl.errors | keyvalue\">\n <ion-text color=\"danger error-message \">{{ errorToString(item) }}</ion-text>\n </ng-container>\n</ion-item>\n", styles: [".error-message{font-weight:700}ion-item{background:#ccc}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i3.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i4.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i4.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { 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: "pipe", type: i2.KeyValuePipe, name: "keyvalue" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MonitoringEditTextComponent, decorators: [{ type: Component, args: [{ selector: 'monitoring-edit-text', template: "<ion-item [formGroup]=\"myGroup\">\n <ion-input\n auto-focus\n (keydown)=\"onKeydown($event)\"\n #inputref\n formControlName=\"myControl\"\n [max]=\"max\"\n [maxlength]=\"maxLength\"\n [min]=\"min\"\n [minlength]=\"minLength\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [type]=\"type\"\n label=\"label\"\n labelPlacement=\"start\"\n >\n </ion-input>\n <ion-buttons>\n <ion-button [disabled]=\"loading\" (click)=\"submit()\">\n <ion-icon name=\"send\" slot=\"start\"></ion-icon>\n <!-- Write -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"refresh()\">\n <ion-icon name=\"refresh\" slot=\"start\"></ion-icon>\n <!-- Refresh -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"close()\">\n <ion-icon name=\"close\" slot=\"start\"></ion-icon>\n </ion-button>\n </ion-buttons>\n <ion-spinner [style.opacity]=\"loading ? 1 : 0\" name=\"lines\"></ion-spinner>\n</ion-item>\n<ion-item\n class=\"validation-errors\"\n *ngIf=\"\n myControl.dirty &&\n myControl.errors &&\n (myControl.errors | keyvalue).length > 0\n \"\n>\n <!-- {{ myControl.errors | json}} -->\n <ng-container *ngFor=\"let item of myControl.errors | keyvalue\">\n <ion-text color=\"danger error-message \">{{ errorToString(item) }}</ion-text>\n </ng-container>\n</ion-item>\n", styles: [".error-message{font-weight:700}ion-item{background:#ccc}\n"] }] }], ctorParameters: () => [{ type: i1.CurrentDeviceService }], propDecorators: { inputref: [{ type: ViewChild, args: ['inputref', { static: false }] }], inputStream: [{ type: Input }], variable: [{ type: Input }], label: [{ type: Input }], input: [{ type: Input }], type: [{ type: Input }], actions: [{ type: Input }], clearInput: [{ type: Input }], clearOnEdit: [{ type: Input }], color: [{ type: Input }], disabled: [{ type: Input }], inputMode: [{ type: Input }], max: [{ type: Input }], min: [{ type: Input }], maxLength: [{ type: Input }], minLength: [{ type: Input }], name: [{ type: Input }], pattern: [{ type: Input }], placeholder: [{ type: Input }], readonly: [{ type: Input }], required: [{ type: Input }], value: [{ type: Input }], outEvent: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9uaXRvcmluZy1lZGl0LXRleHQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL21vbml0b3Jpbmcvc3JjL2xpYi91aS1jb21wb25lbnRzL21vbml0b3JpbmctZWRpdC10ZXh0L21vbml0b3JpbmctZWRpdC10ZXh0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9tb25pdG9yaW5nL3NyYy9saWIvdWktY29tcG9uZW50cy9tb25pdG9yaW5nLWVkaXQtdGV4dC9tb25pdG9yaW5nLWVkaXQtdGV4dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUVMLE1BQU0sRUFDTixTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDcEQsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixRQUFRLEVBQ1Isa0JBQWtCLEdBQ25CLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBYyxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDOzs7Ozs7QUFPekQ7O0dBRUc7QUFNSCxNQUFNLE9BQU8sMkJBQTJCO0lBQ3RDLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsa0JBQWtCLEdBQUc7UUFDbkIsUUFBUSxFQUFFLG1CQUFtQjtRQUM3QixTQUFTLEVBQUUsb0JBQW9CO1FBQy9CLFNBQVMsRUFBRSxtQkFBbUI7UUFDOUIsT0FBTyxFQUFFLDhCQUE4QjtLQUN4QyxDQUFDO0lBRU0sWUFBWSxDQUFnQjtJQUVwQyxTQUFT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LEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxHQUFHO3NCQUFYLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRU8sS0FBSztzQkFBakIsS0FBSztnQkFJSSxRQUFRO3NCQUFqQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIGluamVjdCxcbiAgSW5wdXQsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWJzdHJhY3RWYXJpYWJsZSB9IGZyb20gJ0Bpb3RpemUvdGFwL2RhdGEnO1xuaW1wb3J0IHtcbiAgQ3VycmVudERldmljZVNlcnZpY2UsXG4gIExpYkVycm9yLFxuICBQZW5kaW5nQ2FsbE1hbmFnZXIsXG59IGZyb20gJ0Bpb3RpemUvaW9uaWMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9uaXRvcmluZ0VkaXRUZXh0RXZlbnQge1xuICB0eXBlOiAnQ0xPU0UnIHwgJ1dSSVRFX1NVQ0NFU1MnIHwgJ1dSSVRFX0VSUk9SJztcbiAgcGF5bG9hZD86IGFueTtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdtb25pdG9yaW5nLWVkaXQtdGV4dCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9tb25pdG9yaW5nLWVkaXQtdGV4dC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL21vbml0b3JpbmctZWRpdC10ZXh0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIE1vbml0b3JpbmdFZGl0VGV4dENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG4gIGxvYWRpbmcgPSBmYWxzZTtcblxuICB2YWxpZGF0aW9uTWVzc2FnZXMgPSB7XG4gICAgcmVxdWlyZWQ6ICdJbnB1dCBpcyByZXF1aXJlZCcsXG4gICAgbWlubGVuZ3RoOiAnSW5wdXQgaXMgdG9vIHNob3J0JyxcbiAgICBtYXhsZW5ndGg6ICdJbnB1dCBpcyB0b28gbG9uZycsXG4gICAgcGF0dGVybjogJ0lucHV0IGRvZXMgbm90IG1hdGNoIHBhdHRlcm4nLFxuICB9O1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gIF92YXJpYWJsZT86IEFic3RyYWN0VmFyaWFibGU8YW55PjtcblxuICBAVmlld0NoaWxkKCdpbnB1dHJlZicsIHsgc3RhdGljOiBmYWxzZSB9KSBpbnB1dHJlZjogYW55O1xuICBwZW5kaW5nQ2FsbE1hbmFnZXI6IFBlbmRpbmdDYWxsTWFuYWdlcjtcblxuICBASW5wdXQoKVxuICBzZXQgaW5wdXRTdHJlYW0oc3RyZWFtOiBPYnNlcnZhYmxlPGFueT4gfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnNldFN0cmVhbShzdHJlYW0pO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IHZhcmlhYmxlKHZhcmlhYmxlOiBBYnN0cmFjdFZhcmlhYmxlPGFueT4pIHtcbiAgICB0aGlzLl92YXJpYWJsZSA9IHZhcmlhYmxlO1xuICB9XG5cbiAgQElucHV0KCkgbGFiZWw/OiBzdHJpbmcgPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGlucHV0ID0gJ3N0cmluZyc7XG4gIEBJbnB1dCgpIHR5cGUgPSAnc3RyaW5nJztcbiAgQElucHV0KCkgYWN0aW9ucz86IFN1YmplY3Q8YW55PjtcblxuICBASW5wdXQoKSBjbGVhcklucHV0ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNsZWFyT25FZGl0ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNvbG9yID0gJ3ByaW1hcnknO1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBpbnB1dE1vZGUgPSAndGV4dCc7XG4gIEBJbnB1dCgpIG1heD86IG51bWJlciA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgbWluPzogbnVtYmVyID0gdW5kZWZpbmVkO1xuICBASW5wdXQoKSBtYXhMZW5ndGg/OiBudW1iZXIgPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIG1pbkxlbmd0aD86IG51bWJlciA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgbmFtZT8gPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHBhdHRlcm4/ID0gdW5kZWZpbmVkO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcj8gPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHJlYWRvbmx5ID0gZmFsc2U7XG4gIEBJbnB1dCgpIHJlcXVpcmVkID0gZmFsc2U7XG5cbiAgQElucHV0KCkgc2V0IHZhbHVlKHY6IGFueSkge1xuICAgIHRoaXMubXlDb250cm9sLnNldFZhbHVlKHYpO1xuICB9XG5cbiAgQE91dHB1dCgpIG91dEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxNb25pdG9yaW5nRWRpdFRleHRFdmVudD4oKTtcblxuICBwdWJsaWMgbXlDb250cm9sOiBGb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbChcbiAgICAnJyxcbiAgICBWYWxpZGF0b3JzLmNvbXBvc2UoW1xuICAgICAgVmFsaWRhdG9ycy5yZXF1aXJlZCxcbiAgICAgIC8vIFZhbGlkYXRvcnMubWF4TGVuZ3RoKHRoaXMubWluTGVuZ3RoKSxcbiAgICAgIC8vIFZhbGlkYXRvcnMubWluTGVuZ3RoKHRoaXMubWF4TGVuZ3RoKSxcbiAgICAgIC8vIFZhbGlkYXRvcnMucGF0dGVybih0aGlzLnBhdHRlcm4pLFxuICAgIF0pXG4gICk7XG5cbiAgcHJvdGVjdGVkIGZvcm1CdWlsZGVyID0gaW5qZWN0KEZvcm1CdWlsZGVyKTtcblxuICBteUdyb3VwID0gdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7XG4gICAgbXlDb250cm9sOiB0aGlzLm15Q29udHJvbCxcbiAgfSk7XG5cbiAgZXJyb3JUb1N0cmluZyhpdGVtOiB7IGtleTogc3RyaW5nOyB2YWx1ZTogYW55IH0pIHtcbiAgICBpZiAoaXRlbS5rZXkgaW4gdGhpcy52YWxpZGF0aW9uTWVzc2FnZXMpIHtcbiAgICAgIHJldHVybiAodGhpcy52YWxpZGF0aW9uTWVzc2FnZXMgYXMgYW55KVtpdGVtLmtleV07XG4gICAgfVxuICAgIHJldHVybiBpdGVtLnZhbHVlO1xuICB9XG5cbiAgc3VibWl0KCkge1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gdGhpcy5teUNvbnRyb2wudmFsdWU7XG4gICAgaWYgKHRoaXMuYWN0aW9ucykge1xuICAgICAgdGhpcy5hY3Rpb25zLm5leHQobmV3VmFsdWUpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuX3ZhcmlhYmxlKSB7XG4gICAgICB0aHJvdyBMaWJFcnJvci5jb21wb25lbnRBcmd1bWVudFJlcXVpcmVkKFxuICAgICAgICB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICd2YXJpYWJsZSdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5wZW5kaW5nQ2FsbE1hbmFnZXJcbiAgICAgIC5leGVjKGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX3ZhcmlhYmxlKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5zdGFydEFjdGlvbihcbiAgICAgICAgICAgIHRoaXMuX3ZhcmlhYmxlLndyaXRlKG5ld1ZhbHVlKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5teUNvbnRyb2wuc2V0RXJyb3JzKG51bGwpO1xuICAgICAgICAgICAgICB0aGlzLm91dEV2ZW50LmVtaXQoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdXUklURV9TVUNDRVNTJyxcbiAgICAgICAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogbmV3VmFsdWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICB0aGlzLmFkZEZvcm1FcnJvci5iaW5kKGVycik7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0pO1xuICB9XG5cbiAgb25LZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJykge1xuICAgICAgdGhpcy5zdWJtaXQoKTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAvLyBpZiAoIXRoaXMuaW5wdXRyZWYubmF0aXZlRWxlbWVudCkge1xuICAgICAgLy8gICBjb25zb2xlLndhcm4oJ25vIHRoaXMuaW5wdXRyZWYnKTtcbiAgICAgIC8vICAgcmV0dXJuO1xuICAgICAgLy8gfVxuICAgICAgdGhpcy5pbnB1dHJlZi5zZXRGb2N1cygpO1xuICAgIH0sIDIwMCk7XG4gIH1cblxuICBjbG9zZSgpIHtcbiAgICB0aGlzLm91dEV2ZW50LmVtaXQoe1xuICAgICAgdHlwZTogJ0NMT1NFJyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRm9ybUVycm9yKGVycjogRXJyb3IpIHtcbiAgICBjb25zb2xlLndhcm4oJ0Zvcm0gZXJyb3InLCBlcnIpO1xuICAgIHRoaXMubXlDb250cm9sLnNldEVycm9ycyh7XG4gICAgICB3cml0ZTogZXJyLm1lc3NhZ2UsXG4gICAgfSk7XG4gICAgdGhpcy5vdXRFdmVudC5lbWl0KHtcbiAgICAgIHR5cGU6ICdXUklURV9FUlJPUicsXG4gICAgICBwYXlsb2FkOiB7XG4gICAgICAgIGVycm9yOiBlcnIsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcmVmcmVzaCgpIHtcbiAgICBpZiAoIXRoaXMuX3ZhcmlhYmxlKSB7XG4gICAgICB0aHJvdyBMaWJFcnJvci5jb21wb25lbnRBcmd1bWVudFJlcXVpcmVkKFxuICAgICAgICB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICd2YXJpYWJsZSdcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuc3RhcnRBY3Rpb24oXG4gICAgICB0aGlzLl92YXJpYWJsZVxuICAgICAgICAucmVhZCgpXG4gICAgICAgIC50aGVuKCh2KSA9PiB7XG4gICAgICAgICAgdGhpcy52YWx1ZSA9IHY7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCh0aGlzLmFkZEZvcm1FcnJvci5iaW5kKHRoaXMpKVxuICAgICkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRBY3Rpb24oYWN0aW9uczogUHJvbWlzZTxhbnk+KTogUHJvbWlzZTxhbnk+IHtcbiAgICB0aGlzLnNldExvYWRpbmcodHJ1ZSk7XG4gICAgcmV0dXJuIGFjdGlvbnMuZmluYWxseSgoKSA9PiB0aGlzLnNldExvYWRpbmcoZmFsc2UpKTtcbiAgfVxuXG4gIHNldExvYWRpbmcodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRpbmcgPSB2YWx1ZTtcbiAgICBpZiAodGhpcy5sb2FkaW5nKSB7XG4gICAgICB0aGlzLm15Q29udHJvbC5kaXNhYmxlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubXlDb250cm9sLmVuYWJsZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U3RyZWFtKHN0cmVhbTogT2JzZXJ2YWJsZTxhbnk+IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHN0cmVhbSkge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb24gPSBzdHJlYW0uc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIHRoaXMubXlDb250cm9sLnNldEVycm9ycyh7XG4gICAgICAgICAgICByZWZyZXNoOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHRhcFNlcnZpY2U6IEN1cnJlbnREZXZpY2VTZXJ2aWNlKSB7XG4gICAgdGhpcy5wZW5kaW5nQ2FsbE1hbmFnZXIgPSBQZW5kaW5nQ2FsbE1hbmFnZXIuY3JlYXRlKHRhcFNlcnZpY2UpO1xuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gIH1cbn1cbiIsIjxpb24taXRlbSBbZm9ybUdyb3VwXT1cIm15R3JvdXBcIj5cbiAgPGlvbi1pbnB1dFxuICAgIGF1dG8tZm9jdXNcbiAgICAoa2V5ZG93bik9XCJvbktleWRvd24oJGV2ZW50KVwiXG4gICAgI2lucHV0cmVmXG4gICAgZm9ybUNvbnRyb2xOYW1lPVwibXlDb250cm9sXCJcbiAgICBbbWF4XT1cIm1heFwiXG4gICAgW21heGxlbmd0aF09XCJtYXhMZW5ndGhcIlxuICAgIFttaW5dPVwibWluXCJcbiAgICBbbWlubGVuZ3RoXT1cIm1pbkxlbmd0aFwiXG4gICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgIFt0eXBlXT1cInR5cGVcIlxuICAgIGxhYmVsPVwibGFiZWxcIlxuICAgIGxhYmVsUGxhY2VtZW50PVwic3RhcnRcIlxuICA+XG4gIDwvaW9uLWlucHV0PlxuICA8aW9uLWJ1dHRvbnM+XG4gICAgPGlvbi1idXR0b24gW2Rpc2FibGVkXT1cImxvYWRpbmdcIiAoY2xpY2spPVwic3VibWl0KClcIj5cbiAgICAgIDxpb24taWNvbiBuYW1lPVwic2VuZFwiIHNsb3Q9XCJzdGFydFwiPjwvaW9uLWljb24+XG4gICAgICA8IS0tIFdyaXRlIC0tPlxuICAgIDwvaW9uLWJ1dHRvbj5cbiAgICA8aW9uLWJ1dHRvbiBbZGlzYWJsZWRdPVwibG9hZGluZ1wiIChjbGljayk9XCJyZWZyZXNoKClcIj5cbiAgICAgIDxpb24taWNvbiBuYW1lPVwicmVmcmVzaFwiIHNsb3Q9XCJzdGFydFwiPjwvaW9uLWljb24+XG4gICAgICA8IS0tIFJlZnJlc2ggLS0+XG4gICAgPC9pb24tYnV0dG9uPlxuICAgIDxpb24tYnV0dG9uIFtkaXNhYmxlZF09XCJsb2FkaW5nXCIgKGNsaWNrKT1cImNsb3NlKClcIj5cbiAgICAgIDxpb24taWNvbiBuYW1lPVwiY2xvc2VcIiBzbG90PVwic3RhcnRcIj48L2lvbi1pY29uPlxuICAgIDwvaW9uLWJ1dHRvbj5cbiAgPC9pb24tYnV0dG9ucz5cbiAgPGlvbi1zcGlubmVyIFtzdHlsZS5vcGFjaXR5XT1cImxvYWRpbmcgPyAxIDogMFwiIG5hbWU9XCJsaW5lc1wiPjwvaW9uLXNwaW5uZXI+XG48L2lvbi1pdGVtPlxuPGlvbi1pdGVtXG4gIGNsYXNzPVwidmFsaWRhdGlvbi1lcnJvcnNcIlxuICAqbmdJZj1cIlxuICAgIG15Q29udHJvbC5kaXJ0eSAmJlxuICAgIG15Q29udHJvbC5lcnJvcnMgJiZcbiAgICAobXlDb250cm9sLmVycm9ycyB8IGtleXZhbHVlKS5sZW5ndGggPiAwXG4gIFwiXG4+XG4gIDwhLS0ge3sgbXlDb250cm9sLmVycm9ycyB8IGpzb259fSAtLT5cbiAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBteUNvbnRyb2wuZXJyb3JzIHwga2V5dmFsdWVcIj5cbiAgICA8aW9uLXRleHQgY29sb3I9XCJkYW5nZXIgZXJyb3ItbWVzc2FnZSBcIj57eyBlcnJvclRvU3RyaW5nKGl0ZW0pIH19PC9pb24tdGV4dD5cbiAgPC9uZy1jb250YWluZXI+XG48L2lvbi1pdGVtPlxuIl19