UNPKG

@jsonforms/angular-material

Version:

Material Renderer Set for Angular module of JSON Forms

173 lines (169 loc) 22.3 kB
/* The MIT License Copyright (c) 2017-2019 EclipseSource Munich https://github.com/eclipsesource/jsonforms Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { isIntegerControl, isNumberControl, or, rankWith, } from '@jsonforms/core'; import merge from 'lodash/merge'; import * as i0 from "@angular/core"; import * as i1 from "@jsonforms/angular"; import * as i2 from "@angular/common"; import * as i3 from "@angular/material/form-field"; import * as i4 from "@angular/material/input"; import * as i5 from "@angular/forms"; export class NumberControlRenderer extends JsonFormsControl { MAXIMUM_FRACTIONAL_DIGITS = 20; oldValue; min; max; multipleOf; locale; numberFormat; decimalSeparator; focused = false; constructor(jsonformsService) { super(jsonformsService); } onChange(ev) { const data = this.oldValue ? ev.target.value.replace(this.oldValue, '') : ev.target.value; // ignore these if (data === '.' || data === ',' || data === ' ' || // if the value is 0 and we already have a value then we ignore (data === '0' && this.getValue() !== '' && // a 0 in the first place ((ev.target.selectionStart === 1 && ev.target.selectionEnd === 1) || // or in the last place as this doesn't change the value (when there is a separator) (ev.target.selectionStart === ev.target.value.length && ev.target.selectionEnd === ev.target.value.length && ev.target.value.indexOf(this.decimalSeparator) !== -1)))) { this.oldValue = ev.target.value; return; } super.onChange(ev); this.oldValue = this.getValue(); } getEventValue = (event) => { const cleanPattern = new RegExp(`[^-+0-9${this.decimalSeparator}]`, 'g'); const cleaned = event.target.value.replace(cleanPattern, ''); const normalized = cleaned.replace(this.decimalSeparator, '.'); if (normalized === '') { return undefined; } // convert to number const number = +normalized; // if not a number just return the string if (Number.isNaN(number)) { return event.target.value; } return number; }; getValue = () => { if (this.data !== undefined && this.data !== null) { if (typeof this.data === 'number') { return this.numberFormat.format(this.data); } return this.data; } return ''; }; mapAdditionalProps(props) { if (this.scopedSchema) { const testerContext = { rootSchema: this.rootSchema, config: props.config, }; const defaultStep = isNumberControl(this.uischema, this.rootSchema, testerContext) ? 0.1 : 1; this.min = this.scopedSchema.minimum; this.max = this.scopedSchema.maximum; this.multipleOf = this.scopedSchema.multipleOf || defaultStep; const appliedUiSchemaOptions = merge({}, props.config, this.uischema.options); const currentLocale = this.jsonFormsService.getLocale(); if (this.locale === undefined || this.locale !== currentLocale) { this.locale = currentLocale; this.numberFormat = new Intl.NumberFormat(this.locale, { useGrouping: appliedUiSchemaOptions.useGrouping, maximumFractionDigits: this.MAXIMUM_FRACTIONAL_DIGITS, }); this.determineDecimalSeparator(); this.oldValue = this.getValue(); } this.form.setValue(this.getValue()); } } determineDecimalSeparator() { const example = this.numberFormat.format(1.1); this.decimalSeparator = example.charAt(1); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NumberControlRenderer, deps: [{ token: i1.JsonFormsAngularService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NumberControlRenderer, selector: "NumberControlRenderer", usesInheritance: true, ngImport: i0, template: ` <mat-form-field [ngStyle]="{ display: hidden ? 'none' : '' }"> <mat-label>{{ label }}</mat-label> <input matInput (input)="onChange($event)" [value]="getValue()" [id]="id" [formControl]="form" [min]="min" [max]="max" [step]="multipleOf" (focus)="focused = true" (focusout)="focused = false" /> <mat-hint *ngIf="shouldShowUnfocusedDescription() || focused">{{ description }}</mat-hint> <mat-error>{{ error }}</mat-error> </mat-form-field> `, isInline: true, styles: [":host{display:flex;flex-direction:row}mat-form-field{flex:1 1 auto}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i4.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: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NumberControlRenderer, decorators: [{ type: Component, args: [{ selector: 'NumberControlRenderer', template: ` <mat-form-field [ngStyle]="{ display: hidden ? 'none' : '' }"> <mat-label>{{ label }}</mat-label> <input matInput (input)="onChange($event)" [value]="getValue()" [id]="id" [formControl]="form" [min]="min" [max]="max" [step]="multipleOf" (focus)="focused = true" (focusout)="focused = false" /> <mat-hint *ngIf="shouldShowUnfocusedDescription() || focused">{{ description }}</mat-hint> <mat-error>{{ error }}</mat-error> </mat-form-field> `, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [":host{display:flex;flex-direction:row}mat-form-field{flex:1 1 auto}\n"] }] }], ctorParameters: () => [{ type: i1.JsonFormsAngularService }] }); export const NumberControlRendererTester = rankWith(2, or(isNumberControl, isIntegerControl)); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVtYmVyLnJlbmRlcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYnJhcnkvY29udHJvbHMvbnVtYmVyLnJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQXVCRTtBQUNGLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGdCQUFnQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDL0UsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsRUFBRSxFQUVGLFFBQVEsR0FFVCxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sS0FBSyxNQUFNLGNBQWMsQ0FBQzs7Ozs7OztBQXVDakMsTUFBTSxPQUFPLHFCQUFzQixTQUFRLGdCQUFnQjtJQUN4Qyx5QkFBeUIsR0FBRyxFQUFFLENBQUM7SUFFaEQsUUFBUSxDQUFTO0lBQ2pCLEdBQUcsQ0FBUztJQUNaLEdBQUcsQ0FBUztJQUNaLFVBQVUsQ0FBUztJQUNuQixNQUFNLENBQVM7SUFDZixZQUFZLENBQW9CO0lBQ2hDLGdCQUFnQixDQUFTO0lBQ3pCLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsWUFBWSxnQkFBeUM7UUFDbkQsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVELFFBQVEsQ0FBQyxFQUFPO1FBQ2QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDeEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztZQUM1QyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDcEIsZUFBZTtRQUNmLElBQ0UsSUFBSSxLQUFLLEdBQUc7WUFDWixJQUFJLEtBQUssR0FBRztZQUNaLElBQUksS0FBSyxHQUFHO1lBQ1osK0RBQStEO1lBQy9ELENBQUMsSUFBSSxLQUFLLEdBQUc7Z0JBQ1gsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUU7Z0JBQ3RCLHlCQUF5QjtnQkFDekIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsY0FBYyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUM7b0JBQy9ELG9GQUFvRjtvQkFDcEYsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLGNBQWMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNO3dCQUNsRCxFQUFFLENBQUMsTUFBTSxDQUFDLFlBQVksS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNO3dCQUNqRCxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQzlELENBQUM7WUFDRCxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1lBQ2hDLE9BQU87UUFDVCxDQUFDO1FBQ0QsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsYUFBYSxHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUU7UUFDN0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxNQUFNLENBQUMsVUFBVSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN6RSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdELE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRS9ELElBQUksVUFBVSxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7UUFFRCxvQkFBb0I7UUFDcEIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxVQUFVLENBQUM7UUFDM0IseUNBQXlDO1FBQ3pDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ3pCLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDNUIsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUMsQ0FBQztJQUVGLFFBQVEsR0FBRyxHQUFHLEVBQUU7UUFDZCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDbEQsSUFBSSxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ2xDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdDLENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDbkIsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQyxDQUFDO0lBRUYsa0JBQWtCLENBQUMsS0FBMEI7UUFDM0MsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEIsTUFBTSxhQUFhLEdBQUc7Z0JBQ3BCLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtnQkFDM0IsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO2FBQ3JCLENBQUM7WUFDRixNQUFNLFdBQVcsR0FBRyxlQUFlLENBQ2pDLElBQUksQ0FBQyxRQUFRLEVBQ2IsSUFBSSxDQUFDLFVBQVUsRUFDZixhQUFhLENBQ2Q7Z0JBQ0MsQ0FBQyxDQUFDLEdBQUc7Z0JBQ0wsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNOLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUM7WUFDckMsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQztZQUNyQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxJQUFJLFdBQVcsQ0FBQztZQUM5RCxNQUFNLHNCQUFzQixHQUFHLEtBQUssQ0FDbEMsRUFBRSxFQUNGLEtBQUssQ0FBQyxNQUFNLEVBQ1osSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQ3RCLENBQUM7WUFDRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDeEQsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLGFBQWEsRUFBRSxDQUFDO2dCQUMvRCxJQUFJLENBQUMsTUFBTSxHQUFHLGFBQWEsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtvQkFDckQsV0FBVyxFQUFFLHNCQUFzQixDQUFDLFdBQVc7b0JBQy9DLHFCQUFxQixFQUFFLElBQUksQ0FBQyx5QkFBeUI7aUJBQ3RELENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEMsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRU8seUJBQXlCO1FBQy9CLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7d0dBNUdVLHFCQUFxQjs0RkFBckIscUJBQXFCLG9GQW5DdEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JUOzs0RkFlVSxxQkFBcUI7a0JBckNqQyxTQUFTOytCQUNFLHVCQUF1QixZQUN2Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQsbUJBWWdCLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsS0FBSzs7QUFnSG5CLE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFpQixRQUFRLENBQy9ELENBQUMsRUFDRCxFQUFFLENBQUMsZUFBZSxFQUFFLGdCQUFnQixDQUFDLENBQ3RDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBUaGUgTUlUIExpY2Vuc2VcbiAgXG4gIENvcHlyaWdodCAoYykgMjAxNy0yMDE5IEVjbGlwc2VTb3VyY2UgTXVuaWNoXG4gIGh0dHBzOi8vZ2l0aHViLmNvbS9lY2xpcHNlc291cmNlL2pzb25mb3Jtc1xuICBcbiAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAgXG4gIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICBcbiAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICBUSEUgU09GVFdBUkUuXG4qL1xuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSnNvbkZvcm1zQW5ndWxhclNlcnZpY2UsIEpzb25Gb3Jtc0NvbnRyb2wgfSBmcm9tICdAanNvbmZvcm1zL2FuZ3VsYXInO1xuaW1wb3J0IHtcbiAgaXNJbnRlZ2VyQ29udHJvbCxcbiAgaXNOdW1iZXJDb250cm9sLFxuICBvcixcbiAgUmFua2VkVGVzdGVyLFxuICByYW5rV2l0aCxcbiAgU3RhdGVQcm9wc09mQ29udHJvbCxcbn0gZnJvbSAnQGpzb25mb3Jtcy9jb3JlJztcbmltcG9ydCBtZXJnZSBmcm9tICdsb2Rhc2gvbWVyZ2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdOdW1iZXJDb250cm9sUmVuZGVyZXInLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxtYXQtZm9ybS1maWVsZCBbbmdTdHlsZV09XCJ7IGRpc3BsYXk6IGhpZGRlbiA/ICdub25lJyA6ICcnIH1cIj5cbiAgICAgIDxtYXQtbGFiZWw+e3sgbGFiZWwgfX08L21hdC1sYWJlbD5cbiAgICAgIDxpbnB1dFxuICAgICAgICBtYXRJbnB1dFxuICAgICAgICAoaW5wdXQpPVwib25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgIFt2YWx1ZV09XCJnZXRWYWx1ZSgpXCJcbiAgICAgICAgW2lkXT1cImlkXCJcbiAgICAgICAgW2Zvcm1Db250cm9sXT1cImZvcm1cIlxuICAgICAgICBbbWluXT1cIm1pblwiXG4gICAgICAgIFttYXhdPVwibWF4XCJcbiAgICAgICAgW3N0ZXBdPVwibXVsdGlwbGVPZlwiXG4gICAgICAgIChmb2N1cyk9XCJmb2N1c2VkID0gdHJ1ZVwiXG4gICAgICAgIChmb2N1c291dCk9XCJmb2N1c2VkID0gZmFsc2VcIlxuICAgICAgLz5cbiAgICAgIDxtYXQtaGludCAqbmdJZj1cInNob3VsZFNob3dVbmZvY3VzZWREZXNjcmlwdGlvbigpIHx8IGZvY3VzZWRcIj57e1xuICAgICAgICBkZXNjcmlwdGlvblxuICAgICAgfX08L21hdC1oaW50PlxuICAgICAgPG1hdC1lcnJvcj57eyBlcnJvciB9fTwvbWF0LWVycm9yPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gIGAsXG4gIHN0eWxlczogW1xuICAgIGBcbiAgICAgIDpob3N0IHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICAgIH1cbiAgICAgIG1hdC1mb3JtLWZpZWxkIHtcbiAgICAgICAgZmxleDogMSAxIGF1dG87XG4gICAgICB9XG4gICAgYCxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IGZhbHNlLFxufSlcbmV4cG9ydCBjbGFzcyBOdW1iZXJDb250cm9sUmVuZGVyZXIgZXh0ZW5kcyBKc29uRm9ybXNDb250cm9sIHtcbiAgcHJpdmF0ZSByZWFkb25seSBNQVhJTVVNX0ZSQUNUSU9OQUxfRElHSVRTID0gMjA7XG5cbiAgb2xkVmFsdWU6IHN0cmluZztcbiAgbWluOiBudW1iZXI7XG4gIG1heDogbnVtYmVyO1xuICBtdWx0aXBsZU9mOiBudW1iZXI7XG4gIGxvY2FsZTogc3RyaW5nO1xuICBudW1iZXJGb3JtYXQ6IEludGwuTnVtYmVyRm9ybWF0O1xuICBkZWNpbWFsU2VwYXJhdG9yOiBzdHJpbmc7XG4gIGZvY3VzZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihqc29uZm9ybXNTZXJ2aWNlOiBKc29uRm9ybXNBbmd1bGFyU2VydmljZSkge1xuICAgIHN1cGVyKGpzb25mb3Jtc1NlcnZpY2UpO1xuICB9XG5cbiAgb25DaGFuZ2UoZXY6IGFueSkge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLm9sZFZhbHVlXG4gICAgICA/IGV2LnRhcmdldC52YWx1ZS5yZXBsYWNlKHRoaXMub2xkVmFsdWUsICcnKVxuICAgICAgOiBldi50YXJnZXQudmFsdWU7XG4gICAgLy8gaWdub3JlIHRoZXNlXG4gICAgaWYgKFxuICAgICAgZGF0YSA9PT0gJy4nIHx8XG4gICAgICBkYXRhID09PSAnLCcgfHxcbiAgICAgIGRhdGEgPT09ICcgJyB8fFxuICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIDAgYW5kIHdlIGFscmVhZHkgaGF2ZSBhIHZhbHVlIHRoZW4gd2UgaWdub3JlXG4gICAgICAoZGF0YSA9PT0gJzAnICYmXG4gICAgICAgIHRoaXMuZ2V0VmFsdWUoKSAhPT0gJycgJiZcbiAgICAgICAgLy8gYSAwIGluIHRoZSBmaXJzdCBwbGFjZVxuICAgICAgICAoKGV2LnRhcmdldC5zZWxlY3Rpb25TdGFydCA9PT0gMSAmJiBldi50YXJnZXQuc2VsZWN0aW9uRW5kID09PSAxKSB8fFxuICAgICAgICAgIC8vIG9yIGluIHRoZSBsYXN0IHBsYWNlIGFzIHRoaXMgZG9lc24ndCBjaGFuZ2UgdGhlIHZhbHVlICh3aGVuIHRoZXJlIGlzIGEgc2VwYXJhdG9yKVxuICAgICAgICAgIChldi50YXJnZXQuc2VsZWN0aW9uU3RhcnQgPT09IGV2LnRhcmdldC52YWx1ZS5sZW5ndGggJiZcbiAgICAgICAgICAgIGV2LnRhcmdldC5zZWxlY3Rpb25FbmQgPT09IGV2LnRhcmdldC52YWx1ZS5sZW5ndGggJiZcbiAgICAgICAgICAgIGV2LnRhcmdldC52YWx1ZS5pbmRleE9mKHRoaXMuZGVjaW1hbFNlcGFyYXRvcikgIT09IC0xKSkpXG4gICAgKSB7XG4gICAgICB0aGlzLm9sZFZhbHVlID0gZXYudGFyZ2V0LnZhbHVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzdXBlci5vbkNoYW5nZShldik7XG4gICAgdGhpcy5vbGRWYWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcbiAgfVxuXG4gIGdldEV2ZW50VmFsdWUgPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgIGNvbnN0IGNsZWFuUGF0dGVybiA9IG5ldyBSZWdFeHAoYFteLSswLTkke3RoaXMuZGVjaW1hbFNlcGFyYXRvcn1dYCwgJ2cnKTtcbiAgICBjb25zdCBjbGVhbmVkID0gZXZlbnQudGFyZ2V0LnZhbHVlLnJlcGxhY2UoY2xlYW5QYXR0ZXJuLCAnJyk7XG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IGNsZWFuZWQucmVwbGFjZSh0aGlzLmRlY2ltYWxTZXBhcmF0b3IsICcuJyk7XG5cbiAgICBpZiAobm9ybWFsaXplZCA9PT0gJycpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLy8gY29udmVydCB0byBudW1iZXJcbiAgICBjb25zdCBudW1iZXIgPSArbm9ybWFsaXplZDtcbiAgICAvLyBpZiBub3QgYSBudW1iZXIganVzdCByZXR1cm4gdGhlIHN0cmluZ1xuICAgIGlmIChOdW1iZXIuaXNOYU4obnVtYmVyKSkge1xuICAgICAgcmV0dXJuIGV2ZW50LnRhcmdldC52YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG51bWJlcjtcbiAgfTtcblxuICBnZXRWYWx1ZSA9ICgpID0+IHtcbiAgICBpZiAodGhpcy5kYXRhICE9PSB1bmRlZmluZWQgJiYgdGhpcy5kYXRhICE9PSBudWxsKSB7XG4gICAgICBpZiAodHlwZW9mIHRoaXMuZGF0YSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubnVtYmVyRm9ybWF0LmZvcm1hdCh0aGlzLmRhdGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9O1xuXG4gIG1hcEFkZGl0aW9uYWxQcm9wcyhwcm9wczogU3RhdGVQcm9wc09mQ29udHJvbCkge1xuICAgIGlmICh0aGlzLnNjb3BlZFNjaGVtYSkge1xuICAgICAgY29uc3QgdGVzdGVyQ29udGV4dCA9IHtcbiAgICAgICAgcm9vdFNjaGVtYTogdGhpcy5yb290U2NoZW1hLFxuICAgICAgICBjb25maWc6IHByb3BzLmNvbmZpZyxcbiAgICAgIH07XG4gICAgICBjb25zdCBkZWZhdWx0U3RlcCA9IGlzTnVtYmVyQ29udHJvbChcbiAgICAgICAgdGhpcy51aXNjaGVtYSxcbiAgICAgICAgdGhpcy5yb290U2NoZW1hLFxuICAgICAgICB0ZXN0ZXJDb250ZXh0XG4gICAgICApXG4gICAgICAgID8gMC4xXG4gICAgICAgIDogMTtcbiAgICAgIHRoaXMubWluID0gdGhpcy5zY29wZWRTY2hlbWEubWluaW11bTtcbiAgICAgIHRoaXMubWF4ID0gdGhpcy5zY29wZWRTY2hlbWEubWF4aW11bTtcbiAgICAgIHRoaXMubXVsdGlwbGVPZiA9IHRoaXMuc2NvcGVkU2NoZW1hLm11bHRpcGxlT2YgfHwgZGVmYXVsdFN0ZXA7XG4gICAgICBjb25zdCBhcHBsaWVkVWlTY2hlbWFPcHRpb25zID0gbWVyZ2UoXG4gICAgICAgIHt9LFxuICAgICAgICBwcm9wcy5jb25maWcsXG4gICAgICAgIHRoaXMudWlzY2hlbWEub3B0aW9uc1xuICAgICAgKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRMb2NhbGUgPSB0aGlzLmpzb25Gb3Jtc1NlcnZpY2UuZ2V0TG9jYWxlKCk7XG4gICAgICBpZiAodGhpcy5sb2NhbGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLmxvY2FsZSAhPT0gY3VycmVudExvY2FsZSkge1xuICAgICAgICB0aGlzLmxvY2FsZSA9IGN1cnJlbnRMb2NhbGU7XG4gICAgICAgIHRoaXMubnVtYmVyRm9ybWF0ID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KHRoaXMubG9jYWxlLCB7XG4gICAgICAgICAgdXNlR3JvdXBpbmc6IGFwcGxpZWRVaVNjaGVtYU9wdGlvbnMudXNlR3JvdXBpbmcsXG4gICAgICAgICAgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiB0aGlzLk1BWElNVU1fRlJBQ1RJT05BTF9ESUdJVFMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldGVybWluZURlY2ltYWxTZXBhcmF0b3IoKTtcbiAgICAgICAgdGhpcy5vbGRWYWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZm9ybS5zZXRWYWx1ZSh0aGlzLmdldFZhbHVlKCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGV0ZXJtaW5lRGVjaW1hbFNlcGFyYXRvcigpOiB2b2lkIHtcbiAgICBjb25zdCBleGFtcGxlID0gdGhpcy5udW1iZXJGb3JtYXQuZm9ybWF0KDEuMSk7XG4gICAgdGhpcy5kZWNpbWFsU2VwYXJhdG9yID0gZXhhbXBsZS5jaGFyQXQoMSk7XG4gIH1cbn1cbmV4cG9ydCBjb25zdCBOdW1iZXJDb250cm9sUmVuZGVyZXJUZXN0ZXI6IFJhbmtlZFRlc3RlciA9IHJhbmtXaXRoKFxuICAyLFxuICBvcihpc051bWJlckNvbnRyb2wsIGlzSW50ZWdlckNvbnRyb2wpXG4pO1xuIl19