UNPKG

@nakedobjects/gemini

Version:

Single Page Application client for a Naked Objects application.

148 lines 46.3 kB
import { Component, HostListener, Input, ViewChildren } from '@angular/core'; import * as Ro from '@nakedobjects/restful-objects'; import { FieldComponent } from '../field/field.component'; import * as i0 from "@angular/core"; import * as i1 from "@nakedobjects/services"; import * as i2 from "@nakedobjects/view-models"; import * as i3 from "@angular/common"; import * as i4 from "@angular/forms"; import * as i5 from "@angular/cdk/drag-drop"; import * as i6 from "../clear.directive"; import * as i7 from "../attachment-property/attachment-property.component"; import * as i8 from "../date-picker-facade/date-picker-facade.component"; import * as i9 from "../auto-complete/auto-complete.component"; import * as i10 from "../time-picker-facade/time-picker-facade.component"; export class EditPropertyComponent extends FieldComponent { constructor(loggerService, renderer, dragAndDrop) { super(loggerService, renderer, dragAndDrop); } prop; focusList; checkboxList; parent; set property(value) { this.prop = value; if (this.propertyEntryType === Ro.EntryType.FreeForm) { this.dragAndDrop.setDropZoneId(this.propertyPaneId); } } get property() { return this.prop; } get propertyPaneId() { return this.property.paneArgId; } get propertyId() { return this.property.id; } get propertyChoices() { return this.property.choices; } get title() { return this.property.title; } get propertyType() { return this.property.type; } get propertyReturnType() { return this.property.returnType; } get propertyEntryType() { return this.property.entryType; } get isEditable() { return this.property.isEditable; } get formattedValue() { return this.property.formattedValue; } get value() { return this.property.formattedValue; } get format() { return this.property.format; } get isBlob() { return this.property.format === 'blob'; } get isMultiline() { return !(this.property.multipleLines === 1); } get isPassword() { return this.property.password; } get multilineHeight() { return `${this.property.multipleLines * 20}px`; } get rows() { return this.property.multipleLines; } get propertyDescription() { return this.property.description; } get message() { return this.property.getMessage(); } get attachment() { return this.property.attachment; } choiceName(choice) { return choice.name; } classes() { return { [this.prop.color]: true, 'candrop': this.canDrop, 'dnd-drag-over': this.dragOver, }; } set form(fm) { this.formGroup = fm; } get form() { return this.formGroup; } ngOnInit() { super.init(this.parent, this.property, this.form.controls[this.prop.id]); } onKeydown(event) { this.handleKeyEvents(event, this.isMultiline); } onKeypress(event) { this.handleKeyEvents(event, this.isMultiline); } ngAfterViewInit() { this.populateBoolean(); } ngOnDestroy() { this.dragAndDrop.clearDropZoneId(this.propertyPaneId); super.ngOnDestroy(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: EditPropertyComponent, deps: [{ token: i1.LoggerService }, { token: i0.Renderer2 }, { token: i2.DragAndDropService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: EditPropertyComponent, selector: "nof-edit-property", inputs: { parent: "parent", property: "property", form: "form" }, host: { listeners: { "keydown": "onKeydown($event)", "keypress": "onKeypress($event)" } }, viewQueries: [{ propertyName: "focusList", predicate: ["focus"], descendants: true }, { propertyName: "checkboxList", predicate: ["checkbox"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div [formGroup]=\"form\">\n <div class=\"name\">{{title}}:</div>\n <div class=\"field\">\n <ng-container *ngIf=\"propertyType === 'ref'\">\n\n <div *ngIf=\"!isEditable\" class=\"value\" [ngClass]=\"classes()\">\n {{formattedValue}}\n </div>\n\n <div *ngIf=\"isEditable\" class=\"input-control text\" [ngSwitch]=\"propertyEntryType\">\n <!--\"EntryType.AutoComplete\"-->\n <ng-container *ngSwitchCase=\"5\">\n <nof-auto-complete #focus [form]=\"form\" [model]=\"property\"></nof-auto-complete>\n </ng-container>\n\n <!--\"EntryType.ConditionalChoices\"-->\n <ng-container *ngSwitchCase=\"3\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.Choices\"-->\n <ng-container *ngSwitchCase=\"1\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.FreeForm\"-->\n <ng-container *ngSwitchCase=\"0\">\n <input\n #focus\n [id]=\"propertyPaneId\"\n class=\"value droppable\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n (cdkDropListExited)=\"exit()\"\n (cdkDropListEntered)=\"enter()\"\n [cdkDropListEnterPredicate]=\"accept\"\n [ngClass]=\"classes()\"\n placeholder=\"{{propertyDescription}}\"\n type=\"text\"\n [formControlName]=\"propertyId\"\n [nofClear]=\"subject\"\n (clear)=\"clear()\"/>\n </ng-container>\n\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"propertyType === 'scalar'\">\n\n <ng-container *ngIf=\"!isEditable\">\n <ng-container [ngSwitch]=\"propertyReturnType\">\n <ng-container *ngSwitchCase=\"'string'\">\n <nof-attachment-property *ngIf=\"isBlob\" [attachment]=\"attachment\"></nof-attachment-property>\n <ng-container *ngIf=\"!isBlob\">\n <div *ngIf=\"!isMultiline\" class=\"value\">\n {{formattedValue}}\n </div>\n <div *ngIf=\"isMultiline\" class=\"value multiline\" [ngStyle]=\"{height : multilineHeight}\">\n <pre>{{formattedValue}}</pre>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input type=\"checkbox\" [checked]=\"value\" disabled=\"disabled\" />\n </ng-container>\n\n <ng-container *ngSwitchDefault>\n <div class=\"value\">\n {{formattedValue}}\n </div>\n </ng-container>\n\n </ng-container>\n </ng-container>\n\n <div *ngIf=\"isEditable\" class=\"input-control text\">\n <ng-container [ngSwitch]=\"propertyEntryType\">\n <!--\"EntryType.AutoComplete\"-->\n <ng-container *ngSwitchCase=\"5\">\n <nof-auto-complete #focus [form]=\"form\" [model]=\"property\"></nof-auto-complete>\n </ng-container>\n\n <!--\"EntryType.ConditionalChoices\"-->\n <ng-container *ngSwitchCase=\"3\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.Choices\"-->\n <ng-container *ngSwitchCase=\"1\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.FreeForm\"-->\n <ng-container *ngSwitchCase=\"0\">\n <ng-container [ngSwitch]=\"propertyReturnType\">\n <ng-container *ngSwitchCase=\"'string'\" [ngSwitch]=\"format\">\n <ng-container *ngSwitchCase=\"'date'\">\n <nof-date-picker-facade #focus [control]=\"control\" [form]=\"form\" [model]=\"property\"></nof-date-picker-facade>\n </ng-container>\n <ng-container *ngSwitchCase=\"'time'\">\n <nof-time-picker-facade #focus [control]=\"control\" [form]=\"form\" [model]=\"property\"></nof-time-picker-facade>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <input #focus *ngIf=\"!isMultiline\" [id]=\"propertyPaneId\" placeholder=\"{{propertyDescription}}\" type=\"{{isPassword ? 'password' : 'text'}}\"\n [formControlName]=\"propertyId\" [nofClear]=\"subject\" (clear)=\"clear()\" />\n <textarea #focus *ngIf=\"isMultiline\" rows=\"{{rows}}\" [id]=\"propertyPaneId\" [formControlName]=\"propertyId\"\n placeholder=\"{{propertyDescription}}\"></textarea>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input #focus #checkbox [id]=\"propertyPaneId\" type=\"checkbox\" [formControlName]=\"propertyId\"/>{{propertyDescription}}\n </ng-container>\n <ng-container *ngSwitchDefault>\n <input #focus [id]=\"propertyPaneId\" type=\"text\" placeholder=\"{{propertyDescription}}\" [formControlName]=\"propertyId\"\n [nofClear]=\"subject\" (clear)=\"clear()\" />\n </ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"validation\">{{message}}</div>\n </div>\n</div>", styles: [":host{overflow:hidden;display:block}.name{display:block;float:left;width:var(--field-name-width);padding-right:var(--space-3);font-weight:var(--font-weight-2)er}.field{display:block;float:left;width:var(--field-value-width)}.reference,.value,collectionDetails{display:block;float:left;width:var(--field-value-width);padding-left:var(--space-3);padding-right:var(--space-3);margin:var(--space-1)}.reference img{display:block;cursor:pointer;float:left;max-width:var(--field-value-width);max-height:100px}.value.droppable{border:solid;border-width:1px;width:var(--field-value-width);height:var(--field-value-height)}.value.droppable{border-color:#000}.value.droppable.dnd-drag-over.candrop{border-color:var(--approval-color);cursor:pointer}.value.droppable.dnd-drag-over{border-color:var(--warning-color)}.multiline{overflow:auto}.ng-clearable{background-image:var(--clearable-image);background-repeat:no-repeat;background-position:right -10px;background-size:8px}.ng-clearable[class*=link-color]{background-image:var(--clearable-link-image)}.ng-clearable.ng-x{background-position:right 2px center}.ng-clearable.ng-onX{cursor:pointer}input::-ms-clear{display:none}.input-control input.hasDatepicker,.input-control input.ui-timepicker-input{width:217px}img.ui-datepicker-trigger{margin-left:var(--space-3);margin-top:var(--space-1);width:20px}select{width:var(--field-value-width);height:var(--field-value-height)}select[multiple]{height:68px}.validation{color:var(--default-text-color);padding:var(--space-3);font-size:var(--font-size-2)}.input-control input:not([type=checkbox]),textarea{width:var(--field-value-width);padding-left:var(--space-1)}input:not([type=checkbox]){height:var(--field-value-height)}input,select{border-style:none}.suggestions{display:block;color:#000;background-color:#fff;font-size:var(--font-size-1);font-weight:var(--font-weight-2)er;width:var(--field-value-width)}.suggestions ul{display:block;margin:0;padding:var(--space-3)}.suggestions ul:hover{color:#fff;background-color:#000}.suggestions li{list-style-type:none}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.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: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i6.ClearDirective, selector: "[nofClear]", inputs: ["nofClear"], outputs: ["clear"] }, { kind: "component", type: i7.AttachmentPropertyComponent, selector: "nof-attachment-property", inputs: ["attachment"] }, { kind: "component", type: i8.DatePickerFacadeComponent, selector: "nof-date-picker-facade", inputs: ["control", "form", "model"] }, { kind: "component", type: i9.AutoCompleteComponent, selector: "nof-auto-complete", inputs: ["model", "form"] }, { kind: "component", type: i10.TimePickerFacadeComponent, selector: "nof-time-picker-facade", inputs: ["control", "form", "model"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: EditPropertyComponent, decorators: [{ type: Component, args: [{ selector: 'nof-edit-property', template: "<div [formGroup]=\"form\">\n <div class=\"name\">{{title}}:</div>\n <div class=\"field\">\n <ng-container *ngIf=\"propertyType === 'ref'\">\n\n <div *ngIf=\"!isEditable\" class=\"value\" [ngClass]=\"classes()\">\n {{formattedValue}}\n </div>\n\n <div *ngIf=\"isEditable\" class=\"input-control text\" [ngSwitch]=\"propertyEntryType\">\n <!--\"EntryType.AutoComplete\"-->\n <ng-container *ngSwitchCase=\"5\">\n <nof-auto-complete #focus [form]=\"form\" [model]=\"property\"></nof-auto-complete>\n </ng-container>\n\n <!--\"EntryType.ConditionalChoices\"-->\n <ng-container *ngSwitchCase=\"3\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.Choices\"-->\n <ng-container *ngSwitchCase=\"1\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.FreeForm\"-->\n <ng-container *ngSwitchCase=\"0\">\n <input\n #focus\n [id]=\"propertyPaneId\"\n class=\"value droppable\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n (cdkDropListExited)=\"exit()\"\n (cdkDropListEntered)=\"enter()\"\n [cdkDropListEnterPredicate]=\"accept\"\n [ngClass]=\"classes()\"\n placeholder=\"{{propertyDescription}}\"\n type=\"text\"\n [formControlName]=\"propertyId\"\n [nofClear]=\"subject\"\n (clear)=\"clear()\"/>\n </ng-container>\n\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"propertyType === 'scalar'\">\n\n <ng-container *ngIf=\"!isEditable\">\n <ng-container [ngSwitch]=\"propertyReturnType\">\n <ng-container *ngSwitchCase=\"'string'\">\n <nof-attachment-property *ngIf=\"isBlob\" [attachment]=\"attachment\"></nof-attachment-property>\n <ng-container *ngIf=\"!isBlob\">\n <div *ngIf=\"!isMultiline\" class=\"value\">\n {{formattedValue}}\n </div>\n <div *ngIf=\"isMultiline\" class=\"value multiline\" [ngStyle]=\"{height : multilineHeight}\">\n <pre>{{formattedValue}}</pre>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input type=\"checkbox\" [checked]=\"value\" disabled=\"disabled\" />\n </ng-container>\n\n <ng-container *ngSwitchDefault>\n <div class=\"value\">\n {{formattedValue}}\n </div>\n </ng-container>\n\n </ng-container>\n </ng-container>\n\n <div *ngIf=\"isEditable\" class=\"input-control text\">\n <ng-container [ngSwitch]=\"propertyEntryType\">\n <!--\"EntryType.AutoComplete\"-->\n <ng-container *ngSwitchCase=\"5\">\n <nof-auto-complete #focus [form]=\"form\" [model]=\"property\"></nof-auto-complete>\n </ng-container>\n\n <!--\"EntryType.ConditionalChoices\"-->\n <ng-container *ngSwitchCase=\"3\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.Choices\"-->\n <ng-container *ngSwitchCase=\"1\">\n <select #focus [id]=\"propertyPaneId\" [formControlName]=\"propertyId\">\n <option *ngFor=\"let choice of propertyChoices\" [ngValue]=\"choice\">{{choiceName(choice)}}</option>\n </select>\n </ng-container>\n\n <!--\"EntryType.FreeForm\"-->\n <ng-container *ngSwitchCase=\"0\">\n <ng-container [ngSwitch]=\"propertyReturnType\">\n <ng-container *ngSwitchCase=\"'string'\" [ngSwitch]=\"format\">\n <ng-container *ngSwitchCase=\"'date'\">\n <nof-date-picker-facade #focus [control]=\"control\" [form]=\"form\" [model]=\"property\"></nof-date-picker-facade>\n </ng-container>\n <ng-container *ngSwitchCase=\"'time'\">\n <nof-time-picker-facade #focus [control]=\"control\" [form]=\"form\" [model]=\"property\"></nof-time-picker-facade>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <input #focus *ngIf=\"!isMultiline\" [id]=\"propertyPaneId\" placeholder=\"{{propertyDescription}}\" type=\"{{isPassword ? 'password' : 'text'}}\"\n [formControlName]=\"propertyId\" [nofClear]=\"subject\" (clear)=\"clear()\" />\n <textarea #focus *ngIf=\"isMultiline\" rows=\"{{rows}}\" [id]=\"propertyPaneId\" [formControlName]=\"propertyId\"\n placeholder=\"{{propertyDescription}}\"></textarea>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input #focus #checkbox [id]=\"propertyPaneId\" type=\"checkbox\" [formControlName]=\"propertyId\"/>{{propertyDescription}}\n </ng-container>\n <ng-container *ngSwitchDefault>\n <input #focus [id]=\"propertyPaneId\" type=\"text\" placeholder=\"{{propertyDescription}}\" [formControlName]=\"propertyId\"\n [nofClear]=\"subject\" (clear)=\"clear()\" />\n </ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"validation\">{{message}}</div>\n </div>\n</div>", styles: [":host{overflow:hidden;display:block}.name{display:block;float:left;width:var(--field-name-width);padding-right:var(--space-3);font-weight:var(--font-weight-2)er}.field{display:block;float:left;width:var(--field-value-width)}.reference,.value,collectionDetails{display:block;float:left;width:var(--field-value-width);padding-left:var(--space-3);padding-right:var(--space-3);margin:var(--space-1)}.reference img{display:block;cursor:pointer;float:left;max-width:var(--field-value-width);max-height:100px}.value.droppable{border:solid;border-width:1px;width:var(--field-value-width);height:var(--field-value-height)}.value.droppable{border-color:#000}.value.droppable.dnd-drag-over.candrop{border-color:var(--approval-color);cursor:pointer}.value.droppable.dnd-drag-over{border-color:var(--warning-color)}.multiline{overflow:auto}.ng-clearable{background-image:var(--clearable-image);background-repeat:no-repeat;background-position:right -10px;background-size:8px}.ng-clearable[class*=link-color]{background-image:var(--clearable-link-image)}.ng-clearable.ng-x{background-position:right 2px center}.ng-clearable.ng-onX{cursor:pointer}input::-ms-clear{display:none}.input-control input.hasDatepicker,.input-control input.ui-timepicker-input{width:217px}img.ui-datepicker-trigger{margin-left:var(--space-3);margin-top:var(--space-1);width:20px}select{width:var(--field-value-width);height:var(--field-value-height)}select[multiple]{height:68px}.validation{color:var(--default-text-color);padding:var(--space-3);font-size:var(--font-size-2)}.input-control input:not([type=checkbox]),textarea{width:var(--field-value-width);padding-left:var(--space-1)}input:not([type=checkbox]){height:var(--field-value-height)}input,select{border-style:none}.suggestions{display:block;color:#000;background-color:#fff;font-size:var(--font-size-1);font-weight:var(--font-weight-2)er;width:var(--field-value-width)}.suggestions ul{display:block;margin:0;padding:var(--space-3)}.suggestions ul:hover{color:#fff;background-color:#000}.suggestions li{list-style-type:none}\n"] }] }], ctorParameters: () => [{ type: i1.LoggerService }, { type: i0.Renderer2 }, { type: i2.DragAndDropService }], propDecorators: { focusList: [{ type: ViewChildren, args: ['focus'] }], checkboxList: [{ type: ViewChildren, args: ['checkbox'] }], parent: [{ type: Input }], property: [{ type: Input, args: [{ required: true }] }], form: [{ type: Input, args: [{ required: true }] }], onKeydown: [{ type: HostListener, args: ['keydown', ['$event']] }], onKeypress: [{ type: HostListener, args: ['keypress', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdC1wcm9wZXJ0eS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9nZW1pbmkvc3JjL2VkaXQtcHJvcGVydHkvZWRpdC1wcm9wZXJ0eS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9nZW1pbmkvc3JjL2VkaXQtcHJvcGVydHkvZWRpdC1wcm9wZXJ0eS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUgsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBS0wsWUFBWSxFQUNYLE1BQU0sZUFBZSxDQUFDO0FBRTNCLE9BQU8sS0FBSyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFNcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7Ozs7Ozs7Ozs7QUFRMUQsTUFBTSxPQUFPLHFCQUFzQixTQUFRLGNBQWM7SUFFckQsWUFDSSxhQUE0QixFQUM1QixRQUFtQixFQUNuQixXQUErQjtRQUUvQixLQUFLLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRU8sSUFBSSxDQUFxQjtJQUdqQyxTQUFTLENBQXlHO0lBR2xILFlBQVksQ0FBeUI7SUFHckMsTUFBTSxDQUF5QjtJQUUvQixJQUNJLFFBQVEsQ0FBQyxLQUF3QjtRQUNqQyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztRQUNsQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN4RCxDQUFDO0lBQ0wsQ0FBQztJQUVELElBQUksUUFBUTtRQUNSLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNyQixDQUFDO0lBRUQsSUFBSSxjQUFjO1FBQ2QsT0FBTyxJQUFJLENB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UyxDQUFDLEtBQW9CO1FBQzFCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBR0QsVUFBVSxDQUFDLEtBQW9CO1FBQzNCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQsZUFBZTtRQUNYLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRVEsV0FBVztRQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3hCLENBQUM7dUdBdkpRLHFCQUFxQjsyRkFBckIscUJBQXFCLGtaQzNCbEMsMnROQW9JTTs7MkZEekdPLHFCQUFxQjtrQkFMakMsU0FBUzsrQkFDSSxtQkFBbUI7MklBaUI3QixTQUFTO3NCQURSLFlBQVk7dUJBQUMsT0FBTztnQkFJckIsWUFBWTtzQkFEWCxZQUFZO3VCQUFDLFVBQVU7Z0JBSXhCLE1BQU07c0JBREwsS0FBSztnQkFJRixRQUFRO3NCQURYLEtBQUs7dUJBQUMsRUFBQyxRQUFRLEVBQUUsSUFBSSxFQUFDO2dCQXFHbkIsSUFBSTtzQkFEUCxLQUFLO3VCQUFDLEVBQUMsUUFBUSxFQUFFLElBQUksRUFBQztnQkFjdkIsU0FBUztzQkFEUixZQUFZO3VCQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFNbkMsVUFBVTtzQkFEVCxZQUFZO3VCQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQWZ0ZXJWaWV3SW5pdCxcbiAgICBDb21wb25lbnQsXG4gICAgRWxlbWVudFJlZixcbiAgICBIb3N0TGlzdGVuZXIsXG4gICAgSW5wdXQsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBRdWVyeUxpc3QsXG4gICAgUmVuZGVyZXIyLFxuICAgIFZpZXdDaGlsZHJlblxuICAgIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgKiBhcyBSbyBmcm9tICdAbmFrZWRvYmplY3RzL3Jlc3RmdWwtb2JqZWN0cyc7XG5pbXBvcnQgeyBMb2dnZXJTZXJ2aWNlIH0gZnJvbSAnQG5ha2Vkb2JqZWN0cy9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBBdHRhY2htZW50Vmlld01vZGVsLCBDaG9pY2VWaWV3TW9kZWwsIERvbWFpbk9iamVjdFZpZXdNb2RlbCwgRHJhZ0FuZERyb3BTZXJ2aWNlLCBQcm9wZXJ0eVZpZXdNb2RlbCB9IGZyb20gJ0BuYWtlZG9iamVjdHMvdmlldy1tb2RlbHMnO1xuaW1wb3J0IHsgRGljdGlvbmFyeSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBBdXRvQ29tcGxldGVDb21wb25lbnQgfSBmcm9tICcuLi9hdXRvLWNvbXBsZXRlL2F1dG8tY29tcGxldGUuY29tcG9uZW50JztcbmltcG9ydCB7IERhdGVQaWNrZXJGYWNhZGVDb21wb25lbnQgfSBmcm9tICcuLi9kYXRlLXBpY2tlci1mYWNhZGUvZGF0ZS1waWNrZXItZmFjYWRlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBGaWVsZENvbXBvbmVudCB9IGZyb20gJy4uL2ZpZWxkL2ZpZWxkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUaW1lUGlja2VyRmFjYWRlQ29tcG9uZW50IH0gZnJvbSAnLi4vdGltZS1waWNrZXItZmFjYWRlL3RpbWUtcGlja2VyLWZhY2FkZS5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25vZi1lZGl0LXByb3BlcnR5JyxcbiAgICB0ZW1wbGF0ZVVybDogJ2VkaXQtcHJvcGVydHkuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWydlZGl0LXByb3BlcnR5LmNvbXBvbmVudC5jc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBFZGl0UHJvcGVydHlDb21wb25lbnQgZXh0ZW5kcyBGaWVsZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBsb2dnZXJTZXJ2aWNlOiBMb2dnZXJTZXJ2aWNlLFxuICAgICAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgICAgICBkcmFnQW5kRHJvcDogRHJhZ0FuZERyb3BTZXJ2aWNlLFxuICAgICkge1xuICAgICAgICBzdXBlcihsb2dnZXJTZXJ2aWNlLCByZW5kZXJlciwgZHJhZ0FuZERyb3ApO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHJvcCE6IFByb3BlcnR5Vmlld01vZGVsO1xuXG4gICAgQFZpZXdDaGlsZHJlbignZm9jdXMnKVxuICAgIGZvY3VzTGlzdD86IFF1ZXJ5TGlzdDxFbGVtZW50UmVmIHwgRGF0ZVBpY2tlckZhY2FkZUNvbXBvbmVudCB8IFRpbWVQaWNrZXJGYWNhZGVDb21wb25lbnQgfCBBdXRvQ29tcGxldGVDb21wb25lbnQ+O1xuXG4gICAgQFZpZXdDaGlsZHJlbignY2hlY2tib3gnKVxuICAgIGNoZWNrYm94TGlzdD86IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPjtcblxuICAgIEBJbnB1dCgpXG4gICAgcGFyZW50PzogRG9tYWluT2JqZWN0Vmlld01vZGVsO1xuXG4gICAgQElucHV0KHtyZXF1aXJlZDogdHJ1ZX0pXG4gICAgc2V0IHByb3BlcnR5KHZhbHVlOiBQcm9wZXJ0eVZpZXdNb2RlbCkge1xuICAgICAgICB0aGlzLnByb3AgPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMucHJvcGVydHlFbnRyeVR5cGUgPT09IFJvLkVudHJ5VHlwZS5GcmVlRm9ybSkge1xuICAgICAgICAgICAgdGhpcy5kcmFnQW5kRHJvcC5zZXREcm9wWm9uZUlkKHRoaXMucHJvcGVydHlQYW5lSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IHByb3BlcnR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wO1xuICAgIH1cblxuICAgIGdldCBwcm9wZXJ0eVBhbmVJZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHkucGFuZUFyZ0lkO1xuICAgIH1cblxuICAgIGdldCBwcm9wZXJ0eUlkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5pZDtcbiAgICB9XG5cbiAgICBnZXQgcHJvcGVydHlDaG9pY2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5jaG9pY2VzO1xuICAgIH1cblxuICAgIGdldCB0aXRsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHkudGl0bGU7XG4gICAgfVxuXG4gICAgZ2V0IHByb3BlcnR5VHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHkudHlwZTtcbiAgICB9XG5cbiAgICBnZXQgcHJvcGVydHlSZXR1cm5UeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5yZXR1cm5UeXBlO1xuICAgIH1cblxuICAgIGdldCBwcm9wZXJ0eUVudHJ5VHlwZSgpOiBSby5FbnRyeVR5cGUge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5lbnRyeVR5cGU7XG4gICAgfVxuXG4gICAgZ2V0IGlzRWRpdGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5LmlzRWRpdGFibGU7XG4gICAgfVxuXG4gICAgZ2V0IGZvcm1hdHRlZFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5mb3JtYXR0ZWRWYWx1ZTtcbiAgICB9XG5cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5LmZvcm1hdHRlZFZhbHVlO1xuICAgIH1cblxuICAgIGdldCBmb3JtYXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5LmZvcm1hdDtcbiAgICB9XG5cbiAgICBnZXQgaXNCbG9iKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5mb3JtYXQgPT09ICdibG9iJztcbiAgICB9XG5cbiAgICBnZXQgaXNNdWx0aWxpbmUoKSB7XG4gICAgICAgIHJldHVybiAhKHRoaXMucHJvcGVydHkubXVsdGlwbGVMaW5lcyA9PT0gMSk7XG4gICAgfVxuXG4gICAgZ2V0IGlzUGFzc3dvcmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5LnBhc3N3b3JkO1xuICAgIH1cblxuICAgIGdldCBtdWx0aWxpbmVIZWlnaHQoKSB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLnByb3BlcnR5Lm11bHRpcGxlTGluZXMgKiAyMH1weGA7XG4gICAgfVxuXG4gICAgZ2V0IHJvd3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5Lm11bHRpcGxlTGluZXM7XG4gICAgfVxuXG4gICAgZ2V0IHByb3BlcnR5RGVzY3JpcHRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5LmRlc2NyaXB0aW9uO1xuICAgIH1cblxuICAgIG92ZXJyaWRlIGdldCBtZXNzYWdlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5nZXRNZXNzYWdlKCk7XG4gICAgfVxuXG4gICAgZ2V0IGF0dGFjaG1lbnQoKTogQXR0YWNobWVudFZpZXdNb2RlbCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eS5hdHRhY2htZW50O1xuICAgIH1cblxuICAgIGNob2ljZU5hbWUoY2hvaWNlOiBDaG9pY2VWaWV3TW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIGNob2ljZS5uYW1lO1xuICAgIH1cblxuICAgIGNsYXNzZXMoKTogRGljdGlvbmFyeTxib29sZWFuIHwgbnVsbD4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgW3RoaXMucHJvcC5jb2xvcl06IHRydWUsXG4gICAgICAgICAgICAnY2FuZHJvcCc6IHRoaXMuY2FuRHJvcCxcbiAgICAgICAgICAgICdkbmQtZHJhZy1vdmVyJzogdGhpcy5kcmFnT3ZlcixcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBASW5wdXQoe3JlcXVpcmVkOiB0cnVlfSlcbiAgICBzZXQgZm9ybShmbTogRm9ybUdyb3VwKSB7XG4gICAgICAgIHRoaXMuZm9ybUdyb3VwID0gZm07XG4gICAgfVxuXG4gICAgZ2V0IGZvcm0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1Hcm91cDtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgc3VwZXIuaW5pdCh0aGlzLnBhcmVudCwgdGhpcy5wcm9wZXJ0eSwgdGhpcy5mb3JtLmNvbnRyb2xzW3RoaXMucHJvcC5pZF0pO1xuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24nLCBbJyRldmVudCddKVxuICAgIG9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLmhhbmRsZUtleUV2ZW50cyhldmVudCwgdGhpcy5pc011bHRpbGluZSk7XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5cHJlc3MnLCBbJyRldmVudCddKVxuICAgIG9uS2V5cHJlc3MoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVLZXlFdmVudHMoZXZlbnQsIHRoaXMuaXNNdWx0aWxpbmUpO1xuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgdGhpcy5wb3B1bGF0ZUJvb2xlYW4oKTtcbiAgICB9XG5cbiAgICBvdmVycmlkZSBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kcmFnQW5kRHJvcC5jbGVhckRyb3Bab25lSWQodGhpcy5wcm9wZXJ0eVBhbmVJZCk7XG4gICAgICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgfVxufVxuIiwiPGRpdiBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgICA8ZGl2IGNsYXNzPVwibmFtZVwiPnt7dGl0bGV9fTo8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiZmllbGRcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicHJvcGVydHlUeXBlID09PSAncmVmJ1wiPlxuXG4gICAgICAgIDxkaXYgKm5nSWY9XCIhaXNFZGl0YWJsZVwiIGNsYXNzPVwidmFsdWVcIiBbbmdDbGFzc109XCJjbGFzc2VzKClcIj5cbiAgICAgICAgICAgIHt7Zm9ybWF0dGVkVmFsdWV9fVxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNFZGl0YWJsZVwiIGNsYXNzPVwiaW5wdXQtY29udHJvbCB0ZXh0XCIgW25nU3dpdGNoXT1cInByb3BlcnR5RW50cnlUeXBlXCI+XG4gICAgICAgICAgICA8IS0tXCJFbnRyeVR5cGUuQXV0b0NvbXBsZXRlXCItLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIjVcIj5cbiAgICAgICAgICAgICAgICA8bm9mLWF1dG8tY29tcGxldGUgI2ZvY3VzIFtmb3JtXT1cImZvcm1cIiBbbW9kZWxdPVwicHJvcGVydHlcIj48L25vZi1hdXRvLWNvbXBsZXRlPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwhLS1cIkVudHJ5VHlwZS5Db25kaXRpb25hbENob2ljZXNcIi0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiM1wiPlxuICAgICAgICAgICAgICAgIDxzZWxlY3QgI2ZvY3VzIFtpZF09XCJwcm9wZXJ0eVBhbmVJZFwiICBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5SWRcIj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY2hvaWNlIG9mIHByb3BlcnR5Q2hvaWNlc1wiIFtuZ1ZhbHVlXT1cImNob2ljZVwiPnt7Y2hvaWNlTmFtZShjaG9pY2UpfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8IS0tXCJFbnRyeVR5cGUuQ2hvaWNlc1wiLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIxXCI+XG4gICAgICAgICAgICAgICAgPHNlbGVjdCAjZm9jdXMgW2lkXT1cInByb3BlcnR5UGFuZUlkXCIgIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHlJZFwiPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjaG9pY2Ugb2YgcHJvcGVydHlDaG9pY2VzXCIgW25nVmFsdWVdPVwiY2hvaWNlXCI+e3tjaG9pY2VOYW1lKGNob2ljZSl9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwhLS1cIkVudHJ5VHlwZS5GcmVlRm9ybVwiLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIwXCI+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICNmb2N1c1xuICAgICAgICAgICAgICAgICAgICBbaWRdPVwicHJvcGVydHlQYW5lSWRcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInZhbHVlIGRyb3BwYWJsZVwiXG4gICAgICAgICAgICAgICAgICAgIGNka0Ryb3BMaXN0XG4gICAgICAgICAgICAgICAgICAgIChjZGtEcm9wTGlzdERyb3BwZWQpPVwiZHJvcCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgKGNka0Ryb3BMaXN0RXhpdGVkKT1cImV4aXQoKVwiXG4gICAgICAgICAgICAgICAgICAgIChjZGtEcm9wTGlzdEVudGVyZWQpPVwiZW50ZXIoKVwiXG4gICAgICAgICAgICAgICAgICAgIFtjZGtEcm9wTGlzdEVudGVyUHJlZGljYXRlXT1cImFjY2VwdFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImNsYXNzZXMoKVwiXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3twcm9wZXJ0eURlc2NyaXB0aW9ufX1cIlxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHlJZFwiXG4gICAgICAgICAgICAgICAgICAgIFtub2ZDbGVhcl09XCJzdWJqZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgKGNsZWFyKT1cImNsZWFyKClcIi8+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwcm9wZXJ0eVR5cGUgPT09ICdzY2FsYXInXCI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0VkaXRhYmxlXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJwcm9wZXJ0eVJldHVyblR5cGVcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc3RyaW5nJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bm9mLWF0dGFjaG1lbnQtcHJvcGVydHkgKm5nSWY9XCJpc0Jsb2JcIiBbYXR0YWNobWVudF09XCJhdHRhY2htZW50XCI+PC9ub2YtYXR0YWNobWVudC1wcm9wZXJ0eT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0Jsb2JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhaXNNdWx0aWxpbmVcIiBjbGFzcz1cInZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tmb3JtYXR0ZWRWYWx1ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc011bHRpbGluZVwiIGNsYXNzPVwidmFsdWUgbXVsdGlsaW5lXCIgW25nU3R5bGVdPVwie2hlaWdodCA6IG11bHRpbGluZUhlaWdodH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cHJlPnt7Zm9ybWF0dGVkVmFsdWV9fTwvcHJlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiAgW2NoZWNrZWRdPVwidmFsdWVcIiBkaXNhYmxlZD1cImRpc2FibGVkXCIgLz5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7e2Zvcm1hdHRlZFZhbHVlfX1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNFZGl0YWJsZVwiIGNsYXNzPVwiaW5wdXQtY29udHJvbCB0ZXh0XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJwcm9wZXJ0eUVudHJ5VHlwZVwiPlxuICAgICAgICAgICAgICAgIDwhLS1cIkVudHJ5VHlwZS5BdXRvQ29tcGxldGVcIi0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIjVcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5vZi1hdXRvLWNvbXBsZXRlICNmb2N1cyBbZm9ybV09XCJmb3JtXCIgW21vZGVsXT1cInByb3BlcnR5XCI+PC9ub2YtYXV0by1jb21wbGV0ZT5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDwhLS1cIkVudHJ5VHlwZS5Db25kaXRpb25hbENob2ljZXNcIi0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIjNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCAjZm9jdXMgW2lkXT1cInByb3BlcnR5UGFuZUlkXCIgIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHlJZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY2hvaWNlIG9mIHByb3BlcnR5Q2hvaWNlc1wiIFtuZ1ZhbHVlXT1cImNob2ljZVwiPnt7Y2hvaWNlTmFtZShjaG9pY2UpfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8IS0tXCJFbnRyeVR5cGUuQ2hvaWNlc1wiLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiMVwiPlxuICAgICAgICAgICAgICAgICAgICA8c2VsZWN0ICNmb2N1cyBbaWRdPVwicHJvcGVydHlQYW5lSWRcIiAgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eUlkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjaG9pY2Ugb2YgcHJvcGVydHlDaG9pY2VzXCIgW25nVmFsdWVdPVwiY2hvaWNlXCI+e3tjaG9pY2VOYW1lKGNob2ljZSl9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDwhLS1cIkVudHJ5VHlwZS5GcmVlRm9ybVwiLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiMFwiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJwcm9wZXJ0eVJldHVyblR5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzdHJpbmcnXCIgW25nU3dpdGNoXT1cImZvcm1hdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidkYXRlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bm9mLWRhdGUtcGlja2VyLWZhY2FkZSAjZm9jdXMgW2NvbnRyb2xdPVwiY29udHJvbFwiIFtmb3JtXT1cImZvcm1cIiBbbW9kZWxdPVwicHJvcGVydHlcIj48L25vZi1kYXRlLXBpY2tlci1mYWNhZGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3RpbWUnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxub2YtdGltZS1waWNrZXItZmFjYWRlICNmb2N1cyBbY29udHJvbF09XCJjb250cm9sXCIgW2Zvcm1dPVwiZm9ybVwiIFttb2RlbF09XCJwcm9wZXJ0eVwiPjwvbm9mLXRpbWUtcGlja2VyLWZhY2FkZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAjZm9jdXMgKm5nSWY9XCIhaXNNdWx0aWxpbmVcIiBbaWRdPVwicHJvcGVydHlQYW5lSWRcIiAgcGxhY2Vob2xkZXI9XCJ7e3Byb3BlcnR5RGVzY3JpcHRpb259fVwiIHR5cGU9XCJ7e2lzUGFzc3dvcmQgPyAncGFzc3dvcmQnIDogJ3RleHQnfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHlJZFwiIFtub2ZDbGVhcl09XCJzdWJqZWN0XCIgKGNsZWFyKT1cImNsZWFyKClcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGV4dGFyZWEgI2ZvY3VzICpuZ0lmPVwiaXNNdWx0aWxpbmVcIiByb3dzPVwie3tyb3dzfX1cIiBbaWRdPVwicHJvcGVydHlQYW5lSWRcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5SWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7e3Byb3BlcnR5RGVzY3JpcHRpb259fVwiPjwvdGV4dGFyZWE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidib29sZWFuJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAjZm9jdXMgI2NoZWNrYm94IFtpZF09XCJwcm9wZXJ0eVBhbmVJZFwiIHR5cGU9XCJjaGVja2JveFwiIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHlJZFwiLz57e3Byb3BlcnR5RGVzY3JpcHRpb259fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0ICNmb2N1cyBbaWRdPVwicHJvcGVydHlQYW5lSWRcIiAgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cInt7cHJvcGVydHlEZXNjcmlwdGlvbn19XCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eUlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25vZkNsZWFyXT1cInN1YmplY3RcIiAoY2xlYXIpPVwiY2xlYXIoKVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGRpdiBjbGFzcz1cInZhbGlkYXRpb25cIj57e21lc3NhZ2V9fTwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+Il19