truly-ui
Version:
Web Components for Desktop Applications.
176 lines (174 loc) • 28.7 kB
JavaScript
/*
MIT License
Copyright (c) 2019 Temainfo Software
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 { Component, ContentChild, EventEmitter, forwardRef, Input, Output, ViewChild } from '@angular/core';
import { FormControlName, NG_VALUE_ACCESSOR, NgModel } from '@angular/forms';
import { CdkOverlayOrigin } from '@angular/cdk/overlay';
import { ValueAccessorBase } from '../input/core/value-accessor';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "../icons/icons";
import * as i4 from "../internals/components/label/label";
export class TlTextarea extends ValueAccessorBase {
constructor(change) {
super();
this.change = change;
this.label = '';
this.labelPlacement = 'left';
this.labelSize = '100px';
this.name = '';
this.placeholder = '';
this.height = '80px';
this.tabindex = 0;
this.maxlength = -1;
this.textAlign = 'left';
this.readonly = null;
this.disabled = null;
this.clearButton = false;
this.color = 'basic';
this.withBorder = true;
this.resize = false;
this.showCount = false;
this.click = new EventEmitter();
this.focus = new EventEmitter();
this.blur = new EventEmitter();
this.clear = new EventEmitter();
this.overlayOrigin = new EventEmitter();
this.required = false;
this.isShowingMessages = false;
}
ngOnInit() {
this.overlayOrigin.emit(this.cdkOverlayOrigin);
}
ngAfterViewInit() {
this.setRequired();
this.handleValidator();
}
setRequired() {
const currentControl = this.controlName ? this.controlName : this.model;
if (currentControl && currentControl.control.errors) {
if (currentControl.control.errors['required']) {
this.required = true;
this.change.detectChanges();
}
}
}
handleValidator() {
const currentControl = this.controlName ? this.controlName : this.model;
if (currentControl) {
this.hasValidator = currentControl.control.validator;
this.change.detectChanges();
}
}
setFocus() {
this.textarea.nativeElement.focus();
}
stopEvent($event) {
$event.preventDefault();
$event.stopPropagation();
}
onTextareaClick($event) {
this.stopEvent($event);
this.isShowingMessages = true;
this.click.emit($event);
}
onTextareaFocus($event) {
this.isShowingMessages = true;
this.focus.emit($event);
}
onTextareaBlur($event) {
this.isShowingMessages = false;
this.blur.emit($event);
}
clearTextarea($event) {
this.value = '';
this.setFocus();
this.clear.emit($event);
}
}
/** @nocollapse */ TlTextarea.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlTextarea, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ TlTextarea.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TlTextarea, selector: "tl-textarea", inputs: { label: "label", labelPlacement: "labelPlacement", labelSize: "labelSize", name: "name", placeholder: "placeholder", height: "height", tabindex: "tabindex", maxlength: "maxlength", textAlign: "textAlign", readonly: "readonly", disabled: "disabled", clearButton: "clearButton", color: "color", withBorder: "withBorder", resize: "resize", showCount: "showCount" }, outputs: { click: "click", focus: "focus", blur: "blur", clear: "clear", overlayOrigin: "overlayOrigin" }, providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => TlTextarea)),
multi: true
}], queries: [{ propertyName: "model", first: true, predicate: NgModel, descendants: true, static: true }, { propertyName: "controlName", first: true, predicate: FormControlName, descendants: true, static: true }], viewQueries: [{ propertyName: "textarea", first: true, predicate: ["textarea"], descendants: true, static: true }, { propertyName: "cdkOverlayOrigin", first: true, predicate: CdkOverlayOrigin, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div [class]=\"'tl-textarea ' + color\">\n\n <tl-label *ngIf=\"label\"\n [style.vertical-align]=\"'top'\"\n [labelTitle]=\"label\"\n [required]=\"required\"\n [labelPlacement]=\"labelPlacement\"\n [labelSize]=\"labelSize\"></tl-label>\n\n <div class=\"ui-wrapper-textarea\" [style.height]=\"height\">\n <textarea #textarea\n class=\"field\"\n [ngClass]=\"{\n 'invalid': controlName?.control?.errors || model?.control?.errors,\n 'withValidators': hasValidator,\n 'withoutValidators': !hasValidator,\n 'withBorder': withBorder,\n 'withoutBorder': !withBorder\n }\"\n [style.resize]=\"resize ? 'auto' : 'none'\"\n [style.height]=\"height\"\n [style.text-align]=\"textAlign\"\n [tabindex]=\"tabindex\"\n [disabled]=\"disabled || isDisabled\"\n [attr.name]=\"name\"\n [placeholder]=\"placeholder\"\n [attr.readonly]=\"readonly ? true : null\"\n [attr.maxlength]=\"maxlength\"\n [(ngModel)]=\"value\"\n (click)=\"onTextareaClick($event)\"\n (blur)=\"onTextareaBlur($event)\"\n (focus)=\"onTextareaFocus($event)\"></textarea>\n <tl-icon *ngIf=\"clearButton && value\"\n [style.lineHeight]=\"height\"\n (click)=\"clearTextarea($event)\"\n [lib]=\"'ion'\"\n [style]=\"'ios'\"\n class=\"clearButton\">close</tl-icon>\n <div class=\"count-characters\" *ngIf=\"showCount\">\n {{ ( maxlength > 0 ) ? textarea.value.length + '/' + maxlength : textarea.value.length | number }}\n </div>\n </div>\n</div>\n", styles: ["*{box-sizing:border-box}.tl-textarea{width:100%;height:100%;position:relative;display:table;border-collapse:separate}.tl-textarea>.ui-wrapper-textarea{position:relative}.tl-textarea>.ui-wrapper-textarea>textarea::-webkit-scrollbar{width:8px}.tl-textarea>.ui-wrapper-textarea>.field{display:table-cell;height:23px;padding:4px 20px 4px 6px;font-size:1em;width:100%;font-weight:400;font-family:Segoe UI,Lato,\"sans-serif\",Arial;border-radius:3px;transition:background-color .23s ease-in-out}.tl-textarea>.ui-wrapper-textarea>.count-characters{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-size:.7em;position:absolute;right:0;margin:-22px 2px 0 0;padding:0 10px;border-bottom-left-radius:3px}.tl-textarea>.ui-wrapper-textarea>.field::placeholder{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-size:1em}.tl-textarea>.ui-wrapper-textarea>.field.-cursorblocked{cursor:not-allowed}.tl-textarea>.ui-wrapper-textarea>.field.-disabled{cursor:default!important}.tl-textarea>.ui-wrapper-textarea>.clearButton{position:absolute;top:0;right:0;line-height:40px;font-size:16px;padding-right:15px}.tl-textarea>.ui-wrapper-textarea>.clearButton:hover{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.TlIcons, selector: "tl-icon", inputs: ["icon", "lib", "style", "size", "animation", "color", "align"] }, { kind: "component", type: i4.TlLabel, selector: "tl-label", inputs: ["labelPlacement", "required", "labelSize", "labelTitle"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlTextarea, decorators: [{
type: Component,
args: [{ selector: 'tl-textarea', providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => TlTextarea)),
multi: true
}], template: "<div [class]=\"'tl-textarea ' + color\">\n\n <tl-label *ngIf=\"label\"\n [style.vertical-align]=\"'top'\"\n [labelTitle]=\"label\"\n [required]=\"required\"\n [labelPlacement]=\"labelPlacement\"\n [labelSize]=\"labelSize\"></tl-label>\n\n <div class=\"ui-wrapper-textarea\" [style.height]=\"height\">\n <textarea #textarea\n class=\"field\"\n [ngClass]=\"{\n 'invalid': controlName?.control?.errors || model?.control?.errors,\n 'withValidators': hasValidator,\n 'withoutValidators': !hasValidator,\n 'withBorder': withBorder,\n 'withoutBorder': !withBorder\n }\"\n [style.resize]=\"resize ? 'auto' : 'none'\"\n [style.height]=\"height\"\n [style.text-align]=\"textAlign\"\n [tabindex]=\"tabindex\"\n [disabled]=\"disabled || isDisabled\"\n [attr.name]=\"name\"\n [placeholder]=\"placeholder\"\n [attr.readonly]=\"readonly ? true : null\"\n [attr.maxlength]=\"maxlength\"\n [(ngModel)]=\"value\"\n (click)=\"onTextareaClick($event)\"\n (blur)=\"onTextareaBlur($event)\"\n (focus)=\"onTextareaFocus($event)\"></textarea>\n <tl-icon *ngIf=\"clearButton && value\"\n [style.lineHeight]=\"height\"\n (click)=\"clearTextarea($event)\"\n [lib]=\"'ion'\"\n [style]=\"'ios'\"\n class=\"clearButton\">close</tl-icon>\n <div class=\"count-characters\" *ngIf=\"showCount\">\n {{ ( maxlength > 0 ) ? textarea.value.length + '/' + maxlength : textarea.value.length | number }}\n </div>\n </div>\n</div>\n", styles: ["*{box-sizing:border-box}.tl-textarea{width:100%;height:100%;position:relative;display:table;border-collapse:separate}.tl-textarea>.ui-wrapper-textarea{position:relative}.tl-textarea>.ui-wrapper-textarea>textarea::-webkit-scrollbar{width:8px}.tl-textarea>.ui-wrapper-textarea>.field{display:table-cell;height:23px;padding:4px 20px 4px 6px;font-size:1em;width:100%;font-weight:400;font-family:Segoe UI,Lato,\"sans-serif\",Arial;border-radius:3px;transition:background-color .23s ease-in-out}.tl-textarea>.ui-wrapper-textarea>.count-characters{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-size:.7em;position:absolute;right:0;margin:-22px 2px 0 0;padding:0 10px;border-bottom-left-radius:3px}.tl-textarea>.ui-wrapper-textarea>.field::placeholder{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-size:1em}.tl-textarea>.ui-wrapper-textarea>.field.-cursorblocked{cursor:not-allowed}.tl-textarea>.ui-wrapper-textarea>.field.-disabled{cursor:default!important}.tl-textarea>.ui-wrapper-textarea>.clearButton{position:absolute;top:0;right:0;line-height:40px;font-size:16px;padding-right:15px}.tl-textarea>.ui-wrapper-textarea>.clearButton:hover{cursor:pointer}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { label: [{
type: Input
}], labelPlacement: [{
type: Input
}], labelSize: [{
type: Input
}], name: [{
type: Input
}], placeholder: [{
type: Input
}], height: [{
type: Input
}], tabindex: [{
type: Input
}], maxlength: [{
type: Input
}], textAlign: [{
type: Input
}], readonly: [{
type: Input
}], disabled: [{
type: Input
}], clearButton: [{
type: Input
}], color: [{
type: Input
}], withBorder: [{
type: Input
}], resize: [{
type: Input
}], showCount: [{
type: Input
}], textarea: [{
type: ViewChild,
args: ['textarea', { static: true }]
}], cdkOverlayOrigin: [{
type: ViewChild,
args: [CdkOverlayOrigin, { static: true }]
}], model: [{
type: ContentChild,
args: [NgModel, { static: true }]
}], controlName: [{
type: ContentChild,
args: [FormControlName, { static: true }]
}], click: [{
type: Output
}], focus: [{
type: Output
}], blur: [{
type: Output
}], clear: [{
type: Output
}], overlayOrigin: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dGFyZWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy90cnVseS11aS9zcmMvY29tcG9uZW50cy90ZXh0YXJlYS90ZXh0YXJlYS50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL3RleHRhcmVhL3RleHRhcmVhLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBb0JFO0FBRUYsT0FBTyxFQUdMLFNBQVMsRUFDVCxZQUFZLEVBQ1osWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7QUFhakUsTUFBTSxPQUFPLFVBQVcsU0FBUSxpQkFBeUI7SUEwRHZELFlBQXFCLE1BQXlCO1FBQzVDLEtBQUssRUFBRSxDQUFDO1FBRFcsV0FBTSxHQUFOLE1BQU0sQ0FBbUI7UUF4RHJDLFVBQUssR0FBRyxFQUFFLENBQUM7UUFFWCxtQkFBYyxHQUFHLE1BQU0sQ0FBQztRQUV4QixjQUFTLEdBQUcsT0FBTyxDQUFDO1FBRXBCLFNBQUksR0FBRyxFQUFFLENBQUM7UUFFVixnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUVqQixXQUFNLEdBQUcsTUFBTSxDQUFDO1FBRWhCLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFFYixjQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFZixjQUFTLEdBQTRDLE1BQU0sQ0FBQztRQUU1RCxhQUFRLEdBQUcsSUFBSSxDQUFDO1FBRWhCLGFBQVEsR0FBRyxJQUFJLENB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QUFDLE1BQU0sRUFBRSxJQUFJLEVBQUM7Z0JBRVcsV0FBVztzQkFBM0QsWUFBWTt1QkFBRSxlQUFlLEVBQUUsRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFDO2dCQUVwQyxLQUFLO3NCQUFkLE1BQU07Z0JBRUcsS0FBSztzQkFBZCxNQUFNO2dCQUVHLElBQUk7c0JBQWIsTUFBTTtnQkFFRyxLQUFLO3NCQUFkLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gICAgTUlUIExpY2Vuc2VcblxuICAgIENvcHlyaWdodCAoYykgMjAxOSBUZW1haW5mbyBTb2Z0d2FyZVxuXG4gICAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICAgIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAgICBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gICAgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICAgIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICAgIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gICAgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gICAgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gICAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gICAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gICAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbiAgICBTT0ZUV0FSRS5cbiovXG5cbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sTmFtZSwgTkdfVkFMVUVfQUNDRVNTT1IsIE5nTW9kZWwgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBDZGtPdmVybGF5T3JpZ2luIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHsgVmFsdWVBY2Nlc3NvckJhc2UgfSBmcm9tICcuLi9pbnB1dC9jb3JlL3ZhbHVlLWFjY2Vzc29yJztcbmltcG9ydCB7Rml4ZWRQb3NpdGlvbkRpcmVjdGl2ZX0gZnJvbSAnLi4vbWlzYy9maXhlZC1wb3NpdGlvbi5kaXJlY3RpdmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0bC10ZXh0YXJlYScsXG4gIHRlbXBsYXRlVXJsOiAnLi90ZXh0YXJlYS5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGV4dGFyZWEuc2NzcyddLFxuICBwcm92aWRlcnM6IFsge1xuICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFRsVGV4dGFyZWEpLFxuICAgIG11bHRpOiB0cnVlXG4gIH0gXSxcbn0pXG5leHBvcnQgY2xhc3MgVGxUZXh0YXJlYSBleHRlbmRzIFZhbHVlQWNjZXNzb3JCYXNlPHN0cmluZz4gaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQge1xuXG4gIEBJbnB1dCgpIGxhYmVsID0gJyc7XG5cbiAgQElucHV0KCkgbGFiZWxQbGFjZW1lbnQgPSAnbGVmdCc7XG5cbiAgQElucHV0KCkgbGFiZWxTaXplID0gJzEwMHB4JztcblxuICBASW5wdXQoKSBuYW1lID0gJyc7XG5cbiAgQElucHV0KCkgcGxhY2Vob2xkZXIgPSAnJztcblxuICBASW5wdXQoKSBoZWlnaHQgPSAnODBweCc7XG5cbiAgQElucHV0KCkgdGFiaW5kZXggPSAwO1xuXG4gIEBJbnB1dCgpIG1heGxlbmd0aCA9IC0xO1xuXG4gIEBJbnB1dCgpIHRleHRBbGlnbjogJ2xlZnQnIHwgJ3JpZ2h0JyB8ICdjZW50ZXInIHwgJ2p1c3RpZnknID0gJ2xlZnQnO1xuXG4gIEBJbnB1dCgpIHJlYWRvbmx5ID0gbnVsbDtcblxuICBASW5wdXQoKSBkaXNhYmxlZCA9IG51bGw7XG5cbiAgQElucHV0KCkgY2xlYXJCdXR0b24gPSBmYWxzZTtcblxuICBASW5wdXQoKSBjb2xvciA9ICdiYXNpYyc7XG5cbiAgQElucHV0KCkgd2l0aEJvcmRlciA9IHRydWU7XG5cbiAgQElucHV0KCkgcmVzaXplID0gZmFsc2U7XG5cbiAgQElucHV0KCkgc2hvd0NvdW50ID0gZmFsc2U7XG5cbiAgQFZpZXdDaGlsZCggJ3RleHRhcmVhJywge3N0YXRpYzogdHJ1ZX0gKSB0ZXh0YXJlYTtcblxuICBAVmlld0NoaWxkKCBDZGtPdmVybGF5T3JpZ2luLCB7c3RhdGljOiB0cnVlfSApIGNka092ZXJsYXlPcmlnaW46IENka092ZXJsYXlPcmlnaW47XG5cbiAgQENvbnRlbnRDaGlsZCggTmdNb2RlbCwge3N0YXRpYzogdHJ1ZX0gKSBtb2RlbDogTmdNb2RlbDtcblxuICBAQ29udGVudENoaWxkKCBGb3JtQ29udHJvbE5hbWUsIHtzdGF0aWM6IHRydWV9ICkgY29udHJvbE5hbWU6IEZvcm1Db250cm9sTmFtZTtcblxuICBAT3V0cHV0KCkgY2xpY2s6IEV2ZW50RW1pdHRlcjxNb3VzZUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAT3V0cHV0KCkgZm9jdXM6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBPdXRwdXQoKSBibHVyOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAT3V0cHV0KCkgY2xlYXI6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBPdXRwdXQoKSBvdmVybGF5T3JpZ2luOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBwdWJsaWMgcmVxdWlyZWQgPSBmYWxzZTtcblxuICBwdWJsaWMgaXNTaG93aW5nTWVzc2FnZXMgPSBmYWxzZTtcblxuICBwdWJsaWMgaGFzVmFsaWRhdG9yO1xuXG4gIGNvbnN0cnVjdG9yKCBwcml2YXRlIGNoYW5nZTogQ2hhbmdlRGV0ZWN0b3JSZWYgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMub3ZlcmxheU9yaWdpbi5lbWl0KCB0aGlzLmNka092ZXJsYXlPcmlnaW4gKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLnNldFJlcXVpcmVkKCk7XG4gICAgdGhpcy5oYW5kbGVWYWxpZGF0b3IoKTtcbiAgfVxuXG4gIHNldFJlcXVpcmVkKCkge1xuICAgIGNvbnN0IGN1cnJlbnRDb250cm9sID0gdGhpcy5jb250cm9sTmFtZSA/IHRoaXMuY29udHJvbE5hbWUgOiB0aGlzLm1vZGVsO1xuICAgIGlmICggY3VycmVudENvbnRyb2wgJiYgY3VycmVudENvbnRyb2wuY29udHJvbC5lcnJvcnMpIHtcbiAgICAgIGlmICggY3VycmVudENvbnRyb2wuY29udHJvbC5lcnJvcnNbICdyZXF1aXJlZCcgXSApIHtcbiAgICAgICAgdGhpcy5yZXF1aXJlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuY2hhbmdlLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVWYWxpZGF0b3IoKSB7XG4gICAgY29uc3QgY3VycmVudENvbnRyb2wgPSB0aGlzLmNvbnRyb2xOYW1lID8gdGhpcy5jb250cm9sTmFtZSA6IHRoaXMubW9kZWw7XG4gICAgaWYgKCBjdXJyZW50Q29udHJvbCApIHtcbiAgICAgIHRoaXMuaGFzVmFsaWRhdG9yID0gY3VycmVudENvbnRyb2wuY29udHJvbC52YWxpZGF0b3I7XG4gICAgICB0aGlzLmNoYW5nZS5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgc2V0Rm9jdXMoKSB7XG4gICAgdGhpcy50ZXh0YXJlYS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICBzdG9wRXZlbnQoICRldmVudCApIHtcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBvblRleHRhcmVhQ2xpY2soICRldmVudDogTW91c2VFdmVudCApIHtcbiAgICB0aGlzLnN0b3BFdmVudCgkZXZlbnQpO1xuICAgIHRoaXMuaXNTaG93aW5nTWVzc2FnZXMgPSB0cnVlO1xuICAgIHRoaXMuY2xpY2suZW1pdCggJGV2ZW50ICk7XG4gIH1cblxuICBvblRleHRhcmVhRm9jdXMoICRldmVudCApIHtcbiAgICB0aGlzLmlzU2hvd2luZ01lc3NhZ2VzID0gdHJ1ZTtcbiAgICB0aGlzLmZvY3VzLmVtaXQoICRldmVudCApO1xuICB9XG5cbiAgb25UZXh0YXJlYUJsdXIoICRldmVudCApIHtcbiAgICB0aGlzLmlzU2hvd2luZ01lc3NhZ2VzID0gZmFsc2U7XG4gICAgdGhpcy5ibHVyLmVtaXQoICRldmVudCApO1xuICB9XG5cbiAgY2xlYXJUZXh0YXJlYSggJGV2ZW50PyApIHtcbiAgICB0aGlzLnZhbHVlID0gJyc7XG4gICAgdGhpcy5zZXRGb2N1cygpO1xuICAgIHRoaXMuY2xlYXIuZW1pdCggJGV2ZW50ICk7XG4gIH1cblxufVxuIiwiPGRpdiBbY2xhc3NdPVwiJ3RsLXRleHRhcmVhICcgKyBjb2xvclwiPlxuXG4gIDx0bC1sYWJlbCAqbmdJZj1cImxhYmVsXCJcbiAgICAgICAgICAgIFtzdHlsZS52ZXJ0aWNhbC1hbGlnbl09XCIndG9wJ1wiXG4gICAgICAgICAgICBbbGFiZWxUaXRsZV09XCJsYWJlbFwiXG4gICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgICAgW2xhYmVsUGxhY2VtZW50XT1cImxhYmVsUGxhY2VtZW50XCJcbiAgICAgICAgICAgIFtsYWJlbFNpemVdPVwibGFiZWxTaXplXCI+PC90bC1sYWJlbD5cblxuICA8ZGl2IGNsYXNzPVwidWktd3JhcHBlci10ZXh0YXJlYVwiIFtzdHlsZS5oZWlnaHRdPVwiaGVpZ2h0XCI+XG4gICAgPHRleHRhcmVhICN0ZXh0YXJlYVxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkXCJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICAnaW52YWxpZCc6IGNvbnRyb2xOYW1lPy5jb250cm9sPy5lcnJvcnMgfHwgbW9kZWw/LmNvbnRyb2w/LmVycm9ycyxcbiAgICAgICAgICAgICAgICAgJ3dpdGhWYWxpZGF0b3JzJzogaGFzVmFsaWRhdG9yLFxuICAgICAgICAgICAgICAgICAnd2l0aG91dFZhbGlkYXRvcnMnOiAhaGFzVmFsaWRhdG9yLFxuICAgICAgICAgICAgICAgICAnd2l0aEJvcmRlcic6IHdpdGhCb3JkZXIsXG4gICAgICAgICAgICAgICAgICd3aXRob3V0Qm9yZGVyJzogIXdpdGhCb3JkZXJcbiAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICBbc3R5bGUucmVzaXplXT1cInJlc2l6ZSA/ICdhdXRvJyA6ICdub25lJ1wiXG4gICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHRdPVwiaGVpZ2h0XCJcbiAgICAgICAgICAgICAgW3N0eWxlLnRleHQtYWxpZ25dPVwidGV4dEFsaWduXCJcbiAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkIHx8IGlzRGlzYWJsZWRcIlxuICAgICAgICAgICAgICBbYXR0ci5uYW1lXT1cIm5hbWVcIlxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICBbYXR0ci5yZWFkb25seV09XCJyZWFkb25seSA/IHRydWUgOiBudWxsXCJcbiAgICAgICAgICAgICAgW2F0dHIubWF4bGVuZ3RoXT1cIm1heGxlbmd0aFwiXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidmFsdWVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwib25UZXh0YXJlYUNsaWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAoYmx1cik9XCJvblRleHRhcmVhQmx1cigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGZvY3VzKT1cIm9uVGV4dGFyZWFGb2N1cygkZXZlbnQpXCI+PC90ZXh0YXJlYT5cbiAgICA8dGwtaWNvbiAqbmdJZj1cImNsZWFyQnV0dG9uICYmIHZhbHVlXCJcbiAgICAgICAgICAgICBbc3R5bGUubGluZUhlaWdodF09XCJoZWlnaHRcIlxuICAgICAgICAgICAgIChjbGljayk9XCJjbGVhclRleHRhcmVhKCRldmVudClcIlxuICAgICAgICAgICAgIFtsaWJdPVwiJ2lvbidcIlxuICAgICAgICAgICAgIFtzdHlsZV09XCInaW9zJ1wiXG4gICAgICAgICAgICAgY2xhc3M9XCJjbGVhckJ1dHRvblwiPmNsb3NlPC90bC1pY29uPlxuICAgIDxkaXYgY2xhc3M9XCJjb3VudC1jaGFyYWN0ZXJzXCIgKm5nSWY9XCJzaG93Q291bnRcIj5cbiAgICAgIHt7ICggbWF4bGVuZ3RoID4gMCApID8gdGV4dGFyZWEudmFsdWUubGVuZ3RoICsgJy8nICsgbWF4bGVuZ3RoIDogdGV4dGFyZWEudmFsdWUubGVuZ3RoIHwgbnVtYmVyIH19XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=