@messaia/cdk 17.1.5-rc07 → 17.1.5-rc08

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -397,11 +397,11 @@ export class VdGenericFormComponent {
397
397
  console.log(message, optionalParams);
398
398
  }
399
399
  /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: VdGenericFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
400
- /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.5", type: VdGenericFormComponent, selector: "vd-generic-form", inputs: { formGroup: "formGroup", classType: "classType", formDefinition: "formDefinition", fieldGroups: "fieldGroups", groupName: "groupName", fieldSets: "fieldSets", context: "context", debugValue: "debugValue", readonly: "readonly", separatorKeysCodes: "separatorKeysCodes" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: VdEditorDirective, descendants: true }, { propertyName: "codeTemplate", first: true, predicate: VdCodeDirective, descendants: true }, { propertyName: "fileTemplate", first: true, predicate: VdFileDirective, descendants: true }, { propertyName: "customTemplate", first: true, predicate: VdCustomDirective, descendants: true }, { propertyName: "bottom", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "customFields", first: true, predicate: ["customFields"], descendants: true }, { propertyName: "customFieldsTemplates", predicate: VdGenericFormCustomFieldDirective }], ngImport: i0, template: "<div *ngIf=\"formGroup && fieldRows\" [formGroup]=\"formGroup\">\r\n <!-- #region Fields -->\r\n <ng-container *ngFor=\"let fields of fieldRows; let i = index\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <ng-container *ngFor=\"let field of fields\" [ngSwitch]=\"field.type\">\r\n <ng-container *ngIf=\"!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))\">\r\n <ng-container *ngIf=\"field.wrapped\">\r\n <!-- #region Text input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Text\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Textarea -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.TextArea\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <textarea matInput [formControlName]=\"field.name!\" rows=\"field.rows||2\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Enum -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Enum\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [enum]=\"field.enumType\" [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdSelect -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdSelect\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [matIconKey]=\"field.optionMatIconProperty\" [svgIconKey]=\"field.optionSvgIconProperty\" [fontSet]=\"field.optionIconFontSet\" [multiple]=\"field.multiple\" [selectFirst]=\"field.selectFirst\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerMapper && field.multiple && field.triggerMode == 'chip'\">\r\n <span *ngFor=\"let item of trigger\" class=\"mat-mdc-chip mat-mdc-standard-chip mat-primary mat-mdc-chip-selected\">\r\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\r\n </span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdList -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdList\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-list [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params ??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" [style.max-width]=\"field.maxWidth\" [style.max-height]=\"field.maxHeight\" flex>\r\n <ng-template vd-list-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-list>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Chips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Chips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-chip-row *ngFor=\"let chip of $any(formGroup.controls[field.name!])?.value\" (removed)=\"removeChip(field, chip)\" color=\"primary\" selectable=\"true\" selected>\r\n <span>{{chip}}</span>\r\n <button matChipRemove>\r\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"$any(field.label)\" #chipInput [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" [matAutocomplete]=\"chipAutocomplete\" (input)=\"filterAutocomplete(field, chipInput)\" (matChipInputTokenEnd)=\"addChip(field, $event)\" autocomplete=\"off\">\r\n </mat-chip-grid>\r\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdChips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdChips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-chips #vdChip [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params || {} | func:formValue:formGroup:context\" [searchField]=\"field.searchField\" [classType]=\"field.classType\" [projection]=\"field.projection\" [key]=\"field.optionValueProperty\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [removable]=\"!field.clear\" [context]=\"context\" [suffixButtons]=\"field.suffixButtons\" [autocompleteCssClass]=\"field.autocompleteCssClass\" (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (selected)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\" [customValue]=\"field.customValue\" layout=\"row\" flex>\r\n <ng-template vd-chip let-chip=\"chip\" *ngIf=\"field.chipTemplate\">\r\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n <ng-template vd-autocomplete-option let-option=\"option\" *ngIf=\"field.autocompleteTemplate\">\r\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n </vd-chips>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-hint *ngIf=\"vdChip.emptyResult\" class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Select -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Select\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-select [formControlName]=\"field.name!\" [multiple]=\"field.multiple\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex>\r\n <mat-option *ngFor=\"let option of $any(field.options)\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Autocomplete -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Autocomplete\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input type=\"text\" matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" [matAutocomplete]=\"auto\" #autocompleteInput (input)=\"filterAutocomplete(field, autocompleteInput)\" autocomplete=\"off\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Date -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Date\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" autocomplete=\"off\" [matDatepicker]=\"datePicker\" [matDatepickerFilter]=\"field.dateFilter\" [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Calendar -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Calendar\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\r\n <mat-calendar #calendar [selected]=\"formGroup.get(field.name!)?.value\" (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\" (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\" [headerComponent]=\"datePickerHeaderComponent\" style=\"width: 100%;\"></mat-calendar>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Color input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Color\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n </ng-container>\r\n\r\n <!-- #region Checkbox -->\r\n <div *ngSwitchCase=\"FormFieldType.Checkbox\" [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">{{field.label}}</mat-checkbox>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Editor -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Editor\">\r\n <ng-template *ngIf=\"editorTemplate?.templateRef!\" [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Code -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Code\">\r\n <ng-template *ngIf=\"codeTemplate?.templateRef!\" [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region File -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.File\">\r\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <div vd-file-input [formControlName]=\"field.name!\" (select)=\"field.change && field.change(field, $event, formGroup, context)\" [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex></div>\r\n </mat-form-field>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Custom -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Custom\">\r\n <ng-template *ngIf=\"customTemplate?.templateRef!\" [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == fields[0]?.row && customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </div>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngIf=\"customFields\" [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == ((fields[0]?.row??0)+1) && !customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Form bottom -->\r\n <ng-container *ngIf=\"bottom\" [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Template for suffix buttons -->\r\n <ng-template #suffixButtons let-field>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </ng-template>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formValue | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mdc-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "directive", type: i3.OnlyNumberDirective, selector: "[onlyNumber]", inputs: ["onlyNumber"] }, { kind: "component", type: i4.VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass", "triggerMode"] }, { kind: "directive", type: i5.VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: i6.VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "component", type: i7.VdChipsComponent, selector: "vd-chips", inputs: ["classType", "chips", "endpoint", "params", "projection", "paginated", "customValue", "context", "key", "searchField", "searchFields", "removable", "debounce", "autocompleteCssClass", "suffixButtons"], outputs: ["initSelect", "selected", "cleared", "launch", "chipFocus"] }, { kind: "directive", type: i8.VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "directive", type: i9.VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "component", type: i10.VdFileInputComponent, selector: "[vd-file-input]", inputs: ["accept", "placeholder", "required", "multiple", "disabled", "errorState"], outputs: ["select", "clear"] }, { kind: "component", type: i11.VdListComponent, selector: "vd-list" }, { kind: "directive", type: i12.VdListOptionDirective, selector: "[vd-list-option]ng-template" }, { kind: "directive", type: i13.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: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i13.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i13.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i13.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i13.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i13.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i13.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i14.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i14.MatLabel, selector: "mat-label" }, { kind: "directive", type: i14.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i14.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i14.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i15.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i16.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i17.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i18.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i19.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i20.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "component", type: i20.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i20.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i20.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i21.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i22.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i22.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i23.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i23.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i23.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i23.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i24.NgxColorsComponent, selector: "ngx-colors" }, { kind: "directive", type: i24.NgxColorsTriggerDirective, selector: "[ngx-colors-trigger]", inputs: ["colorsAnimation", "palette", "format", "formats", "position", "hideTextInput", "hideColorPicker", "attachTo", "overlayClassName", "colorPickerControls", "acceptLabel", "cancelLabel"], outputs: ["change", "input", "slider", "close", "open"] }, { kind: "directive", type: i25.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i26.MatFormFieldReadonlyDirective, selector: "mat-form-field" }, { kind: "directive", type: i27.EmptyStringResetDirective, selector: "[ngModel],[formControlName],[formControl]" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }, { kind: "pipe", type: i28.FuncPipe, name: "func" }] });
400
+ /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.5", type: VdGenericFormComponent, selector: "vd-generic-form", inputs: { formGroup: "formGroup", classType: "classType", formDefinition: "formDefinition", fieldGroups: "fieldGroups", groupName: "groupName", fieldSets: "fieldSets", context: "context", debugValue: "debugValue", readonly: "readonly", separatorKeysCodes: "separatorKeysCodes" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: VdEditorDirective, descendants: true }, { propertyName: "codeTemplate", first: true, predicate: VdCodeDirective, descendants: true }, { propertyName: "fileTemplate", first: true, predicate: VdFileDirective, descendants: true }, { propertyName: "customTemplate", first: true, predicate: VdCustomDirective, descendants: true }, { propertyName: "bottom", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "customFields", first: true, predicate: ["customFields"], descendants: true }, { propertyName: "customFieldsTemplates", predicate: VdGenericFormCustomFieldDirective }], ngImport: i0, template: "<div *ngIf=\"formGroup && fieldRows\" [formGroup]=\"formGroup\">\r\n <!-- #region Fields -->\r\n <ng-container *ngFor=\"let fields of fieldRows; let i = index\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <ng-container *ngFor=\"let field of fields\" [ngSwitch]=\"field.type\">\r\n <ng-container *ngIf=\"!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))\">\r\n <ng-container *ngIf=\"field.wrapped\">\r\n <!-- #region Text input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Text\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType ?? 'text'\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Textarea -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.TextArea\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <textarea matInput [formControlName]=\"field.name!\" rows=\"field.rows||2\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Enum -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Enum\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [enum]=\"field.enumType\" [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdSelect -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdSelect\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [matIconKey]=\"field.optionMatIconProperty\" [svgIconKey]=\"field.optionSvgIconProperty\" [fontSet]=\"field.optionIconFontSet\" [multiple]=\"field.multiple\" [selectFirst]=\"field.selectFirst\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerMapper && field.multiple && field.triggerMode == 'chip'\">\r\n <span *ngFor=\"let item of trigger\" class=\"mat-mdc-chip mat-mdc-standard-chip mat-primary mat-mdc-chip-selected\">\r\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\r\n </span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdList -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdList\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-list [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params ??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" [style.max-width]=\"field.maxWidth\" [style.max-height]=\"field.maxHeight\" flex>\r\n <ng-template vd-list-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-list>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Chips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Chips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-chip-row *ngFor=\"let chip of $any(formGroup.controls[field.name!])?.value\" (removed)=\"removeChip(field, chip)\" color=\"primary\" selectable=\"true\" selected>\r\n <span>{{chip}}</span>\r\n <button matChipRemove>\r\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"$any(field.label)\" #chipInput [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" [matAutocomplete]=\"chipAutocomplete\" (input)=\"filterAutocomplete(field, chipInput)\" (matChipInputTokenEnd)=\"addChip(field, $event)\" autocomplete=\"off\">\r\n </mat-chip-grid>\r\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdChips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdChips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-chips #vdChip [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params || {} | func:formValue:formGroup:context\" [searchField]=\"field.searchField\" [classType]=\"field.classType\" [projection]=\"field.projection\" [key]=\"field.optionValueProperty\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [removable]=\"!field.clear\" [context]=\"context\" [suffixButtons]=\"field.suffixButtons\" [autocompleteCssClass]=\"field.autocompleteCssClass\" (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (selected)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\" [customValue]=\"field.customValue\" layout=\"row\" flex>\r\n <ng-template vd-chip let-chip=\"chip\" *ngIf=\"field.chipTemplate\">\r\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n <ng-template vd-autocomplete-option let-option=\"option\" *ngIf=\"field.autocompleteTemplate\">\r\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n </vd-chips>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-hint *ngIf=\"vdChip.emptyResult\" class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Select -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Select\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-select [formControlName]=\"field.name!\" [multiple]=\"field.multiple\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex>\r\n <mat-option *ngFor=\"let option of $any(field.options)\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Autocomplete -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Autocomplete\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input type=\"text\" matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" [matAutocomplete]=\"auto\" #autocompleteInput (input)=\"filterAutocomplete(field, autocompleteInput)\" autocomplete=\"off\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Date -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Date\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" autocomplete=\"off\" [matDatepicker]=\"datePicker\" [matDatepickerFilter]=\"field.dateFilter\" [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Calendar -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Calendar\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\r\n <mat-calendar #calendar [selected]=\"formGroup.get(field.name!)?.value\" (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\" (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\" [headerComponent]=\"datePickerHeaderComponent\" style=\"width: 100%;\"></mat-calendar>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Color input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Color\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType ?? 'text'\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n </ng-container>\r\n\r\n <!-- #region Checkbox -->\r\n <div *ngSwitchCase=\"FormFieldType.Checkbox\" [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">{{field.label}}</mat-checkbox>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Editor -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Editor\">\r\n <ng-template *ngIf=\"editorTemplate?.templateRef!\" [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Code -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Code\">\r\n <ng-template *ngIf=\"codeTemplate?.templateRef!\" [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region File -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.File\">\r\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <div vd-file-input [formControlName]=\"field.name!\" (select)=\"field.change && field.change(field, $event, formGroup, context)\" [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex></div>\r\n </mat-form-field>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Custom -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Custom\">\r\n <ng-template *ngIf=\"customTemplate?.templateRef!\" [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == fields[0]?.row && customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </div>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngIf=\"customFields\" [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == ((fields[0]?.row??0)+1) && !customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Form bottom -->\r\n <ng-container *ngIf=\"bottom\" [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Template for suffix buttons -->\r\n <ng-template #suffixButtons let-field>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </ng-template>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formValue | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mdc-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "directive", type: i3.OnlyNumberDirective, selector: "[onlyNumber]", inputs: ["onlyNumber"] }, { kind: "component", type: i4.VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass", "triggerMode"] }, { kind: "directive", type: i5.VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: i6.VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "component", type: i7.VdChipsComponent, selector: "vd-chips", inputs: ["classType", "chips", "endpoint", "params", "projection", "paginated", "customValue", "context", "key", "searchField", "searchFields", "removable", "debounce", "autocompleteCssClass", "suffixButtons"], outputs: ["initSelect", "selected", "cleared", "launch", "chipFocus"] }, { kind: "directive", type: i8.VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "directive", type: i9.VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "component", type: i10.VdFileInputComponent, selector: "[vd-file-input]", inputs: ["accept", "placeholder", "required", "multiple", "disabled", "errorState"], outputs: ["select", "clear"] }, { kind: "component", type: i11.VdListComponent, selector: "vd-list" }, { kind: "directive", type: i12.VdListOptionDirective, selector: "[vd-list-option]ng-template" }, { kind: "directive", type: i13.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: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i13.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i13.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i13.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i13.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i13.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i13.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i14.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i14.MatLabel, selector: "mat-label" }, { kind: "directive", type: i14.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i14.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i14.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i15.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i16.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i17.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i18.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i19.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i20.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "component", type: i20.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i20.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i20.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i21.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i22.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i22.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i23.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i23.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i23.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i23.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i24.NgxColorsComponent, selector: "ngx-colors" }, { kind: "directive", type: i24.NgxColorsTriggerDirective, selector: "[ngx-colors-trigger]", inputs: ["colorsAnimation", "palette", "format", "formats", "position", "hideTextInput", "hideColorPicker", "attachTo", "overlayClassName", "colorPickerControls", "acceptLabel", "cancelLabel"], outputs: ["change", "input", "slider", "close", "open"] }, { kind: "directive", type: i25.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i26.MatFormFieldReadonlyDirective, selector: "mat-form-field" }, { kind: "directive", type: i27.EmptyStringResetDirective, selector: "[ngModel],[formControlName],[formControl]" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }, { kind: "pipe", type: i28.FuncPipe, name: "func" }] });
401
401
  }
402
402
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: VdGenericFormComponent, decorators: [{
403
403
  type: Component,
404
- args: [{ selector: 'vd-generic-form', template: "<div *ngIf=\"formGroup && fieldRows\" [formGroup]=\"formGroup\">\r\n <!-- #region Fields -->\r\n <ng-container *ngFor=\"let fields of fieldRows; let i = index\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <ng-container *ngFor=\"let field of fields\" [ngSwitch]=\"field.type\">\r\n <ng-container *ngIf=\"!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))\">\r\n <ng-container *ngIf=\"field.wrapped\">\r\n <!-- #region Text input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Text\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Textarea -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.TextArea\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <textarea matInput [formControlName]=\"field.name!\" rows=\"field.rows||2\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Enum -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Enum\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [enum]=\"field.enumType\" [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdSelect -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdSelect\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [matIconKey]=\"field.optionMatIconProperty\" [svgIconKey]=\"field.optionSvgIconProperty\" [fontSet]=\"field.optionIconFontSet\" [multiple]=\"field.multiple\" [selectFirst]=\"field.selectFirst\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerMapper && field.multiple && field.triggerMode == 'chip'\">\r\n <span *ngFor=\"let item of trigger\" class=\"mat-mdc-chip mat-mdc-standard-chip mat-primary mat-mdc-chip-selected\">\r\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\r\n </span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdList -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdList\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-list [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params ??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" [style.max-width]=\"field.maxWidth\" [style.max-height]=\"field.maxHeight\" flex>\r\n <ng-template vd-list-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-list>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Chips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Chips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-chip-row *ngFor=\"let chip of $any(formGroup.controls[field.name!])?.value\" (removed)=\"removeChip(field, chip)\" color=\"primary\" selectable=\"true\" selected>\r\n <span>{{chip}}</span>\r\n <button matChipRemove>\r\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"$any(field.label)\" #chipInput [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" [matAutocomplete]=\"chipAutocomplete\" (input)=\"filterAutocomplete(field, chipInput)\" (matChipInputTokenEnd)=\"addChip(field, $event)\" autocomplete=\"off\">\r\n </mat-chip-grid>\r\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdChips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdChips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-chips #vdChip [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params || {} | func:formValue:formGroup:context\" [searchField]=\"field.searchField\" [classType]=\"field.classType\" [projection]=\"field.projection\" [key]=\"field.optionValueProperty\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [removable]=\"!field.clear\" [context]=\"context\" [suffixButtons]=\"field.suffixButtons\" [autocompleteCssClass]=\"field.autocompleteCssClass\" (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (selected)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\" [customValue]=\"field.customValue\" layout=\"row\" flex>\r\n <ng-template vd-chip let-chip=\"chip\" *ngIf=\"field.chipTemplate\">\r\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n <ng-template vd-autocomplete-option let-option=\"option\" *ngIf=\"field.autocompleteTemplate\">\r\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n </vd-chips>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-hint *ngIf=\"vdChip.emptyResult\" class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Select -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Select\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-select [formControlName]=\"field.name!\" [multiple]=\"field.multiple\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex>\r\n <mat-option *ngFor=\"let option of $any(field.options)\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Autocomplete -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Autocomplete\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input type=\"text\" matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" [matAutocomplete]=\"auto\" #autocompleteInput (input)=\"filterAutocomplete(field, autocompleteInput)\" autocomplete=\"off\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Date -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Date\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" autocomplete=\"off\" [matDatepicker]=\"datePicker\" [matDatepickerFilter]=\"field.dateFilter\" [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Calendar -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Calendar\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\r\n <mat-calendar #calendar [selected]=\"formGroup.get(field.name!)?.value\" (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\" (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\" [headerComponent]=\"datePickerHeaderComponent\" style=\"width: 100%;\"></mat-calendar>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Color input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Color\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n </ng-container>\r\n\r\n <!-- #region Checkbox -->\r\n <div *ngSwitchCase=\"FormFieldType.Checkbox\" [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">{{field.label}}</mat-checkbox>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Editor -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Editor\">\r\n <ng-template *ngIf=\"editorTemplate?.templateRef!\" [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Code -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Code\">\r\n <ng-template *ngIf=\"codeTemplate?.templateRef!\" [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region File -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.File\">\r\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <div vd-file-input [formControlName]=\"field.name!\" (select)=\"field.change && field.change(field, $event, formGroup, context)\" [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex></div>\r\n </mat-form-field>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Custom -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Custom\">\r\n <ng-template *ngIf=\"customTemplate?.templateRef!\" [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == fields[0]?.row && customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </div>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngIf=\"customFields\" [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == ((fields[0]?.row??0)+1) && !customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Form bottom -->\r\n <ng-container *ngIf=\"bottom\" [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Template for suffix buttons -->\r\n <ng-template #suffixButtons let-field>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </ng-template>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formValue | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mdc-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}\n"] }]
404
+ args: [{ selector: 'vd-generic-form', template: "<div *ngIf=\"formGroup && fieldRows\" [formGroup]=\"formGroup\">\r\n <!-- #region Fields -->\r\n <ng-container *ngFor=\"let fields of fieldRows; let i = index\">\r\n <div layout-gt-sm=\"row\" layout=\"column\">\r\n <ng-container *ngFor=\"let field of fields\" [ngSwitch]=\"field.type\">\r\n <ng-container *ngIf=\"!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))\">\r\n <ng-container *ngIf=\"field.wrapped\">\r\n <!-- #region Text input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Text\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType ?? 'text'\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Textarea -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.TextArea\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <textarea matInput [formControlName]=\"field.name!\" rows=\"field.rows||2\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Enum -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Enum\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [enum]=\"field.enumType\" [enumFilter]=\"field.enumFilter | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdSelect -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdSelect\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-select [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [defaultOption]=\"field.defaultOption??true\" [matIconKey]=\"field.optionMatIconProperty\" [svgIconKey]=\"field.optionSvgIconProperty\" [fontSet]=\"field.optionIconFontSet\" [multiple]=\"field.multiple\" [selectFirst]=\"field.selectFirst\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" layout=\"row\" flex>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerTemplate\">\r\n <span [innerHTML]=\"field.triggerTemplate(trigger, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n <ng-template vd-select-trigger let-trigger=\"trigger\" *ngIf=\"field.triggerMapper && field.multiple && field.triggerMode == 'chip'\">\r\n <span *ngFor=\"let item of trigger\" class=\"mat-mdc-chip mat-mdc-standard-chip mat-primary mat-mdc-chip-selected\">\r\n <span [innerHTML]=\"field.triggerMapper(item, formValue, formGroup, context)\"></span>\r\n </span>\r\n </ng-template>\r\n <ng-template vd-select-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdList -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdList\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-list\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-list [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params ??{} | func:formValue:formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formValue:formGroup:context\" [optionValueProperty]=\"field.optionValueProperty\" [optionTextProperty]=\"field.optionTextProperty\" [multiple]=\"field.multiple\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" [style.max-width]=\"field.maxWidth\" [style.max-height]=\"field.maxHeight\" flex>\r\n <ng-template vd-list-option let-option=\"option\" *ngIf=\"field.optionTemplate\">\r\n <span [outerHTML]=\"field.optionTemplate(option, formValue, formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-list>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Chips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Chips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-chip-row *ngFor=\"let chip of $any(formGroup.controls[field.name!])?.value\" (removed)=\"removeChip(field, chip)\" color=\"primary\" selectable=\"true\" selected>\r\n <span>{{chip}}</span>\r\n <button matChipRemove>\r\n <mat-icon fontSet=\"material-symbols-outlined\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"$any(field.label)\" #chipInput [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" [matAutocomplete]=\"chipAutocomplete\" (input)=\"filterAutocomplete(field, chipInput)\" (matChipInputTokenEnd)=\"addChip(field, $event)\" autocomplete=\"off\">\r\n </mat-chip-grid>\r\n <mat-autocomplete autoActiveFirstOption #chipAutocomplete=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\" (optionSelected)=\"autocompleteValueSelected(field, $event, chipInput)\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region VdChips -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.VdChips\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <vd-chips #vdChip [formControlName]=\"field.name!\" [endpoint]=\"field.endpoint??'' | func:formValue:formGroup:context\" [params]=\"field.params || {} | func:formValue:formGroup:context\" [searchField]=\"field.searchField\" [classType]=\"field.classType\" [projection]=\"field.projection\" [key]=\"field.optionValueProperty\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [removable]=\"!field.clear\" [context]=\"context\" [suffixButtons]=\"field.suffixButtons\" [autocompleteCssClass]=\"field.autocompleteCssClass\" (initSelect)=\"field.itemSelect && field.itemSelect($event, formValue, formGroup, context);\" (selected)=\"field.itemChange && field.itemChange($event, formValue, formGroup, context);\" (cleared)=\"field.clear && field.clear(formValue, formGroup, context);\" [customValue]=\"field.customValue\" layout=\"row\" flex>\r\n <ng-template vd-chip let-chip=\"chip\" *ngIf=\"field.chipTemplate\">\r\n <div [outerHTML]=\"field.chipTemplate(chip, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n <ng-template vd-autocomplete-option let-option=\"option\" *ngIf=\"field.autocompleteTemplate\">\r\n <div [outerHTML]=\"field.autocompleteTemplate(option, formValue, formGroup, context)\"></div>\r\n </ng-template>\r\n </vd-chips>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-hint *ngIf=\"vdChip.emptyResult\" class=\"tc-red-400\" i18n=\"@@noResultsFound\">No results were found.</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Select -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Select\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <mat-select [formControlName]=\"field.name!\" [multiple]=\"field.multiple\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex>\r\n <mat-option *ngFor=\"let option of $any(field.options)\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Autocomplete -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Autocomplete\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input type=\"text\" matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" [matAutocomplete]=\"auto\" #autocompleteInput (input)=\"filterAutocomplete(field, autocompleteInput)\" autocomplete=\"off\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">\r\n <mat-autocomplete autoActiveFirstOption #auto=\"matAutocomplete\" [class]=\"field.autocompleteCssClass\">\r\n <mat-option *ngFor=\"let option of autocompleteFilteredOptions[field.name!]\" [value]=\"option.id\">\r\n {{option.name}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Date -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Date\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input matInput [formControlName]=\"field.name!\" [min]=\"field.min\" [max]=\"field.max\" autocomplete=\"off\" [matDatepicker]=\"datePicker\" [matDatepickerFilter]=\"field.dateFilter\" [readonly]=\"readonly || field.forceSelect || (field.readonly && field.readonly(formValue, formGroup, context))\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" (monthSelected)=\"handleDatePickerFilterAsync(datePicker, field, $event )\" (opened)=\"handleDatePickerOpened(datePicker, field)\" [calendarHeaderComponent]=\"datePickerHeaderComponent\"></mat-datepicker>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Calendar -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Calendar\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" floatLabel=\"always\" class=\"form-field-type-calendar\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input input=\"hidden\" hidden matInput [formControlName]=\"field.name!\">\r\n <mat-calendar #calendar [selected]=\"formGroup.get(field.name!)?.value\" (selectedChange)=\"formGroup.get(field.name!)?.setValue($event);\" (monthSelected)=\"handleCalendarFilterAsync(calendar, field, $event )\" [headerComponent]=\"datePickerHeaderComponent\" style=\"width: 100%;\"></mat-calendar>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Color input -->\r\n <mat-form-field *ngSwitchCase=\"FormFieldType.Color\" [attr.flex]=\"field.flex||0\" [class]=\"field.cssClass\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <input [type]=\"field.inputType ?? 'text'\" [minlength]=\"field.minLength||null\" [maxlength]=\"field.maxLength||null\" [min]=\"field.min\" [max]=\"field.max\" matInput [formControlName]=\"field.name!\" [readonly]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" [pattern]=\"(field.pattern??'')\" [onlyNumber]=\"(field.numbersOnly??false)\">\r\n <ngx-colors matSuffix ngx-colors-trigger [formControlName]=\"field.name!\" [hideTextInput]=\"true\" (close)=\"this.formGroup.get(field.name!)?.setValue($event)\" format=\"hex\" class=\"color-picker\"></ngx-colors>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n <mat-hint *ngIf=\"field.hint\">{{field.hint}}</mat-hint>\r\n <mat-error *ngFor=\"let errorMessage of $any($any(formGroup.controls[field.name!]))['errorMessages']\">{{errorMessage}}</mat-error>\r\n </mat-form-field>\r\n <!-- #endregion -->\r\n </ng-container>\r\n\r\n <!-- #region Checkbox -->\r\n <div *ngSwitchCase=\"FormFieldType.Checkbox\" [attr.flex]=\"field.flex||0\" class=\"mat-checkbox-wrap\" [class]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name!\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\">{{field.label}}</mat-checkbox>\r\n <mat-error *ngFor=\"let errorMessage of $any(formGroup.controls[field.name!])['errorMessages']\" layout-margin>{{errorMessage}}</mat-error>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Editor -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Editor\">\r\n <ng-template *ngIf=\"editorTemplate?.templateRef!\" [ngTemplateOutlet]=\"editorTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Code -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Code\">\r\n <ng-template *ngIf=\"codeTemplate?.templateRef!\" [ngTemplateOutlet]=\"codeTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region File -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.File\">\r\n <mat-form-field [attr.flex]=\"field.flex||0\" layout-margin>\r\n <mat-label>{{field.label}}</mat-label>\r\n <div vd-file-input [formControlName]=\"field.name!\" (select)=\"field.change && field.change(field, $event, formGroup, context)\" [accept]=\"field.fileExtensions\" [disableControl]=\"(readonly || (field.readonly && field.readonly(formValue, formGroup, context)))??false\" flex></div>\r\n </mat-form-field>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Custom -->\r\n <ng-container *ngSwitchCase=\"FormFieldType.Custom\">\r\n <ng-template *ngIf=\"customTemplate?.templateRef!\" [ngTemplateOutlet]=\"customTemplate?.templateRef!\" [ngTemplateOutletContext]=\"{ field: field, formGroup: formGroup }\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == fields[0]?.row && customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </div>\r\n\r\n <!-- #region Template for custom fields -->\r\n <ng-container *ngIf=\"customFields\" [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == ((fields[0]?.row??0)+1) && !customField.inline\" [ngTemplateOutlet]=\"customField?.templateRef!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\r\n </ng-container>\r\n <!-- #endregion -->\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Form bottom -->\r\n <ng-container *ngIf=\"bottom\" [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Template for suffix buttons -->\r\n <ng-template #suffixButtons let-field>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </ng-template>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formValue | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mdc-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}\n"] }]
405
405
  }], propDecorators: { formGroup: [{
406
406
  type: Input
407
407
  }], classType: [{
@@ -444,4 +444,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImpor
444
444
  type: ContentChildren,
445
445
  args: [VdGenericFormCustomFieldDirective]
446
446
  }] } });
447
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nkay9zcmMvbGliL2Zvcm1zL2NvbXBvbmVudHMvZ2VuZXJpYy1mb3JtL2dlbmVyaWMtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZGsvc3JjL2xpYi9mb3Jtcy9jb21wb25lbnRzL2dlbmVyaWMtZm9ybS9nZW5lcmljLWZvcm0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsU0FBUyxFQUFFLFlBQVksRUFBaUIsV0FBVyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoTCxPQUFPLEVBQWUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSXBFLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQzVHLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFHOUQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMkNBQTJDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV0Rjs7R0FFRztBQUVILE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxTQUFTO0lBQzVDLFlBQVksV0FBNkIsRUFBRSxnQkFBa0M7UUFDekUsS0FBSyxDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7MEhBSFEsaUJBQWlCOzhHQUFqQixpQkFBaUI7OzJGQUFqQixpQkFBaUI7a0JBRDdCLFNBQVM7bUJBQUMsRUFBRSxRQUFRLEVBQUUsd0JBQXdCLEVBQUU7O0FBT2pEOztHQUVHO0FBRUgsTUFBTSxPQUFPLGVBQWdCLFNBQVEsU0FBUztJQUMxQyxZQUFZLFdBQTZCLEVBQUUsZ0JBQWtDO1FBQ3pFLEtBQUssQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUN6QyxDQUFDOzBIQUhRLGVBQWU7OEdBQWYsZUFBZTs7MkZBQWYsZUFBZTtrQkFEM0IsU0FBUzttQkFBQyxFQUFFLFFBQVEsRUFBRSxzQkFBc0IsRUFBRTs7QUFPL0M7O0dBRUc7QUFFSCxNQUFNLE9BQU8sZUFBZ0IsU0FBUSxTQUFTO0lBQzFDLFlBQVksV0FBNkIsRUFBRSxnQkFBa0M7UUFDekUsS0FBSyxDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7MEhBSFEsZUFBZTs4R0FBZixlQUFlOzsyRkFBZixlQUFlO2tCQUQzQixTQUFTO21CQUFDLEVBQUUsUUFBUSxFQUFFLHNCQUFzQixFQUFFOztBQU8vQzs7R0FFRztBQUVILE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxTQUFTO0lBQzVDLFlBQVksV0FBNkIsRUFBRSxnQkFBa0M7UUFDekUsS0FBSyxDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7MEhBSFEsaUJBQWlCOzhHQUFqQixpQkFBaUI7OzJGQUFqQixpQkFBaUI7a0JBRDdCLFNBQVM7bUJBQUMsRUFBRSxRQUFRLEVBQUUsd0JBQXdCLEVBQUU7O0FBWWpELE1BQU0sT0FBTyxzQkFBc0I7SUFDL0I7O09BRUc7SUFFSSxTQUFTLENBQWE7SUFFN0I7O09BRUc7SUFDSCxJQUFXLFNBQVMsS0FBVSxPQUFPLElBQUksQ0FBQyxTQUFTLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXJFOztPQUVHO0lBRUksU0FBUyxDQUFhO0lBRTdCOztPQUVHO0lBRUksY0FBYyxDQUFrQjtJQUV2Qzs7T0FFRztJQUVJLFdBQVcsQ0FBOEI7SUFFaEQ7O09BRUc7SUFFSSxTQUFTLENBQVU7SUFFMUI7O09BRUc7SUFFSSxTQUFTLENBQVk7SUFFNUI7OztPQUdHO0lBRUksT0FBTyxDQUFNO0lBRXBCOztPQUVHO0lBRUksVUFBVSxHQUFZLEtBQUssQ0FBQztJQUVuQzs7T0FFRztJQUVJLFFBQVEsQ0FBVztJQUUxQjs7T0FFRztJQUVJLGtCQUFrQixHQUFhLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBRXJEOztPQUVHO0lBQ0ksU0FBUyxDQUEyQjtJQUUzQzs7T0FFRztJQUNJLE1BQU0sQ0FBeUI7SUFFdEM7O09BRUc7SUFDSSxhQUFhLEdBQXlCLGFBQWEsQ0FBQztJQUUzRDs7T0FFRztJQUVJLGNBQWMsQ0FBcUI7SUFFMUM7O09BRUc7SUFFSSxZQUFZLENBQW1CO0lBRXRDOztPQUVHO0lBRUksWUFBWSxDQUFtQjtJQUV0Qzs7T0FFRztJQUVJLGNBQWMsQ0FBcUI7SUFFMUM7O09BRUc7SUFDSSx5QkFBeUIsR0FBRyx5QkFBeUIsQ0FBQztJQUU3RDs7T0FFRztJQUVJLE1BQU0sQ0FBb0I7SUFFakM7O09BRUc7SUFFSSxZQUFZLENBQW9CO0lBRXZDOztPQUVHO0lBRUkscUJBQXFCLENBQWdEO0lBRTVFOztPQUVHO0lBQ0ksMkJBQTJCLEdBQVEsRUFBRSxDQUFDO0lBRTdDOzs7Ozs7T0FNRztJQUNILFFBQVE7UUFDSiwyQkFBMkI7UUFDM0IsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLHdCQUF3QixFQUFFO1lBQ3pDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUN0QjtRQUVELG9CQUFvQjtRQUNwQixJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUN6QyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFO1lBQ3hDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQTs0RUFDMkQsQ0FDdkUsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUM7UUFFYixJQUFJLFNBQVMsRUFBRTtZQUNYLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN4RjtRQUVELHlCQUF5QjtRQUN6QixJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUM5TDtRQUVELG9CQUFvQjtRQUNwQixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDL0QsSUFBSSxNQUFNLEVBQUU7WUFDUixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ3REO1FBRUQsOEJBQThCO1FBQzlCLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLGFBQWEsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUN2RSxJQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxFQUFFLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFFLENBQUMsTUFBTSxJQUFJLENBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDcEosQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLGVBQWUsR0FBRyxDQUFDLFFBQTZCLEVBQUUsQ0FBc0IsRUFBRSxFQUFFO1lBQzVFLDZDQUE2QztZQUM3QyxJQUFJLElBQUksR0FBRyxRQUFRLEVBQUUsSUFBSSxDQUFDO1lBQzFCLElBQUksS0FBSyxHQUFHLFFBQVEsRUFBRSxLQUFLLENBQUM7WUFDNUIsSUFBSSxPQUFPLEdBQUcsUUFBUSxFQUFFLE9BQU8sQ0FBQztZQUVoQywyQkFBMkI7WUFDM0IsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLE9BQU8sSUFBSSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUVwRyw0QkFBNEI7WUFDNUIsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLE9BQU8sS0FBSyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUV4Ryw4QkFBOEI7WUFDOUIsQ0FBQyxDQUFDLE9BQU8sR0FBRyxDQUFDLE9BQU8sT0FBTyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUVoSCwwQkFBMEI7WUFDMUIsSUFBSSxXQUFXLEdBQXVDLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7WUFFeEYsb0NBQW9DO1lBQ3BDLElBQUksUUFBUSxHQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQ3pJLElBQUksV0FBVyxJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUU7Z0JBQ3ZDLElBQUksUUFBUSxLQUFLLElBQUksRUFBRTtvQkFDbkIsV0FBVyxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ2xEO3FCQUFNO29CQUNILFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ3JEO2FBQ0o7UUFDTCxDQUFDLENBQUE7UUFFRCwyQ0FBMkM7UUFDM0MsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNoQixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdELElBQUksUUFBUSxFQUFFO2dCQUNWLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxRQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUMvRTtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxrQkFBa0IsQ0FBQyxLQUEwQixFQUFFLEtBQVU7UUFDNUQsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQ1osSUFBSSxDQUFDLDJCQUEyQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBaUMsS0FBSyxDQUFDLE9BQVE7Z0JBQ3ZGLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDdEc7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLHlCQUF5QixDQUFDLEtBQTBCLEVBQUUsS0FBbUMsRUFBRSxjQUFtQjtRQUNqSCxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzdDLGNBQWMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksT0FBTyxDQUFDLEtBQTBCLEVBQUUsS0FBd0I7UUFDL0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLEtBQUssQ0FBQyxTQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxVQUFVLENBQUMsS0FBMEIsRUFBRSxJQUFTO1FBQ25ELCtDQUErQztRQUMvQyxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXpELCtCQUErQjtRQUMvQixNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQyxJQUFJLE9BQU8sSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFO1lBQ3ZCLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvQixPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxTQUFTLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQztTQUM1QztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssUUFBUSxDQUFDLEtBQTBCLEVBQUUsS0FBYTtRQUN0RCwrQ0FBK0M7UUFDL0MsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUV6RCwrQkFBK0I7UUFDL0IsS0FBSyxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzdCLElBQUksT0FBTyxJQUFJLEtBQUssRUFBRTtZQUNsQixRQUFRLEtBQUssQ0FBQyxTQUFTLEVBQUU7Z0JBQ3JCLEtBQUssUUFBUTtvQkFDVCxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzdCLElBQUksTUFBTSxFQUFFO3dCQUNSLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO3FCQUM5QjtvQkFDRCxNQUFNO2dCQUVWLEtBQUssT0FBTztvQkFDUixJQUFJLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzlCLElBQUksS0FBSyxFQUFFO3dCQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUM3QjtvQkFDRCxNQUFNO2dCQUVWO29CQUNJLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMxQixNQUFNO2FBQ2I7WUFFRCxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxTQUFTLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQztTQUM1QztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksc0JBQXNCLENBQUMsVUFBOEIsRUFBRSxLQUEwQjtRQUNwRixJQUFJLEtBQUssRUFBRSxnQkFBZ0IsRUFBRTtZQUN6QixLQUFLLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQzNGO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSwyQkFBMkIsQ0FBQyxVQUE4QixFQUFFLEtBQTBCLEVBQUUsSUFBZ0I7UUFDM0csSUFBSSxLQUFLLEVBQUUsZUFBZSxFQUFFO1lBQ3hCLHdCQUF3QjtZQUN4QixVQUFVLENBQUMsZUFBZSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQU8sRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDO1lBQzNELFVBQVUsQ0FBQyxXQUFXLENBQWdCLEVBQUUsWUFBWSxFQUFFLElBQUksWUFBWSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRXpGLDRCQUE0QjtZQUM1QixLQUFLLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQzNGLFVBQVUsQ0FBQyxlQUFlLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMvRCxVQUFVLENBQUMsV0FBVyxDQUFnQixFQUFFLFlBQVksRUFBRSxJQUFJLFlBQVksQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM3RixDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSx5QkFBeUIsQ0FBQyxRQUEwQixFQUFFLEtBQTBCLEVBQUUsSUFBZ0I7UUFDckcsSUFBSSxLQUFLLEVBQUUsZUFBZSxFQUFFO1lBQ3hCLHdCQUF3QjtZQUN4QixRQUFRLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBTyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDekMsUUFBUSxDQUFDLFdBQVcsQ0FBZ0IsRUFBRSxZQUFZLEVBQUUsSUFBSSxZQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFdkYsNEJBQTRCO1lBQzVCLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDOUcsUUFBUSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDN0MsUUFBUSxDQUFDLFdBQVcsQ0FBZ0IsRUFBRSxZQUFZLEVBQUUsSUFBSSxZQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZGLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ08sV0FBVztRQUNqQix1Q0FBdUM7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpR0FBaUcsQ0FBQyxDQUFDO1NBQ3RIO1FBRUQseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxjQUFjLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUU5RCxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksR0FBRyxDQUFDLE9BQVksRUFBRSxHQUFHLGNBQXFCO1FBQzdDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7MEhBdlhRLHNCQUFzQjs4R0FBdEIsc0JBQXNCLDJYQXFGakIsaUJBQWlCLCtFQU1qQixlQUFlLCtFQU1mLGVBQWUsaUZBTWYsaUJBQWlCLDZQQXVCZCxpQ0FBaUMsNkJDMUx0RCwydTRCQXlSTTs7MkZEN05PLHNCQUFzQjtrQkFMbEMsU0FBUzsrQkFDSSxpQkFBaUI7OEJBU3BCLFNBQVM7c0JBRGYsS0FBSztnQkFZQyxTQUFTO3NCQURmLEtBQUs7Z0JBT0MsY0FBYztzQkFEcEIsS0FBSztnQkFPQyxXQUFXO3NCQURqQixLQUFLO2dCQU9DLFNBQVM7c0JBRGYsS0FBSztnQkFPQyxTQUFTO3NCQURmLEtBQUs7Z0JBUUMsT0FBTztzQkFEYixLQUFLO2dCQU9DLFVBQVU7c0JBRGhCLEtBQUs7Z0JBT0MsUUFBUTtzQkFEZCxLQUFLO2dCQU9DLGtCQUFrQjtzQkFEeEIsS0FBSztnQkFzQkMsY0FBYztzQkFEcEIsWUFBWTt1QkFBQyxpQkFBaUI7Z0JBT3hCLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsZUFBZTtnQkFPdEIsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxlQUFlO2dCQU90QixjQUFjO3NCQURwQixZQUFZO3VCQUFDLGlCQUFpQjtnQkFZeEIsTUFBTTtzQkFEWixZQUFZO3VCQUFDLFFBQVE7Z0JBT2YsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxjQUFjO2dCQU9yQixxQkFBcUI7c0JBRDNCLGVBQWU7dUJBQUMsaUNBQWlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ09NTUEsIEVOVEVSIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcclxuaW1wb3J0IHsgQ2RrUG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XHJcbmltcG9ydCB7IENvbXBvbmVudCwgQ29udGVudENoaWxkLCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgSW5wdXQsIE9uSW5pdCwgUXVlcnlMaXN0LCBTaW1wbGVDaGFuZ2UsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBUeXBlLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE1hdEF1dG9jb21wbGV0ZVNlbGVjdGVkRXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9hdXRvY29tcGxldGUnO1xyXG5pbXBvcnQgeyBNYXRDaGlwSW5wdXRFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NoaXBzJztcclxuaW1wb3J0IHsgTWF0Q2FsZW5kYXIsIE1hdERhdGVwaWNrZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcclxuaW1wb3J0IHsgVmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy92ZC1nZW5lcmljLWZvcm0tY3VzdG9tLWZpZWxkLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEZvcm1GaWVsZFR5cGUgfSBmcm9tICcuLi8uLi9lbnVtcy9mb3JtLWZpZWxkLXR5cGUnO1xyXG5pbXBvcnQgeyBnZXRGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBGb3JtRmllbGREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Zvcm0tZmllbGQtZGVmaW5pdGlvbic7XHJcbmltcG9ydCB7IEZvcm1GaWVsZEdyb3VwRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWZpZWxkLWdyb3VwLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBEYXRlUGlja2VySGVhZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vZGF0ZXBpY2tlci9kYXRlcGlja2VyLWhlYWRlci5jb21wb25lbnQnO1xyXG5cclxuLyoqXHJcbiAqIFZkRWRpdG9yRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtZWRpdG9yXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRFZGl0b3JEaXJlY3RpdmUgZXh0ZW5kcyBDZGtQb3J0YWwge1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBWZENvZGVEaXJlY3RpdmUgY2xhc3NcclxuICovXHJcbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1t2ZC1jb2RlXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRDb2RlRGlyZWN0aXZlIGV4dGVuZHMgQ2RrUG9ydGFsIHtcclxuICAgIGNvbnN0cnVjdG9yKHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+LCB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmKSB7XHJcbiAgICAgICAgc3VwZXIodGVtcGxhdGVSZWYsIHZpZXdDb250YWluZXJSZWYpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogVmRGaWxlRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtZmlsZV1uZy10ZW1wbGF0ZScgfSlcclxuZXhwb3J0IGNsYXNzIFZkRmlsZURpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Piwgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZikge1xyXG4gICAgICAgIHN1cGVyKHRlbXBsYXRlUmVmLCB2aWV3Q29udGFpbmVyUmVmKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFZkQ3VzdG9tRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtY3VzdG9tXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRDdXN0b21EaXJlY3RpdmUgZXh0ZW5kcyBDZGtQb3J0YWwge1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICd2ZC1nZW5lcmljLWZvcm0nLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2dlbmVyaWMtZm9ybS5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9nZW5lcmljLWZvcm0uY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVmRHZW5lcmljRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgICAvKipcclxuICAgICAqIGZvcm06IEZvcm1Hcm91cFxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGZvcm1Hcm91cD86IEZvcm1Hcm91cDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZvcm0gcmF3IHZhbHVlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgZm9ybVZhbHVlKCk6IGFueSB7IHJldHVybiB0aGlzLmZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKTsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogY2xhc3NUeXBlOiBUeXBlPGFueT5cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjbGFzc1R5cGU/OiBUeXBlPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBmb3JtRGVmaW5pdGlvbjogRm9ybURlZmluaXRpb25cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmb3JtRGVmaW5pdGlvbj86IEZvcm1EZWZpbml0aW9uO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogZmllbGRHcm91cHM6IEZvcm1GaWVsZEdyb3VwW11cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmaWVsZEdyb3Vwcz86IEZvcm1GaWVsZEdyb3VwRGVmaW5pdGlvbltdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR3JvdXAgbmFtZVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGdyb3VwTmFtZT86IHN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpZWxkIHNldCBuYW1lXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZmllbGRTZXRzPzogc3RyaW5nW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBjb250ZXh0OiBhbnlcclxuICAgICAqIFRoZSBjdXJyZW50IGNvbnRleHRcclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjb250ZXh0OiBhbnk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBkZWJ1Z1ZhbHVlOiBib29sZWFuXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZGVidWdWYWx1ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogcmVhZG9ubHk6IGJvb2xlYW5cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyByZWFkb25seT86IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBzZXBhcmF0b3JLZXlzQ29kZXM6IG51bWJlcltdXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2VwYXJhdG9yS2V5c0NvZGVzOiBudW1iZXJbXSA9IFtFTlRFUiwgQ09NTUFdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogZmllbGRSb3dzOiBGb3JtRmllbGREZWZpbml0aW9uW11bXVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmllbGRSb3dzPzogRm9ybUZpZWxkRGVmaW5pdGlvbltdW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBmaWVsZHM6IEZvcm1GaWVsZERlZmluaXRpb25bXVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmllbGRzPzogRm9ybUZpZWxkRGVmaW5pdGlvbltdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRm9ybUZpZWxkVHlwZTogdHlwZW9mIEZvcm1GaWVsZFR5cGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIEZvcm1GaWVsZFR5cGU6IHR5cGVvZiBGb3JtRmllbGRUeXBlID0gRm9ybUZpZWxkVHlwZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVkaXRvciB0ZW1wbGF0ZVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKFZkRWRpdG9yRGlyZWN0aXZlKVxyXG4gICAgcHVibGljIGVkaXRvclRlbXBsYXRlPzogVmRFZGl0b3JEaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb2RlIHRlbXBsYXRlXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoVmRDb2RlRGlyZWN0aXZlKVxyXG4gICAgcHVibGljIGNvZGVUZW1wbGF0ZT86IFZkQ29kZURpcmVjdGl2ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbGUgdGVtcGxhdGVcclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZEZpbGVEaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgZmlsZVRlbXBsYXRlPzogVmRGaWxlRGlyZWN0aXZlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3VzdG9tIHRlbXBsYXRlXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoVmRDdXN0b21EaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgY3VzdG9tVGVtcGxhdGU/OiBWZEN1c3RvbURpcmVjdGl2ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEN1c3RvbWVyIGRhdGUgaGVhZGVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkYXRlUGlja2VySGVhZGVyQ29tcG9uZW50ID0gRGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkcyBvbiB0aGUgYm90dG9tXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2JvdHRvbScpXHJcbiAgICBwdWJsaWMgYm90dG9tPzogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKCdjdXN0b21GaWVsZHMnKVxyXG4gICAgcHVibGljIGN1c3RvbUZpZWxkcz86IFRlbXBsYXRlUmVmPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZW1wbGF0ZSByZWYgZm9yIGN1c3RvbSBmaWVsZHMgb24gdGhlIGJvdHRvbVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkcmVuKFZkR2VuZXJpY0Zvcm1DdXN0b21GaWVsZERpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBjdXN0b21GaWVsZHNUZW1wbGF0ZXM/OiBRdWVyeUxpc3Q8VmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbHRlcmQgb3B0aW9ucyBmb3IgYXV0b2NvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdXRvY29tcGxldGVGaWx0ZXJlZE9wdGlvbnM6IGFueSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWxsYmFjayBtZXRob2QgdGhhdCBpcyBpbnZva2VkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZVxyXG4gICAgICogZGVmYXVsdCBjaGFuZ2UgZGV0ZWN0b3IgaGFzIGNoZWNrZWQgdGhlIGRpcmVjdGl2ZSdzXHJcbiAgICAgKiBkYXRhLWJvdW5kIHByb3BlcnRpZXMgZm9yIHRoZSBmaXJzdCB0aW1lLFxyXG4gICAgICogYW5kIGJlZm9yZSBhbnkgb2YgdGhlIHZpZXcgb3IgY29udGVudCBjaGlsZHJlbiBoYXZlIGJlZW4gY2hlY2tlZC5cclxuICAgICAqIEl0IGlzIGludm9rZWQgb25seSBvbmNlIHdoZW4gdGhlIGRpcmVjdGl2ZSBpcyBpbnN0YW50aWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgICAgIC8qIEJ1aWxkIHRoZSBmb3JtIGZpZWxkcyAqL1xyXG4gICAgICAgIGlmICh0aGlzLmNsYXNzVHlwZSAvKiYmICF0aGlzLmZpZWxkR3JvdXBzKi8pIHtcclxuICAgICAgICAgICAgdGhpcy5idWlsZEZpZWxkcygpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogR2V0IGZpbGVkIHJvd3MgKi9cclxuICAgICAgICBsZXQgZmllbGRSb3dzID0gdGhpcy5maWVsZEdyb3Vwcz8uZmlsdGVyKHggPT5cclxuICAgICAgICAgICAgeC5uYW1lPy50cmltKCkgPT0gdGhpcy5ncm91cE5hbWU/LnRyaW0oKSAmJlxyXG4gICAgICAgICAgICAheC5oaWRkZW4vKiAmJlxyXG4gICAgICAgICAgICAoIXguaGlkZSB8fCAheC5oaWRlKHRoaXMuZm9ybVZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KSkqL1xyXG4gICAgICAgIClbMF0/Lmdyb3VwcztcclxuXHJcbiAgICAgICAgaWYgKGZpZWxkUm93cykge1xyXG4gICAgICAgICAgICB0aGlzLmZpZWxkUm93cyA9IGZpZWxkUm93cy5tYXAoYSA9PiB7IHJldHVybiBbLi4uYS5tYXAoeSA9PiB7IHJldHVybiB7IC4uLnkgfSB9KV0gfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBGaWx0ZXIgYnkgZmllbGQgc2V0ICovXHJcbiAgICAgICAgaWYgKHRoaXMuZmllbGRTZXRzICYmIHRoaXMuZmllbGRSb3dzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmllbGRSb3dzID0gdGhpcy5maWVsZFJvd3MubWFwKHggPT4geCA9IHguZmlsdGVyKHkgPT4geS5maWVsZFNldHM/LnNvbWUoeiA9PiB0aGlzLmZpZWxkU2V0cz8uc29tZShhID0+IGE/LnRyaW0oKT8udG9Mb3dlckNhc2UoKSA9PSB6Py50cmltKCk/LnRvTG93ZXJDYXNlKCkpKSkpLmZpbHRlcih4ID0+IHgubGVuZ3RoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIEdldCBhbGwgZmllbGRzICovXHJcbiAgICAgICAgbGV0IGZpZWxkcyA9IHRoaXMuZmllbGRSb3dzPy5yZWR1Y2UoKGEsIGIpID0+IGEuY29uY2F0KGIpLCBbXSk7XHJcbiAgICAgICAgaWYgKGZpZWxkcykge1xyXG4gICAgICAgICAgICB0aGlzLmZpZWxkcyA9IGZpZWxkcy5tYXAoYSA9PiB7IHJldHVybiB7IC4uLmEgfSB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIFN1YnNjcmllIHRvIGNoYW5nZSBldmVudCAqL1xyXG4gICAgICAgIGZpZWxkcz8uZmlsdGVyKHkgPT4geS50eXBlICE9IEZvcm1GaWVsZFR5cGUuRmlsZSAmJiB5LmNoYW5nZSk/LmZvckVhY2goeCA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy5nZXQoeC5uYW1lID8/ICcnKT8udmFsdWVDaGFuZ2VzPy5zdWJzY3JpYmUoeSA9PiB4IS5jaGFuZ2UgJiYgeCEuY2hhbmdlKHksIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsZXQgdXBkYXRlRm9ybUZpZWxkID0gKG9yZ0ZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCB4OiBGb3JtRmllbGREZWZpbml0aW9uKSA9PiB7XHJcbiAgICAgICAgICAgIC8qIEdldCB0aGUgdHlwZSBhbmQgdGhlIGxhYmVsIG9mIHRoZSBmaWVsZCAqL1xyXG4gICAgICAgICAgICBsZXQgdHlwZSA9IG9yZ0ZpZWxkPy50eXBlO1xyXG4gICAgICAgICAgICBsZXQgbGFiZWwgPSBvcmdGaWVsZD8ubGFiZWw7XHJcbiAgICAgICAgICAgIGxldCBvcHRpb25zID0gb3JnRmllbGQ/Lm9wdGlvbnM7XHJcblxyXG4gICAgICAgICAgICAvKiBSZW5kZXIgdGhlIGZpZWxkIHR5cGUgKi9cclxuICAgICAgICAgICAgeC50eXBlID0gKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSA/IHR5cGUodGhpcy5mb3JtVmFsdWUsIHRoaXMuZm9ybUdyb3VwLCB0aGlzLmNvbnRleHQpIDogeC50eXBlO1xyXG5cclxuICAgICAgICAgICAgLyogUmVuZGVyIHRoZSBmaWVsZCBsYWJlbCAqL1xyXG4gICAgICAgICAgICB4LmxhYmVsID0gKHR5cGVvZiBsYWJlbCA9PT0gJ2Z1bmN0aW9uJykgPyBsYWJlbCh0aGlzLmZvcm1WYWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkgOiB4LmxhYmVsO1xyXG5cclxuICAgICAgICAgICAgLyogUmVuZGVyIHRoZSBmaWVsZCBvcHRpb25zICovXHJcbiAgICAgICAgICAgIHgub3B0aW9ucyA9ICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgPyBvcHRpb25zKHRoaXMuZm9ybVZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KSA6IHgub3B0aW9ucztcclxuXHJcbiAgICAgICAgICAgIC8qIEdldCB0aGUgZm9ybSBjb250cm9sICovXHJcbiAgICAgICAgICAgIGxldCBmb3JtQ29udHJvbDogRm9ybUNvbnRyb2w8YW55PiA9IDxGb3JtQ29udHJvbDxhbnk+PnRoaXMuZm9ybUdyb3VwPy5nZXQoeC5uYW1lID8/ICcnKTtcclxuXHJcbiAgICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSBmaWVsZCBpcyByZXF1aXJlZCAqL1xyXG4gICAgICAgICAgICBsZXQgcmVxdWlyZWQ6IGJvb2xlYW4gfCBhbnkgPSAodHlwZW9mIHgucmVxdWlyZWQgPT09ICdmdW5jdGlvbicpID8geC5yZXF1aXJlZCh0aGlzLmZvcm1WYWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkgOiB4LnJlcXVpcmVkO1xyXG4gICAgICAgICAgICBpZiAoZm9ybUNvbnRyb2wgJiYgcmVxdWlyZWQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVkID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wuYWRkVmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wucmVtb3ZlVmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogVXBkYXRlIHNvbWUgdmFsdWVzIChsYWJlbCwgdHlwZSwgLi4uKSAqL1xyXG4gICAgICAgIGZpZWxkcz8uZm9yRWFjaCh4ID0+IHtcclxuICAgICAgICAgICAgdmFyIG9yZ0ZpZWxkID0gdGhpcy5maWVsZHM/LmZpbHRlcih5ID0+IHkubmFtZSA9PSB4Lm5hbWUpWzBdO1xyXG4gICAgICAgICAgICBpZiAob3JnRmllbGQpIHtcclxuICAgICAgICAgICAgICAgIHVwZGF0ZUZvcm1GaWVsZChvcmdGaWVsZCwgeCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1Hcm91cD8udmFsdWVDaGFuZ2VzPy5zdWJzY3JpYmUoeSA9PiB1cGRhdGVGb3JtRmllbGQob3JnRmllbGQhLCB4KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhhbmRsZXMgYXV0b2NvbXBsZXRlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmaWx0ZXJBdXRvY29tcGxldGUoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZmllbGQubmFtZSkge1xyXG4gICAgICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZUZpbHRlcmVkT3B0aW9uc1tmaWVsZC5uYW1lXSA9ICg8eyBpZDogYW55LCBuYW1lOiBzdHJpbmcgfVtdPmZpZWxkLm9wdGlvbnMpXHJcbiAgICAgICAgICAgICAgICA/LmZpbHRlcihvcHRpb24gPT4gb3B0aW9uLm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhldmVudC52YWx1ZT8udG9TdHJpbmcoKT8udG9Mb3dlckNhc2UoKSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBjaGlwIHdoZW4gYSBhdXRvY29tcGxldGUgdmFsdWUgaXMgc2VsZWN0ZWRcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSBldmVudCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGF1dG9jb21wbGV0ZVZhbHVlU2VsZWN0ZWQoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGV2ZW50OiBNYXRBdXRvY29tcGxldGVTZWxlY3RlZEV2ZW50LCBjaGlwSW5wdXRFdmVudDogYW55KTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fYWRkQ2hpcChmaWVsZCwgZXZlbnQub3B0aW9uLnZpZXdWYWx1ZSk7XHJcbiAgICAgICAgY2hpcElucHV0RXZlbnQudmFsdWUgPSAnJztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBjaGlwXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGRDaGlwKGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBldmVudDogTWF0Q2hpcElucHV0RXZlbnQpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9hZGRDaGlwKGZpZWxkLCBldmVudC52YWx1ZSk7XHJcbiAgICAgICAgZXZlbnQuY2hpcElucHV0IS5jbGVhcigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBhIGNoaXBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSBjaGlwIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVtb3ZlQ2hpcChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgY2hpcDogYW55KTogdm9pZCB7XHJcbiAgICAgICAgLyogR2V0IHRoZSBmb3JtIGNvbnRyb2wgdXNpbmcgdGhlIGZpZWxkIG5hbWUgKi9cclxuICAgICAgICBsZXQgY29udHJvbCA9IHRoaXMuZm9ybUdyb3VwPy5jb250cm9sc1tmaWVsZC5uYW1lID8/ICcnXTtcclxuXHJcbiAgICAgICAgLyogR2V0IHRoZSBpbmRleCBvZiB0aGUgY2hpcCAqL1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gY29udHJvbD8udmFsdWUuaW5kZXhPZihjaGlwKTtcclxuICAgICAgICBpZiAoY29udHJvbCAmJiBpbmRleCA+PSAwKSB7XHJcbiAgICAgICAgICAgIGNvbnRyb2wudmFsdWUuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cD8udXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBjaGlwXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2FkZENoaXAoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICAvKiBHZXQgdGhlIGZvcm0gY29udHJvbCB1c2luZyB0aGUgZmllbGQgbmFtZSAqL1xyXG4gICAgICAgIGxldCBjb250cm9sID0gdGhpcy5mb3JtR3JvdXA/LmNvbnRyb2xzW2ZpZWxkLm5hbWUgPz8gJyddO1xyXG5cclxuICAgICAgICAvKiBHZXQgdGhlIHZhbHVlIG9mIHRoZSBjaGlwICovXHJcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfHwgJycpLnRyaW0oKTtcclxuICAgICAgICBpZiAoY29udHJvbCAmJiB2YWx1ZSkge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGZpZWxkLmlucHV0VHlwZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnbnVtYmVyJzpcclxuICAgICAgICAgICAgICAgICAgICBsZXQgbnVtYmVyID0gcGFyc2VJbnQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChudW1iZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC52YWx1ZS5wdXNoKG51bWJlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Zsb2F0JzpcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZmxvYXQgPSBwYXJzZUZsb2F0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmxvYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC52YWx1ZS5wdXNoKGZsb2F0KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2godmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICAgICAgdGhpcy5mb3JtR3JvdXA/Lm1hcmtBc0RpcnR5KCk7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyBkYXRlIHBpY2tlciBvcGVuZWQgZXZlbnRcclxuICAgICAqIEBwYXJhbSBkYXRlUGlja2VyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlRGF0ZVBpY2tlck9wZW5lZChkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlUGlja2VyT3BlbmVkKSB7XHJcbiAgICAgICAgICAgIGZpZWxkLmRhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGRhdGUgZmlsdGVyIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0gZGF0ZVBpY2tlciBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGhhbmRsZURhdGVQaWNrZXJGaWx0ZXJBc3luYyhkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBkYXRlOiBEYXRlIHwgYW55KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlRmlsdGVyQXN5bmMpIHtcclxuICAgICAgICAgICAgLyogRGlzYWJsZXMgYWxsIGRhdGVzICovXHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIuZGF0ZXBpY2tlcklucHV0LmRhdGVGaWx0ZXIgPSAoZDogRGF0ZSkgPT4gZmFsc2U7XHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICBmaWVsZC5kYXRlRmlsdGVyQXN5bmMoZGF0ZSwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KS5zdWJzY3JpYmUoeCA9PiB7XHJcbiAgICAgICAgICAgICAgICBkYXRlUGlja2VyLmRhdGVwaWNrZXJJbnB1dC5kYXRlRmlsdGVyID0gKGQ6IERhdGUpID0+IGQgJiYgeChkKTtcclxuICAgICAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGNhbGVuZGFyIGZpbHRlciBldmVudFxyXG4gICAgICogQHBhcmFtIGNhbGVuZGFyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlQ2FsZW5kYXJGaWx0ZXJBc3luYyhjYWxlbmRhcjogTWF0Q2FsZW5kYXI8YW55PiwgZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGRhdGU6IERhdGUgfCBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZmllbGQ/LmRhdGVGaWx0ZXJBc3luYykge1xyXG4gICAgICAgICAgICAvKiBEaXNhYmxlcyBhbGwgZGF0ZXMgKi9cclxuICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBmYWxzZTtcclxuICAgICAgICAgICAgY2FsZW5kYXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICB2YXIgc3Vic2NyaXB0aW9uID0gZmllbGQuZGF0ZUZpbHRlckFzeW5jKGRhdGUsIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkuc3Vic2NyaWJlKHggPT4ge1xyXG4gICAgICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBkICYmIHgoZCk7XHJcbiAgICAgICAgICAgICAgICBjYWxlbmRhci5uZ09uQ2hhbmdlcyg8U2ltcGxlQ2hhbmdlcz57ICdkYXRlRmlsdGVyJzogbmV3IFNpbXBsZUNoYW5nZShcIlwiLCBcIlwiLCBmYWxzZSkgfSk7XHJcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQnVpbGRzIHRoZSBmb3JtIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYnVpbGRGaWVsZHMoKTogdm9pZCB7XHJcbiAgICAgICAgLyogQ2hlY2sgaWYgY2xhc3NUeXBlIGlzIG5vdCBkZWZpbmVkICovXHJcbiAgICAgICAgaWYgKCF0aGlzLmNsYXNzVHlwZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2xhc3NUeXBlLiBQbGVhc2UgZW5zdXJlIGNsYXNzVHlwZSBpcyBkZWZpbmVkLCBub3QgbnVsbCwgYW5kIGlzIGEgY29uc3RydWN0b3IgZnVuY3Rpb24uJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBHZXQgZm9ybSBkZWZpbml0aW9uICovXHJcbiAgICAgICAgdGhpcy5mb3JtRGVmaW5pdGlvbiA9IGdldEZvcm1EZWZpbml0aW9uKG5ldyB0aGlzLmNsYXNzVHlwZSgpKTtcclxuXHJcbiAgICAgICAgLyogQ3JlYXRlIHRoZSBmcm9tIGZpZWxkcyB1c2luZyB0aGUgZW50aXR5IHR5cGUgKi9cclxuICAgICAgICB0aGlzLmZpZWxkR3JvdXBzID0gdGhpcy5mb3JtRGVmaW5pdGlvbj8uZmllbGRHcm91cHM/LmZpbHRlcih4ID0+ICF4LmhpZGRlbik/Lm1hcChhID0+IHsgcmV0dXJuIHsgLi4uYSB9IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9nIHRvIGNvbnNvbGVcclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFxyXG4gICAgICogQHBhcmFtIG9wdGlvbmFsUGFyYW1zIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9nKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2cobWVzc2FnZSwgb3B0aW9uYWxQYXJhbXMpO1xyXG4gICAgfVxyXG59IiwiPGRpdiAqbmdJZj1cImZvcm1Hcm91cCAmJiBmaWVsZFJvd3NcIiBbZm9ybUdyb3VwXT1cImZvcm1Hcm91cFwiPlxyXG4gICAgPCEtLSAjcmVnaW9uIEZpZWxkcyAtLT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkcyBvZiBmaWVsZFJvd3M7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICA8ZGl2IGxheW91dC1ndC1zbT1cInJvd1wiIGxheW91dD1cImNvbHVtblwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmaWVsZHNcIiBbbmdTd2l0Y2hdPVwiZmllbGQudHlwZVwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmaWVsZC5oaWRkZW4gJiYgIShmaWVsZC5oaWRlICYmIGZpZWxkLmhpZGUoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWVsZC53cmFwcGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZXh0IGlucHV0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVGV4dFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cImZpZWxkLmlucHV0VHlwZVwiIFttaW5sZW5ndGhdPVwiZmllbGQubWluTGVuZ3RofHxudWxsXCIgW21heGxlbmd0aF09XCJmaWVsZC5tYXhMZW5ndGh8fG51bGxcIiBbbWluXT1cImZpZWxkLm1pblwiIFttYXhdPVwiZmllbGQubWF4XCIgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFtyZWFkb25seV09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiIFtwYXR0ZXJuXT1cIihmaWVsZC5wYXR0ZXJuPz8nJylcIiBbb25seU51bWJlcl09XCIoZmllbGQubnVtYmVyc09ubHk/P2ZhbHNlKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFRleHRhcmVhIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVGV4dEFyZWFcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgcm93cz1cImZpZWxkLnJvd3N8fDJcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIj48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIEVudW0gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5FbnVtXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbZW51bV09XCJmaWVsZC5lbnVtVHlwZVwiIFtlbnVtRmlsdGVyXT1cImZpZWxkLmVudW1GaWx0ZXIgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtvcHRpb25WYWx1ZVByb3BlcnR5XT1cImZpZWxkLm9wdGlvblZhbHVlUHJvcGVydHlcIiBbb3B0aW9uVGV4dFByb3BlcnR5XT1cImZpZWxkLm9wdGlvblRleHRQcm9wZXJ0eVwiIFtkZWZhdWx0T3B0aW9uXT1cImZpZWxkLmRlZmF1bHRPcHRpb24/P3RydWVcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIiBbdHJpZ2dlckNzc0NsYXNzXT1cImZpZWxkLnRyaWdnZXJDc3NDbGFzc1wiIFt0cmlnZ2VyTW9kZV09XCJmaWVsZC50cmlnZ2VyTW9kZVwiIGxheW91dD1cInJvd1wiIGZsZXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC10cmlnZ2VyIGxldC10cmlnZ2VyPVwidHJpZ2dlclwiICpuZ0lmPVwiZmllbGQudHJpZ2dlclRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtpbm5lckhUTUxdPVwiZmllbGQudHJpZ2dlclRlbXBsYXRlKHRyaWdnZXIsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3Qtb3B0aW9uIGxldC1vcHRpb249XCJvcHRpb25cIiAqbmdJZj1cImZpZWxkLm9wdGlvblRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtvdXRlckhUTUxdPVwiZmllbGQub3B0aW9uVGVtcGxhdGUob3B0aW9uLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFZkU2VsZWN0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVmRTZWxlY3RcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx2ZC1zZWxlY3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFtlbmRwb2ludF09XCJmaWVsZC5lbmRwb2ludD8/JycgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtwYXJhbXNdPVwiZmllbGQucGFyYW1zPz97fSB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW3Byb2plY3Rpb25dPVwiZmllbGQucHJvamVjdGlvblwiIFttYXBwZXJdPVwiZmllbGQubWFwcGVyXCIgW2NvbXBhcmVXaXRoXT1cImZpZWxkLmNvbXBhcmVXaXRoXCIgW2xvYWREYXRhXT1cImZpZWxkLmZldGNoQ29uZGl0aW9uIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbb3B0aW9uVmFsdWVQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25WYWx1ZVByb3BlcnR5XCIgW29wdGlvblRleHRQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25UZXh0UHJvcGVydHlcIiBbZGVmYXVsdE9wdGlvbl09XCJmaWVsZC5kZWZhdWx0T3B0aW9uPz90cnVlXCIgW21hdEljb25LZXldPVwiZmllbGQub3B0aW9uTWF0SWNvblByb3BlcnR5XCIgW3N2Z0ljb25LZXldPVwiZmllbGQub3B0aW9uU3ZnSWNvblByb3BlcnR5XCIgW2ZvbnRTZXRdPVwiZmllbGQub3B0aW9uSWNvbkZvbnRTZXRcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbc2VsZWN0Rmlyc3RdPVwiZmllbGQuc2VsZWN0Rmlyc3RcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIiBbdHJpZ2dlckNzc0NsYXNzXT1cImZpZWxkLnRyaWdnZXJDc3NDbGFzc1wiIFt0cmlnZ2VyTW9kZV09XCJmaWVsZC50cmlnZ2VyTW9kZVwiIChpdGVtU2VsZWN0ZWQpPVwiZmllbGQuaXRlbVNlbGVjdCAmJiBmaWVsZC5pdGVtU2VsZWN0KCRldmVudCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpO1wiIChpdGVtQ2hhbmdlKT1cImZpZWxkLml0ZW1DaGFuZ2UgJiYgZmllbGQuaXRlbUNoYW5nZSgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiBsYXlvdXQ9XCJyb3dcIiBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3QtdHJpZ2dlciBsZXQtdHJpZ2dlcj1cInRyaWdnZXJcIiAqbmdJZj1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZSh0cmlnZ2VyLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LXRyaWdnZXIgbGV0LXRyaWdnZXI9XCJ0cmlnZ2VyXCIgKm5nSWY9XCJmaWVsZC50cmlnZ2VyTWFwcGVyICYmIGZpZWxkLm11bHRpcGxlICYmIGZpZWxkLnRyaWdnZXJNb2RlID09ICdjaGlwJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiB0cmlnZ2VyXCIgY2xhc3M9XCJtYXQtbWRjLWNoaXAgbWF0LW1kYy1zdGFuZGFyZC1jaGlwIG1hdC1wcmltYXJ5IG1hdC1tZGMtY2hpcC1zZWxlY3RlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySFRNTF09XCJmaWVsZC50cmlnZ2VyTWFwcGVyKGl0ZW0sIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiICpuZ0lmPVwiZmllbGQub3B0aW9uVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW291dGVySFRNTF09XCJmaWVsZC5vcHRpb25UZW1wbGF0ZShvcHRpb24sIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC92ZC1zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1WYWx1ZSwgY29udGV4dClcIiAoY2xpY2spPVwic3VmZml4QnV0dG9uLmV2ZW50ICYmIHN1ZmZpeEJ1dHRvbi5ldmVudChmb3JtVmFsdWUsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBmb250U2V0PVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gVmRMaXN0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVmRMaXN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgZmxvYXRMYWJlbD1cImFsd2F5c1wiIGNsYXNzPVwiZm9ybS1maWVsZC10eXBlLWxpc3RcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx2ZC1saXN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbZW5kcG9pbnRdPVwiZmllbGQuZW5kcG9pbnQ/PycnIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbcGFyYW1zXT1cImZpZWxkLnBhcmFtcyA/P3t9IHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbcHJvamVjdGlvbl09XCJmaWVsZC5wcm9qZWN0aW9uXCIgW21hcHBlcl09XCJmaWVsZC5tYXBwZXJcIiBbY29tcGFyZVdpdGhdPVwiZmllbGQuY29tcGFyZVdpdGhcIiBbbG9hZERhdGFdPVwiZmllbGQuZmV0Y2hDb25kaXRpb24gfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtvcHRpb25WYWx1ZVByb3BlcnR5XT1cImZpZWxkLm9wdGlvblZhbHVlUHJvcGVydHlcIiBbb3B0aW9uVGV4dFByb3BlcnR5XT1cImZpZWxkLm9wdGlvblRleHRQcm9wZXJ0eVwiIFttdWx0aXBsZV09XCJmaWVsZC5tdWx0aXBsZVwiIFtyZWFkb25seV09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiIChpdGVtU2VsZWN0ZWQpPVwiZmllbGQuaXRlbVNlbGVjdCAmJiBmaWVsZC5pdGVtU2VsZWN0KCRldmVudCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpO1wiIChpdGVtQ2hhbmdlKT1cImZpZWxkLml0ZW1DaGFuZ2UgJiYgZmllbGQuaXRlbUNoYW5nZSgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiBbc3R5bGUubWF4LXdpZHRoXT1cImZpZWxkLm1heFdpZHRoXCIgW3N0eWxlLm1heC1oZWlnaHRdPVwiZmllbGQubWF4SGVpZ2h0XCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtbGlzdC1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiICpuZ0lmPVwiZmllbGQub3B0aW9uVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW291dGVySFRNTF09XCJmaWVsZC5vcHRpb25UZW1wbGF0ZShvcHRpb24sIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC92ZC1saXN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDaGlwcyAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkNoaXBzXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoaXAtZ3JpZCAjY2hpcExpc3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFtkaXNhYmxlQ29udHJvbF09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hpcC1yb3cgKm5nRm9yPVwibGV0IGNoaXAgb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKT8udmFsdWVcIiAocmVtb3ZlZCk9XCJyZW1vdmVDaGlwKGZpZWxkLCBjaGlwKVwiIGNvbG9yPVwicHJpbWFyeVwiIHNlbGVjdGFibGU9XCJ0cnVlXCIgc2VsZWN0ZWQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7Y2hpcH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdENoaXBSZW1vdmU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj5jYW5jZWw8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGlwLXJvdz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgW3BsYWNlaG9sZGVyXT1cIiRhbnkoZmllbGQubGFiZWwpXCIgI2NoaXBJbnB1dCBbbWF0Q2hpcElucHV0Rm9yXT1cImNoaXBMaXN0XCIgW21hdENoaXBJbnB1dFNlcGFyYXRvcktleUNvZGVzXT1cInNlcGFyYXRvcktleXNDb2Rlc1wiIFttYXRBdXRvY29tcGxldGVdPVwiY2hpcEF1dG9jb21wbGV0ZVwiIChpbnB1dCk9XCJmaWx0ZXJBdXRvY29tcGxldGUoZmllbGQsIGNoaXBJbnB1dClcIiAobWF0Q2hpcElucHV0VG9rZW5FbmQpPVwiYWRkQ2hpcChmaWVsZCwgJGV2ZW50KVwiIGF1dG9jb21wbGV0ZT1cIm9mZlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hpcC1ncmlkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1hdXRvY29tcGxldGUgYXV0b0FjdGl2ZUZpcnN0T3B0aW9uICNjaGlwQXV0b2NvbXBsZXRlPVwibWF0QXV0b2NvbXBsZXRlXCIgW2NsYXNzXT1cImZpZWxkLmF1dG9jb21wbGV0ZUNzc0NsYXNzXCIgKG9wdGlvblNlbGVjdGVkKT1cImF1dG9jb21wbGV0ZVZhbHVlU2VsZWN0ZWQoZmllbGQsICRldmVudCwgY2hpcElucHV0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWUhXVwiIFt2YWx1ZV09XCJvcHRpb24uaWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tvcHRpb24ubmFtZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtYXV0b2NvbXBsZXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFZkQ2hpcHMgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5WZENoaXBzXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtY2hpcHMgI3ZkQ2hpcCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW2VuZHBvaW50XT1cImZpZWxkLmVuZHBvaW50Pz8nJyB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgfHwge30gfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtzZWFyY2hGaWVsZF09XCJmaWVsZC5zZWFyY2hGaWVsZFwiIFtjbGFzc1R5cGVdPVwiZmllbGQuY2xhc3NUeXBlXCIgW3Byb2plY3Rpb25dPVwiZmllbGQucHJvamVjdGlvblwiIFtrZXldPVwiZmllbGQub3B0aW9uVmFsdWVQcm9wZXJ0eVwiIFtyZWFkb25seV09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiIFtyZW1vdmFibGVdPVwiIWZpZWxkLmNsZWFyXCIgW2NvbnRleHRdPVwiY29udGV4dFwiIFtzdWZmaXhCdXR0b25zXT1cImZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBbYXV0b2NvbXBsZXRlQ3NzQ2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIiAoaW5pdFNlbGVjdCk9XCJmaWVsZC5pdGVtU2VsZWN0ICYmIGZpZWxkLml0ZW1TZWxlY3QoJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgKHNlbGVjdGVkKT1cImZpZWxkLml0ZW1DaGFuZ2UgJiYgZmllbGQuaXRlbUNoYW5nZSgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiAoY2xlYXJlZCk9XCJmaWVsZC5jbGVhciAmJiBmaWVsZC5jbGVhcihmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgW2N1c3RvbVZhbHVlXT1cImZpZWxkLmN1c3RvbVZhbHVlXCIgbGF5b3V0PVwicm93XCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtY2hpcCBsZXQtY2hpcD1cImNoaXBcIiAqbmdJZj1cImZpZWxkLmNoaXBUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtvdXRlckhUTUxdPVwiZmllbGQuY2hpcFRlbXBsYXRlKGNoaXAsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLWF1dG9jb21wbGV0ZS1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiICpuZ0lmPVwiZmllbGQuYXV0b2NvbXBsZXRlVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbb3V0ZXJIVE1MXT1cImZpZWxkLmF1dG9jb21wbGV0ZVRlbXBsYXRlKG9wdGlvbiwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtY2hpcHM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwidmRDaGlwLmVtcHR5UmVzdWx0XCIgY2xhc3M9XCJ0Yy1yZWQtNDAwXCIgaTE4bj1cIkBAbm9SZXN1bHRzRm91bmRcIj5ObyByZXN1bHRzIHdlcmUgZm91bmQuPC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBTZWxlY3QgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5TZWxlY3RcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbZGlzYWJsZUNvbnRyb2xdPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIiBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgJGFueShmaWVsZC5vcHRpb25zKVwiIFt2YWx1ZV09XCJvcHRpb24uaWRcIj57e29wdGlvbi5uYW1lfX08L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1WYWx1ZSwgY29udGV4dClcIiAoY2xpY2spPVwic3VmZml4QnV0dG9uLmV2ZW50ICYmIHN1ZmZpeEJ1dHRvbi5ldmVudChmb3JtVmFsdWUsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBmb250U2V0PVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gQXV0b2NvbXBsZXRlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQXV0b2NvbXBsZXRlXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiIFttYXRBdXRvY29tcGxldGVdPVwiYXV0b1wiICNhdXRvY29tcGxldGVJbnB1dCAoaW5wdXQpPVwiZmlsdGVyQXV0b2NvbXBsZXRlKGZpZWxkLCBhdXRvY29tcGxldGVJbnB1dClcIiBhdXRvY29tcGxldGU9XCJvZmZcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtYXV0b2NvbXBsZXRlIGF1dG9BY3RpdmVGaXJzdE9wdGlvbiAjYXV0bz1cIm1hdEF1dG9jb21wbGV0ZVwiIFtjbGFzc109XCJmaWVsZC5hdXRvY29tcGxldGVDc3NDbGFzc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWUhXVwiIFt2YWx1ZV09XCJvcHRpb24uaWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tvcHRpb24ubmFtZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtYXV0b2NvbXBsZXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIERhdGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5EYXRlXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFttaW5dPVwiZmllbGQubWluXCIgW21heF09XCJmaWVsZC5tYXhcIiBhdXRvY29tcGxldGU9XCJvZmZcIiBbbWF0RGF0ZXBpY2tlcl09XCJkYXRlUGlja2VyXCIgW21hdERhdGVwaWNrZXJGaWx0ZXJdPVwiZmllbGQuZGF0ZUZpbHRlclwiIFtyZWFkb25seV09XCJyZWFkb25seSB8fCBmaWVsZC5mb3JjZVNlbGVjdCB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlcGlja2VyLXRvZ2dsZSBtYXRTdWZmaXggW2Zvcl09XCJkYXRlUGlja2VyXCI+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWRhdGVwaWNrZXIgI2RhdGVQaWNrZXIgW2Rpc2FibGVkXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCIgKG1vbnRoU2VsZWN0ZWQpPVwiaGFuZGxlRGF0ZVBpY2tlckZpbHRlckFzeW5jKGRhdGVQaWNrZXIsIGZpZWxkLCAkZXZlbnQgKVwiIChvcGVuZWQpPVwiaGFuZGxlRGF0ZVBpY2tlck9wZW5lZChkYXRlUGlja2VyLCBmaWVsZClcIiBbY2FsZW5kYXJIZWFkZXJDb21wb25lbnRdPVwiZGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudFwiPjwvbWF0LWRhdGVwaWNrZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENhbGVuZGFyIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2FsZW5kYXJcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBmbG9hdExhYmVsPVwiYWx3YXlzXCIgY2xhc3M9XCJmb3JtLWZpZWxkLXR5cGUtY2FsZW5kYXJcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpbnB1dD1cImhpZGRlblwiIGhpZGRlbiBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNhbGVuZGFyICNjYWxlbmRhciBbc2VsZWN0ZWRdPVwiZm9ybUdyb3VwLmdldChmaWVsZC5uYW1lISk/LnZhbHVlXCIgKHNlbGVjdGVkQ2hhbmdlKT1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSEpPy5zZXRWYWx1ZSgkZXZlbnQpO1wiIChtb250aFNlbGVjdGVkKT1cImhhbmRsZUNhbGVuZGFyRmlsdGVyQXN5bmMoY2FsZW5kYXIsIGZpZWxkLCAkZXZlbnQgKVwiIFtoZWFkZXJDb21wb25lbnRdPVwiZGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudFwiIHN0eWxlPVwid2lkdGg6IDEwMCU7XCI+PC9tYXQtY2FsZW5kYXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCIgbGF5b3V0LW1hcmdpbj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDb2xvciBpbnB1dCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkNvbG9yXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgW3R5cGVdPVwiZmllbGQuaW5wdXRUeXBlXCIgW21pbmxlbmd0aF09XCJmaWVsZC5taW5MZW5ndGh8fG51bGxcIiBbbWF4bGVuZ3RoXT1cImZpZWxkLm1heExlbmd0aHx8bnVsbFwiIFttaW5dPVwiZmllbGQubWluXCIgW21heF09XCJmaWVsZC5tYXhcIiBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCIgW3BhdHRlcm5dPVwiKGZpZWxkLnBhdHRlcm4/PycnKVwiIFtvbmx5TnVtYmVyXT1cIihmaWVsZC5udW1iZXJzT25seT8/ZmFsc2UpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmd4LWNvbG9ycyBtYXRTdWZmaXggbmd4LWNvbG9ycy10cmlnZ2VyIFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbaGlkZVRleHRJbnB1dF09XCJ0cnVlXCIgKGNsb3NlKT1cInRoaXMuZm9ybUdyb3VwLmdldChmaWVsZC5uYW1lISk/LnNldFZhbHVlKCRldmVudClcIiBmb3JtYXQ9XCJoZXhcIiBjbGFzcz1cImNvbG9yLXBpY2tlclwiPjwvbmd4LWNvbG9ycz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KCRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSkpWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENoZWNrYm94IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2hlY2tib3hcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBjbGFzcz1cIm1hdC1jaGVja2JveC13cmFwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFtkaXNhYmxlQ29udHJvbF09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiPnt7ZmllbGQubGFiZWx9fTwvbWF0LWNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCIgbGF5b3V0LW1hcmdpbj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gRWRpdG9yIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuRWRpdG9yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImVkaXRvclRlbXBsYXRlPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJlZGl0b3JUZW1wbGF0ZT8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgZmllbGQ6IGZpZWxkLCBmb3JtR3JvdXA6IGZvcm1Hcm91cCB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDb2RlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ29kZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJjb2RlVGVtcGxhdGU/LnRlbXBsYXRlUmVmIVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvZGVUZW1wbGF0ZT8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgZmllbGQ6IGZpZWxkLCBmb3JtR3JvdXA6IGZvcm1Hcm91cCB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBGaWxlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuRmlsZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHZkLWZpbGUtaW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIChzZWxlY3QpPVwiZmllbGQuY2hhbmdlICYmIGZpZWxkLmNoYW5nZShmaWVsZCwgJGV2ZW50LCBmb3JtR3JvdXAsIGNvbnRleHQpXCIgW2FjY2VwdF09XCJmaWVsZC5maWxlRXh0ZW5zaW9uc1wiIFtkaXNhYmxlQ29udHJvbF09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiIGZsZXg+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gQ3VzdG9tIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ3VzdG9tXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImN1c3RvbVRlbXBsYXRlPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJjdXN0b21UZW1wbGF0ZT8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgZmllbGQ6IGZpZWxkLCBmb3JtR3JvdXA6IGZvcm1Hcm91cCB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICA8IS0tICNyZWdpb24gVGVtcGxhdGUgZm9yIGN1c3RvbSBmaWVsZHMgLS0+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGN1c3RvbUZpZWxkIG9mIGN1c3RvbUZpZWxkc1RlbXBsYXRlc1wiPlxyXG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmICYmIGN1c3RvbUZpZWxkLnJvdyA9PSBmaWVsZHNbMF0/LnJvdyAmJiBjdXN0b21GaWVsZC5pbmxpbmVcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJjdXN0b21GaWVsZD8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntmb3JtR3JvdXA6IGZvcm1Hcm91cH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tICNyZWdpb24gVGVtcGxhdGUgZm9yIGN1c3RvbSBmaWVsZHMgLS0+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImN1c3RvbUZpZWxkc1wiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbUZpZWxkc1wiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXAsIHJvdzogZmllbGRzWzBdLnJvd31cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjdXN0b21GaWVsZCBvZiBjdXN0b21GaWVsZHNUZW1wbGF0ZXNcIj5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmICYmIGN1c3RvbUZpZWxkLnJvdyA9PSAoKGZpZWxkc1swXT8ucm93Pz8wKSsxKSAmJiAhY3VzdG9tRmllbGQuaW5saW5lXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmIVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICA8IS0tICNyZWdpb24gRm9ybSBib3R0b20gLS0+XHJcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYm90dG9tXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiYm90dG9tXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntmb3JtR3JvdXA6IGZvcm1Hcm91cH1cIj48L25nLWNvbnRhaW5lcj5cclxuICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICA8IS0tICNyZWdpb24gVGVtcGxhdGUgZm9yIHN1ZmZpeCBidXR0b25zIC0tPlxyXG4gICAgPG5nLXRlbXBsYXRlICNzdWZmaXhCdXR0b25zIGxldC1maWVsZD5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgIDwhLS0gI3JlZ2lvbiBEZWJ1ZyB2YWx1ZSAtLT5cclxuICAgIDxjb2RlICpuZ0lmPVwiZGVidWdWYWx1ZVwiPlxyXG4gICAgICAgIDxwcmU+e3tmb3JtVmFsdWUgfCBqc29ufX08L3ByZT5cclxuICAgIDwvY29kZT5cclxuICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuPC9kaXY+Il19
447
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nkay9zcmMvbGliL2Zvcm1zL2NvbXBvbmVudHMvZ2VuZXJpYy1mb3JtL2dlbmVyaWMtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZGsvc3JjL2xpYi9mb3Jtcy9jb21wb25lbnRzL2dlbmVyaWMtZm9ybS9nZW5lcmljLWZvcm0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsU0FBUyxFQUFFLFlBQVksRUFBaUIsV0FBVyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoTCxPQUFPLEVBQWUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSXBFLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQzVHLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFHOUQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMkNBQTJDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV0Rjs7R0FFRztBQUVILE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxTQUFTO0lBQzVDLFlBQVksV0FBNkIsRUFBRSxn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aUJBQWlCLDZQQXVCZCxpQ0FBaUMsNkJDMUx0RCwrdjRCQXlSTTs7MkZEN05PLHNCQUFzQjtrQkFMbEMsU0FBUzsrQkFDSSxpQkFBaUI7OEJBU3BCLFNBQVM7c0JBRGYsS0FBSztnQkFZQyxTQUFTO3NCQURmLEtBQUs7Z0JBT0MsY0FBYztzQkFEcEIsS0FBSztnQkFPQyxXQUFXO3NCQURqQixLQUFLO2dCQU9DLFNBQVM7c0JBRGYsS0FBSztnQkFPQyxTQUFTO3NCQURmLEtBQUs7Z0JBUUMsT0FBTztzQkFEYixLQUFLO2dCQU9DLFVBQVU7c0JBRGhCLEtBQUs7Z0JBT0MsUUFBUTtzQkFEZCxLQUFLO2dCQU9DLGtCQUFrQjtzQkFEeEIsS0FBSztnQkFzQkMsY0FBYztzQkFEcEIsWUFBWTt1QkFBQyxpQkFBaUI7Z0JBT3hCLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsZUFBZTtnQkFPdEIsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxlQUFlO2dCQU90QixjQUFjO3NCQURwQixZQUFZO3VCQUFDLGlCQUFpQjtnQkFZeEIsTUFBTTtzQkFEWixZQUFZO3VCQUFDLFFBQVE7Z0JBT2YsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxjQUFjO2dCQU9yQixxQkFBcUI7c0JBRDNCLGVBQWU7dUJBQUMsaUNBQWlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ09NTUEsIEVOVEVSIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcclxuaW1wb3J0IHsgQ2RrUG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XHJcbmltcG9ydCB7IENvbXBvbmVudCwgQ29udGVudENoaWxkLCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgSW5wdXQsIE9uSW5pdCwgUXVlcnlMaXN0LCBTaW1wbGVDaGFuZ2UsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBUeXBlLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE1hdEF1dG9jb21wbGV0ZVNlbGVjdGVkRXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9hdXRvY29tcGxldGUnO1xyXG5pbXBvcnQgeyBNYXRDaGlwSW5wdXRFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NoaXBzJztcclxuaW1wb3J0IHsgTWF0Q2FsZW5kYXIsIE1hdERhdGVwaWNrZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcclxuaW1wb3J0IHsgVmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy92ZC1nZW5lcmljLWZvcm0tY3VzdG9tLWZpZWxkLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEZvcm1GaWVsZFR5cGUgfSBmcm9tICcuLi8uLi9lbnVtcy9mb3JtLWZpZWxkLXR5cGUnO1xyXG5pbXBvcnQgeyBnZXRGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBGb3JtRmllbGREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Zvcm0tZmllbGQtZGVmaW5pdGlvbic7XHJcbmltcG9ydCB7IEZvcm1GaWVsZEdyb3VwRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWZpZWxkLWdyb3VwLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBEYXRlUGlja2VySGVhZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vZGF0ZXBpY2tlci9kYXRlcGlja2VyLWhlYWRlci5jb21wb25lbnQnO1xyXG5cclxuLyoqXHJcbiAqIFZkRWRpdG9yRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtZWRpdG9yXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRFZGl0b3JEaXJlY3RpdmUgZXh0ZW5kcyBDZGtQb3J0YWwge1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBWZENvZGVEaXJlY3RpdmUgY2xhc3NcclxuICovXHJcbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1t2ZC1jb2RlXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRDb2RlRGlyZWN0aXZlIGV4dGVuZHMgQ2RrUG9ydGFsIHtcclxuICAgIGNvbnN0cnVjdG9yKHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+LCB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmKSB7XHJcbiAgICAgICAgc3VwZXIodGVtcGxhdGVSZWYsIHZpZXdDb250YWluZXJSZWYpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogVmRGaWxlRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtZmlsZV1uZy10ZW1wbGF0ZScgfSlcclxuZXhwb3J0IGNsYXNzIFZkRmlsZURpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Piwgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZikge1xyXG4gICAgICAgIHN1cGVyKHRlbXBsYXRlUmVmLCB2aWV3Q29udGFpbmVyUmVmKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFZkQ3VzdG9tRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtY3VzdG9tXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRDdXN0b21EaXJlY3RpdmUgZXh0ZW5kcyBDZGtQb3J0YWwge1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICd2ZC1nZW5lcmljLWZvcm0nLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2dlbmVyaWMtZm9ybS5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9nZW5lcmljLWZvcm0uY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVmRHZW5lcmljRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgICAvKipcclxuICAgICAqIGZvcm06IEZvcm1Hcm91cFxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGZvcm1Hcm91cD86IEZvcm1Hcm91cDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZvcm0gcmF3IHZhbHVlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgZm9ybVZhbHVlKCk6IGFueSB7IHJldHVybiB0aGlzLmZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKTsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogY2xhc3NUeXBlOiBUeXBlPGFueT5cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjbGFzc1R5cGU/OiBUeXBlPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBmb3JtRGVmaW5pdGlvbjogRm9ybURlZmluaXRpb25cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmb3JtRGVmaW5pdGlvbj86IEZvcm1EZWZpbml0aW9uO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogZmllbGRHcm91cHM6IEZvcm1GaWVsZEdyb3VwW11cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmaWVsZEdyb3Vwcz86IEZvcm1GaWVsZEdyb3VwRGVmaW5pdGlvbltdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR3JvdXAgbmFtZVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGdyb3VwTmFtZT86IHN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpZWxkIHNldCBuYW1lXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZmllbGRTZXRzPzogc3RyaW5nW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBjb250ZXh0OiBhbnlcclxuICAgICAqIFRoZSBjdXJyZW50IGNvbnRleHRcclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjb250ZXh0OiBhbnk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBkZWJ1Z1ZhbHVlOiBib29sZWFuXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZGVidWdWYWx1ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogcmVhZG9ubHk6IGJvb2xlYW5cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyByZWFkb25seT86IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBzZXBhcmF0b3JLZXlzQ29kZXM6IG51bWJlcltdXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2VwYXJhdG9yS2V5c0NvZGVzOiBudW1iZXJbXSA9IFtFTlRFUiwgQ09NTUFdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogZmllbGRSb3dzOiBGb3JtRmllbGREZWZpbml0aW9uW11bXVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmllbGRSb3dzPzogRm9ybUZpZWxkRGVmaW5pdGlvbltdW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBmaWVsZHM6IEZvcm1GaWVsZERlZmluaXRpb25bXVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmllbGRzPzogRm9ybUZpZWxkRGVmaW5pdGlvbltdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRm9ybUZpZWxkVHlwZTogdHlwZW9mIEZvcm1GaWVsZFR5cGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIEZvcm1GaWVsZFR5cGU6IHR5cGVvZiBGb3JtRmllbGRUeXBlID0gRm9ybUZpZWxkVHlwZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVkaXRvciB0ZW1wbGF0ZVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKFZkRWRpdG9yRGlyZWN0aXZlKVxyXG4gICAgcHVibGljIGVkaXRvclRlbXBsYXRlPzogVmRFZGl0b3JEaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb2RlIHRlbXBsYXRlXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoVmRDb2RlRGlyZWN0aXZlKVxyXG4gICAgcHVibGljIGNvZGVUZW1wbGF0ZT86IFZkQ29kZURpcmVjdGl2ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbGUgdGVtcGxhdGVcclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZEZpbGVEaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgZmlsZVRlbXBsYXRlPzogVmRGaWxlRGlyZWN0aXZlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3VzdG9tIHRlbXBsYXRlXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoVmRDdXN0b21EaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgY3VzdG9tVGVtcGxhdGU/OiBWZEN1c3RvbURpcmVjdGl2ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEN1c3RvbWVyIGRhdGUgaGVhZGVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkYXRlUGlja2VySGVhZGVyQ29tcG9uZW50ID0gRGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkcyBvbiB0aGUgYm90dG9tXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2JvdHRvbScpXHJcbiAgICBwdWJsaWMgYm90dG9tPzogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKCdjdXN0b21GaWVsZHMnKVxyXG4gICAgcHVibGljIGN1c3RvbUZpZWxkcz86IFRlbXBsYXRlUmVmPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZW1wbGF0ZSByZWYgZm9yIGN1c3RvbSBmaWVsZHMgb24gdGhlIGJvdHRvbVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkcmVuKFZkR2VuZXJpY0Zvcm1DdXN0b21GaWVsZERpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBjdXN0b21GaWVsZHNUZW1wbGF0ZXM/OiBRdWVyeUxpc3Q8VmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbHRlcmQgb3B0aW9ucyBmb3IgYXV0b2NvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdXRvY29tcGxldGVGaWx0ZXJlZE9wdGlvbnM6IGFueSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWxsYmFjayBtZXRob2QgdGhhdCBpcyBpbnZva2VkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZVxyXG4gICAgICogZGVmYXVsdCBjaGFuZ2UgZGV0ZWN0b3IgaGFzIGNoZWNrZWQgdGhlIGRpcmVjdGl2ZSdzXHJcbiAgICAgKiBkYXRhLWJvdW5kIHByb3BlcnRpZXMgZm9yIHRoZSBmaXJzdCB0aW1lLFxyXG4gICAgICogYW5kIGJlZm9yZSBhbnkgb2YgdGhlIHZpZXcgb3IgY29udGVudCBjaGlsZHJlbiBoYXZlIGJlZW4gY2hlY2tlZC5cclxuICAgICAqIEl0IGlzIGludm9rZWQgb25seSBvbmNlIHdoZW4gdGhlIGRpcmVjdGl2ZSBpcyBpbnN0YW50aWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgICAgIC8qIEJ1aWxkIHRoZSBmb3JtIGZpZWxkcyAqL1xyXG4gICAgICAgIGlmICh0aGlzLmNsYXNzVHlwZSAvKiYmICF0aGlzLmZpZWxkR3JvdXBzKi8pIHtcclxuICAgICAgICAgICAgdGhpcy5idWlsZEZpZWxkcygpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogR2V0IGZpbGVkIHJvd3MgKi9cclxuICAgICAgICBsZXQgZmllbGRSb3dzID0gdGhpcy5maWVsZEdyb3Vwcz8uZmlsdGVyKHggPT5cclxuICAgICAgICAgICAgeC5uYW1lPy50cmltKCkgPT0gdGhpcy5ncm91cE5hbWU/LnRyaW0oKSAmJlxyXG4gICAgICAgICAgICAheC5oaWRkZW4vKiAmJlxyXG4gICAgICAgICAgICAoIXguaGlkZSB8fCAheC5oaWRlKHRoaXMuZm9ybVZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KSkqL1xyXG4gICAgICAgIClbMF0/Lmdyb3VwcztcclxuXHJcbiAgICAgICAgaWYgKGZpZWxkUm93cykge1xyXG4gICAgICAgICAgICB0aGlzLmZpZWxkUm93cyA9IGZpZWxkUm93cy5tYXAoYSA9PiB7IHJldHVybiBbLi4uYS5tYXAoeSA9PiB7IHJldHVybiB7IC4uLnkgfSB9KV0gfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBGaWx0ZXIgYnkgZmllbGQgc2V0ICovXHJcbiAgICAgICAgaWYgKHRoaXMuZmllbGRTZXRzICYmIHRoaXMuZmllbGRSb3dzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmllbGRSb3dzID0gdGhpcy5maWVsZFJvd3MubWFwKHggPT4geCA9IHguZmlsdGVyKHkgPT4geS5maWVsZFNldHM/LnNvbWUoeiA9PiB0aGlzLmZpZWxkU2V0cz8uc29tZShhID0+IGE/LnRyaW0oKT8udG9Mb3dlckNhc2UoKSA9PSB6Py50cmltKCk/LnRvTG93ZXJDYXNlKCkpKSkpLmZpbHRlcih4ID0+IHgubGVuZ3RoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIEdldCBhbGwgZmllbGRzICovXHJcbiAgICAgICAgbGV0IGZpZWxkcyA9IHRoaXMuZmllbGRSb3dzPy5yZWR1Y2UoKGEsIGIpID0+IGEuY29uY2F0KGIpLCBbXSk7XHJcbiAgICAgICAgaWYgKGZpZWxkcykge1xyXG4gICAgICAgICAgICB0aGlzLmZpZWxkcyA9IGZpZWxkcy5tYXAoYSA9PiB7IHJldHVybiB7IC4uLmEgfSB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIFN1YnNjcmllIHRvIGNoYW5nZSBldmVudCAqL1xyXG4gICAgICAgIGZpZWxkcz8uZmlsdGVyKHkgPT4geS50eXBlICE9IEZvcm1GaWVsZFR5cGUuRmlsZSAmJiB5LmNoYW5nZSk/LmZvckVhY2goeCA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy5nZXQoeC5uYW1lID8/ICcnKT8udmFsdWVDaGFuZ2VzPy5zdWJzY3JpYmUoeSA9PiB4IS5jaGFuZ2UgJiYgeCEuY2hhbmdlKHksIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsZXQgdXBkYXRlRm9ybUZpZWxkID0gKG9yZ0ZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCB4OiBGb3JtRmllbGREZWZpbml0aW9uKSA9PiB7XHJcbiAgICAgICAgICAgIC8qIEdldCB0aGUgdHlwZSBhbmQgdGhlIGxhYmVsIG9mIHRoZSBmaWVsZCAqL1xyXG4gICAgICAgICAgICBsZXQgdHlwZSA9IG9yZ0ZpZWxkPy50eXBlO1xyXG4gICAgICAgICAgICBsZXQgbGFiZWwgPSBvcmdGaWVsZD8ubGFiZWw7XHJcbiAgICAgICAgICAgIGxldCBvcHRpb25zID0gb3JnRmllbGQ/Lm9wdGlvbnM7XHJcblxyXG4gICAgICAgICAgICAvKiBSZW5kZXIgdGhlIGZpZWxkIHR5cGUgKi9cclxuICAgICAgICAgICAgeC50eXBlID0gKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSA/IHR5cGUodGhpcy5mb3JtVmFsdWUsIHRoaXMuZm9ybUdyb3VwLCB0aGlzLmNvbnRleHQpIDogeC50eXBlO1xyXG5cclxuICAgICAgICAgICAgLyogUmVuZGVyIHRoZSBmaWVsZCBsYWJlbCAqL1xyXG4gICAgICAgICAgICB4LmxhYmVsID0gKHR5cGVvZiBsYWJlbCA9PT0gJ2Z1bmN0aW9uJykgPyBsYWJlbCh0aGlzLmZvcm1WYWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkgOiB4LmxhYmVsO1xyXG5cclxuICAgICAgICAgICAgLyogUmVuZGVyIHRoZSBmaWVsZCBvcHRpb25zICovXHJcbiAgICAgICAgICAgIHgub3B0aW9ucyA9ICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgPyBvcHRpb25zKHRoaXMuZm9ybVZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KSA6IHgub3B0aW9ucztcclxuXHJcbiAgICAgICAgICAgIC8qIEdldCB0aGUgZm9ybSBjb250cm9sICovXHJcbiAgICAgICAgICAgIGxldCBmb3JtQ29udHJvbDogRm9ybUNvbnRyb2w8YW55PiA9IDxGb3JtQ29udHJvbDxhbnk+PnRoaXMuZm9ybUdyb3VwPy5nZXQoeC5uYW1lID8/ICcnKTtcclxuXHJcbiAgICAgICAgICAgIC8qIENoZWNrIGlmIHRoZSBmaWVsZCBpcyByZXF1aXJlZCAqL1xyXG4gICAgICAgICAgICBsZXQgcmVxdWlyZWQ6IGJvb2xlYW4gfCBhbnkgPSAodHlwZW9mIHgucmVxdWlyZWQgPT09ICdmdW5jdGlvbicpID8geC5yZXF1aXJlZCh0aGlzLmZvcm1WYWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkgOiB4LnJlcXVpcmVkO1xyXG4gICAgICAgICAgICBpZiAoZm9ybUNvbnRyb2wgJiYgcmVxdWlyZWQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVkID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wuYWRkVmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wucmVtb3ZlVmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogVXBkYXRlIHNvbWUgdmFsdWVzIChsYWJlbCwgdHlwZSwgLi4uKSAqL1xyXG4gICAgICAgIGZpZWxkcz8uZm9yRWFjaCh4ID0+IHtcclxuICAgICAgICAgICAgdmFyIG9yZ0ZpZWxkID0gdGhpcy5maWVsZHM/LmZpbHRlcih5ID0+IHkubmFtZSA9PSB4Lm5hbWUpWzBdO1xyXG4gICAgICAgICAgICBpZiAob3JnRmllbGQpIHtcclxuICAgICAgICAgICAgICAgIHVwZGF0ZUZvcm1GaWVsZChvcmdGaWVsZCwgeCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1Hcm91cD8udmFsdWVDaGFuZ2VzPy5zdWJzY3JpYmUoeSA9PiB1cGRhdGVGb3JtRmllbGQob3JnRmllbGQhLCB4KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhhbmRsZXMgYXV0b2NvbXBsZXRlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmaWx0ZXJBdXRvY29tcGxldGUoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZmllbGQubmFtZSkge1xyXG4gICAgICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZUZpbHRlcmVkT3B0aW9uc1tmaWVsZC5uYW1lXSA9ICg8eyBpZDogYW55LCBuYW1lOiBzdHJpbmcgfVtdPmZpZWxkLm9wdGlvbnMpXHJcbiAgICAgICAgICAgICAgICA/LmZpbHRlcihvcHRpb24gPT4gb3B0aW9uLm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhldmVudC52YWx1ZT8udG9TdHJpbmcoKT8udG9Mb3dlckNhc2UoKSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBjaGlwIHdoZW4gYSBhdXRvY29tcGxldGUgdmFsdWUgaXMgc2VsZWN0ZWRcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSBldmVudCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGF1dG9jb21wbGV0ZVZhbHVlU2VsZWN0ZWQoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGV2ZW50OiBNYXRBdXRvY29tcGxldGVTZWxlY3RlZEV2ZW50LCBjaGlwSW5wdXRFdmVudDogYW55KTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fYWRkQ2hpcChmaWVsZCwgZXZlbnQub3B0aW9uLnZpZXdWYWx1ZSk7XHJcbiAgICAgICAgY2hpcElucHV0RXZlbnQudmFsdWUgPSAnJztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBjaGlwXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGRDaGlwKGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBldmVudDogTWF0Q2hpcElucHV0RXZlbnQpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9hZGRDaGlwKGZpZWxkLCBldmVudC52YWx1ZSk7XHJcbiAgICAgICAgZXZlbnQuY2hpcElucHV0IS5jbGVhcigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBhIGNoaXBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSBjaGlwIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVtb3ZlQ2hpcChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgY2hpcDogYW55KTogdm9pZCB7XHJcbiAgICAgICAgLyogR2V0IHRoZSBmb3JtIGNvbnRyb2wgdXNpbmcgdGhlIGZpZWxkIG5hbWUgKi9cclxuICAgICAgICBsZXQgY29udHJvbCA9IHRoaXMuZm9ybUdyb3VwPy5jb250cm9sc1tmaWVsZC5uYW1lID8/ICcnXTtcclxuXHJcbiAgICAgICAgLyogR2V0IHRoZSBpbmRleCBvZiB0aGUgY2hpcCAqL1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gY29udHJvbD8udmFsdWUuaW5kZXhPZihjaGlwKTtcclxuICAgICAgICBpZiAoY29udHJvbCAmJiBpbmRleCA+PSAwKSB7XHJcbiAgICAgICAgICAgIGNvbnRyb2wudmFsdWUuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cD8udXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBjaGlwXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2FkZENoaXAoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICAvKiBHZXQgdGhlIGZvcm0gY29udHJvbCB1c2luZyB0aGUgZmllbGQgbmFtZSAqL1xyXG4gICAgICAgIGxldCBjb250cm9sID0gdGhpcy5mb3JtR3JvdXA/LmNvbnRyb2xzW2ZpZWxkLm5hbWUgPz8gJyddO1xyXG5cclxuICAgICAgICAvKiBHZXQgdGhlIHZhbHVlIG9mIHRoZSBjaGlwICovXHJcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfHwgJycpLnRyaW0oKTtcclxuICAgICAgICBpZiAoY29udHJvbCAmJiB2YWx1ZSkge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGZpZWxkLmlucHV0VHlwZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnbnVtYmVyJzpcclxuICAgICAgICAgICAgICAgICAgICBsZXQgbnVtYmVyID0gcGFyc2VJbnQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChudW1iZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC52YWx1ZS5wdXNoKG51bWJlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Zsb2F0JzpcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZmxvYXQgPSBwYXJzZUZsb2F0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmxvYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC52YWx1ZS5wdXNoKGZsb2F0KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2godmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICAgICAgdGhpcy5mb3JtR3JvdXA/Lm1hcmtBc0RpcnR5KCk7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyBkYXRlIHBpY2tlciBvcGVuZWQgZXZlbnRcclxuICAgICAqIEBwYXJhbSBkYXRlUGlja2VyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlRGF0ZVBpY2tlck9wZW5lZChkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlUGlja2VyT3BlbmVkKSB7XHJcbiAgICAgICAgICAgIGZpZWxkLmRhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGRhdGUgZmlsdGVyIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0gZGF0ZVBpY2tlciBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGhhbmRsZURhdGVQaWNrZXJGaWx0ZXJBc3luYyhkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBkYXRlOiBEYXRlIHwgYW55KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlRmlsdGVyQXN5bmMpIHtcclxuICAgICAgICAgICAgLyogRGlzYWJsZXMgYWxsIGRhdGVzICovXHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIuZGF0ZXBpY2tlcklucHV0LmRhdGVGaWx0ZXIgPSAoZDogRGF0ZSkgPT4gZmFsc2U7XHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICBmaWVsZC5kYXRlRmlsdGVyQXN5bmMoZGF0ZSwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KS5zdWJzY3JpYmUoeCA9PiB7XHJcbiAgICAgICAgICAgICAgICBkYXRlUGlja2VyLmRhdGVwaWNrZXJJbnB1dC5kYXRlRmlsdGVyID0gKGQ6IERhdGUpID0+IGQgJiYgeChkKTtcclxuICAgICAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGNhbGVuZGFyIGZpbHRlciBldmVudFxyXG4gICAgICogQHBhcmFtIGNhbGVuZGFyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlQ2FsZW5kYXJGaWx0ZXJBc3luYyhjYWxlbmRhcjogTWF0Q2FsZW5kYXI8YW55PiwgZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGRhdGU6IERhdGUgfCBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZmllbGQ/LmRhdGVGaWx0ZXJBc3luYykge1xyXG4gICAgICAgICAgICAvKiBEaXNhYmxlcyBhbGwgZGF0ZXMgKi9cclxuICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBmYWxzZTtcclxuICAgICAgICAgICAgY2FsZW5kYXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICB2YXIgc3Vic2NyaXB0aW9uID0gZmllbGQuZGF0ZUZpbHRlckFzeW5jKGRhdGUsIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkuc3Vic2NyaWJlKHggPT4ge1xyXG4gICAgICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBkICYmIHgoZCk7XHJcbiAgICAgICAgICAgICAgICBjYWxlbmRhci5uZ09uQ2hhbmdlcyg8U2ltcGxlQ2hhbmdlcz57ICdkYXRlRmlsdGVyJzogbmV3IFNpbXBsZUNoYW5nZShcIlwiLCBcIlwiLCBmYWxzZSkgfSk7XHJcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQnVpbGRzIHRoZSBmb3JtIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYnVpbGRGaWVsZHMoKTogdm9pZCB7XHJcbiAgICAgICAgLyogQ2hlY2sgaWYgY2xhc3NUeXBlIGlzIG5vdCBkZWZpbmVkICovXHJcbiAgICAgICAgaWYgKCF0aGlzLmNsYXNzVHlwZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2xhc3NUeXBlLiBQbGVhc2UgZW5zdXJlIGNsYXNzVHlwZSBpcyBkZWZpbmVkLCBub3QgbnVsbCwgYW5kIGlzIGEgY29uc3RydWN0b3IgZnVuY3Rpb24uJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBHZXQgZm9ybSBkZWZpbml0aW9uICovXHJcbiAgICAgICAgdGhpcy5mb3JtRGVmaW5pdGlvbiA9IGdldEZvcm1EZWZpbml0aW9uKG5ldyB0aGlzLmNsYXNzVHlwZSgpKTtcclxuXHJcbiAgICAgICAgLyogQ3JlYXRlIHRoZSBmcm9tIGZpZWxkcyB1c2luZyB0aGUgZW50aXR5IHR5cGUgKi9cclxuICAgICAgICB0aGlzLmZpZWxkR3JvdXBzID0gdGhpcy5mb3JtRGVmaW5pdGlvbj8uZmllbGRHcm91cHM/LmZpbHRlcih4ID0+ICF4LmhpZGRlbik/Lm1hcChhID0+IHsgcmV0dXJuIHsgLi4uYSB9IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9nIHRvIGNvbnNvbGVcclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFxyXG4gICAgICogQHBhcmFtIG9wdGlvbmFsUGFyYW1zIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9nKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2cobWVzc2FnZSwgb3B0aW9uYWxQYXJhbXMpO1xyXG4gICAgfVxyXG59IiwiPGRpdiAqbmdJZj1cImZvcm1Hcm91cCAmJiBmaWVsZFJvd3NcIiBbZm9ybUdyb3VwXT1cImZvcm1Hcm91cFwiPlxyXG4gICAgPCEtLSAjcmVnaW9uIEZpZWxkcyAtLT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkcyBvZiBmaWVsZFJvd3M7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICA8ZGl2IGxheW91dC1ndC1zbT1cInJvd1wiIGxheW91dD1cImNvbHVtblwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmaWVsZHNcIiBbbmdTd2l0Y2hdPVwiZmllbGQudHlwZVwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmaWVsZC5oaWRkZW4gJiYgIShmaWVsZC5oaWRlICYmIGZpZWxkLmhpZGUoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWVsZC53cmFwcGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZXh0IGlucHV0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVGV4dFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cImZpZWxkLmlucHV0VHlwZSA/PyAndGV4dCdcIiBbbWlubGVuZ3RoXT1cImZpZWxkLm1pbkxlbmd0aHx8bnVsbFwiIFttYXhsZW5ndGhdPVwiZmllbGQubWF4TGVuZ3RofHxudWxsXCIgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiIG1hdElucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIiBbcGF0dGVybl09XCIoZmllbGQucGF0dGVybj8/JycpXCIgW29ubHlOdW1iZXJdPVwiKGZpZWxkLm51bWJlcnNPbmx5Pz9mYWxzZSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KCRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSkpWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZXh0YXJlYSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlRleHRBcmVhXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGV4dGFyZWEgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIHJvd3M9XCJmaWVsZC5yb3dzfHwyXCIgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCI+PC90ZXh0YXJlYT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBFbnVtIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuRW51bVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHZkLXNlbGVjdCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW2VudW1dPVwiZmllbGQuZW51bVR5cGVcIiBbZW51bUZpbHRlcl09XCJmaWVsZC5lbnVtRmlsdGVyIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbb3B0aW9uVmFsdWVQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25WYWx1ZVByb3BlcnR5XCIgW29wdGlvblRleHRQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25UZXh0UHJvcGVydHlcIiBbZGVmYXVsdE9wdGlvbl09XCJmaWVsZC5kZWZhdWx0T3B0aW9uPz90cnVlXCIgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCIgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCIgW3RyaWdnZXJDc3NDbGFzc109XCJmaWVsZC50cmlnZ2VyQ3NzQ2xhc3NcIiBbdHJpZ2dlck1vZGVdPVwiZmllbGQudHJpZ2dlck1vZGVcIiBsYXlvdXQ9XCJyb3dcIiBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3QtdHJpZ2dlciBsZXQtdHJpZ2dlcj1cInRyaWdnZXJcIiAqbmdJZj1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZSh0cmlnZ2VyLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LW9wdGlvbiBsZXQtb3B0aW9uPVwib3B0aW9uXCIgKm5nSWY9XCJmaWVsZC5vcHRpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbb3V0ZXJIVE1MXT1cImZpZWxkLm9wdGlvblRlbXBsYXRlKG9wdGlvbiwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3ZkLXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZFNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlZkU2VsZWN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbZW5kcG9pbnRdPVwiZmllbGQuZW5kcG9pbnQ/PycnIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbcGFyYW1zXT1cImZpZWxkLnBhcmFtcz8/e30gfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIiBbbWFwcGVyXT1cImZpZWxkLm1hcHBlclwiIFtjb21wYXJlV2l0aF09XCJmaWVsZC5jb21wYXJlV2l0aFwiIFtsb2FkRGF0YV09XCJmaWVsZC5mZXRjaENvbmRpdGlvbiB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW29wdGlvblZhbHVlUHJvcGVydHldPVwiZmllbGQub3B0aW9uVmFsdWVQcm9wZXJ0eVwiIFtvcHRpb25UZXh0UHJvcGVydHldPVwiZmllbGQub3B0aW9uVGV4dFByb3BlcnR5XCIgW2RlZmF1bHRPcHRpb25dPVwiZmllbGQuZGVmYXVsdE9wdGlvbj8/dHJ1ZVwiIFttYXRJY29uS2V5XT1cImZpZWxkLm9wdGlvbk1hdEljb25Qcm9wZXJ0eVwiIFtzdmdJY29uS2V5XT1cImZpZWxkLm9wdGlvblN2Z0ljb25Qcm9wZXJ0eVwiIFtmb250U2V0XT1cImZpZWxkLm9wdGlvbkljb25Gb250U2V0XCIgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCIgW3NlbGVjdEZpcnN0XT1cImZpZWxkLnNlbGVjdEZpcnN0XCIgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCIgW3RyaWdnZXJDc3NDbGFzc109XCJmaWVsZC50cmlnZ2VyQ3NzQ2xhc3NcIiBbdHJpZ2dlck1vZGVdPVwiZmllbGQudHJpZ2dlck1vZGVcIiAoaXRlbVNlbGVjdGVkKT1cImZpZWxkLml0ZW1TZWxlY3QgJiYgZmllbGQuaXRlbVNlbGVjdCgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiAoaXRlbUNoYW5nZSk9XCJmaWVsZC5pdGVtQ2hhbmdlICYmIGZpZWxkLml0ZW1DaGFuZ2UoJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgbGF5b3V0PVwicm93XCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LXRyaWdnZXIgbGV0LXRyaWdnZXI9XCJ0cmlnZ2VyXCIgKm5nSWY9XCJmaWVsZC50cmlnZ2VyVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySFRNTF09XCJmaWVsZC50cmlnZ2VyVGVtcGxhdGUodHJpZ2dlciwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC10cmlnZ2VyIGxldC10cmlnZ2VyPVwidHJpZ2dlclwiICpuZ0lmPVwiZmllbGQudHJpZ2dlck1hcHBlciAmJiBmaWVsZC5tdWx0aXBsZSAmJiBmaWVsZC50cmlnZ2VyTW9kZSA9PSAnY2hpcCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nRm9yPVwibGV0IGl0ZW0gb2YgdHJpZ2dlclwiIGNsYXNzPVwibWF0LW1kYy1jaGlwIG1hdC1tZGMtc3RhbmRhcmQtY2hpcCBtYXQtcHJpbWFyeSBtYXQtbWRjLWNoaXAtc2VsZWN0ZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtpbm5lckhUTUxdPVwiZmllbGQudHJpZ2dlck1hcHBlcihpdGVtLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3Qtb3B0aW9uIGxldC1vcHRpb249XCJvcHRpb25cIiAqbmdJZj1cImZpZWxkLm9wdGlvblRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtvdXRlckhUTUxdPVwiZmllbGQub3B0aW9uVGVtcGxhdGUob3B0aW9uLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFZkTGlzdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlZkTGlzdFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGZsb2F0TGFiZWw9XCJhbHdheXNcIiBjbGFzcz1cImZvcm0tZmllbGQtdHlwZS1saXN0XCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtbGlzdCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW2VuZHBvaW50XT1cImZpZWxkLmVuZHBvaW50Pz8nJyB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgPz97fSB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW3Byb2plY3Rpb25dPVwiZmllbGQucHJvamVjdGlvblwiIFttYXBwZXJdPVwiZmllbGQubWFwcGVyXCIgW2NvbXBhcmVXaXRoXT1cImZpZWxkLmNvbXBhcmVXaXRoXCIgW2xvYWREYXRhXT1cImZpZWxkLmZldGNoQ29uZGl0aW9uIHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbb3B0aW9uVmFsdWVQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25WYWx1ZVByb3BlcnR5XCIgW29wdGlvblRleHRQcm9wZXJ0eV09XCJmaWVsZC5vcHRpb25UZXh0UHJvcGVydHlcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIiAoaXRlbVNlbGVjdGVkKT1cImZpZWxkLml0ZW1TZWxlY3QgJiYgZmllbGQuaXRlbVNlbGVjdCgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiAoaXRlbUNoYW5nZSk9XCJmaWVsZC5pdGVtQ2hhbmdlICYmIGZpZWxkLml0ZW1DaGFuZ2UoJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgW3N0eWxlLm1heC13aWR0aF09XCJmaWVsZC5tYXhXaWR0aFwiIFtzdHlsZS5tYXgtaGVpZ2h0XT1cImZpZWxkLm1heEhlaWdodFwiIGZsZXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLWxpc3Qtb3B0aW9uIGxldC1vcHRpb249XCJvcHRpb25cIiAqbmdJZj1cImZpZWxkLm9wdGlvblRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtvdXRlckhUTUxdPVwiZmllbGQub3B0aW9uVGVtcGxhdGUob3B0aW9uLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtbGlzdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gQ2hpcHMgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5DaGlwc1wiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGlwLWdyaWQgI2NoaXBMaXN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbZGlzYWJsZUNvbnRyb2xdPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoaXAtcm93ICpuZ0Zvcj1cImxldCBjaGlwIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSk/LnZhbHVlXCIgKHJlbW92ZWQpPVwicmVtb3ZlQ2hpcChmaWVsZCwgY2hpcClcIiBjb2xvcj1cInByaW1hcnlcIiBzZWxlY3RhYmxlPVwidHJ1ZVwiIHNlbGVjdGVkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57e2NoaXB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXRDaGlwUmVtb3ZlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+Y2FuY2VsPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hpcC1yb3c+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFtwbGFjZWhvbGRlcl09XCIkYW55KGZpZWxkLmxhYmVsKVwiICNjaGlwSW5wdXQgW21hdENoaXBJbnB1dEZvcl09XCJjaGlwTGlzdFwiIFttYXRDaGlwSW5wdXRTZXBhcmF0b3JLZXlDb2Rlc109XCJzZXBhcmF0b3JLZXlzQ29kZXNcIiBbbWF0QXV0b2NvbXBsZXRlXT1cImNoaXBBdXRvY29tcGxldGVcIiAoaW5wdXQpPVwiZmlsdGVyQXV0b2NvbXBsZXRlKGZpZWxkLCBjaGlwSW5wdXQpXCIgKG1hdENoaXBJbnB1dFRva2VuRW5kKT1cImFkZENoaXAoZmllbGQsICRldmVudClcIiBhdXRvY29tcGxldGU9XCJvZmZcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoaXAtZ3JpZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtYXV0b2NvbXBsZXRlIGF1dG9BY3RpdmVGaXJzdE9wdGlvbiAjY2hpcEF1dG9jb21wbGV0ZT1cIm1hdEF1dG9jb21wbGV0ZVwiIFtjbGFzc109XCJmaWVsZC5hdXRvY29tcGxldGVDc3NDbGFzc1wiIChvcHRpb25TZWxlY3RlZCk9XCJhdXRvY29tcGxldGVWYWx1ZVNlbGVjdGVkKGZpZWxkLCAkZXZlbnQsIGNoaXBJbnB1dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGF1dG9jb21wbGV0ZUZpbHRlcmVkT3B0aW9uc1tmaWVsZC5uYW1lIV1cIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9uLm5hbWV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZENoaXBzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVmRDaGlwc1wiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHZkLWNoaXBzICN2ZENoaXAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFtlbmRwb2ludF09XCJmaWVsZC5lbmRwb2ludD8/JycgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtwYXJhbXNdPVwiZmllbGQucGFyYW1zIHx8IHt9IHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbc2VhcmNoRmllbGRdPVwiZmllbGQuc2VhcmNoRmllbGRcIiBbY2xhc3NUeXBlXT1cImZpZWxkLmNsYXNzVHlwZVwiIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIiBba2V5XT1cImZpZWxkLm9wdGlvblZhbHVlUHJvcGVydHlcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIiBbcmVtb3ZhYmxlXT1cIiFmaWVsZC5jbGVhclwiIFtjb250ZXh0XT1cImNvbnRleHRcIiBbc3VmZml4QnV0dG9uc109XCJmaWVsZC5zdWZmaXhCdXR0b25zXCIgW2F1dG9jb21wbGV0ZUNzc0NsYXNzXT1cImZpZWxkLmF1dG9jb21wbGV0ZUNzc0NsYXNzXCIgKGluaXRTZWxlY3QpPVwiZmllbGQuaXRlbVNlbGVjdCAmJiBmaWVsZC5pdGVtU2VsZWN0KCRldmVudCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpO1wiIChzZWxlY3RlZCk9XCJmaWVsZC5pdGVtQ2hhbmdlICYmIGZpZWxkLml0ZW1DaGFuZ2UoJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgKGNsZWFyZWQpPVwiZmllbGQuY2xlYXIgJiYgZmllbGQuY2xlYXIoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpO1wiIFtjdXN0b21WYWx1ZV09XCJmaWVsZC5jdXN0b21WYWx1ZVwiIGxheW91dD1cInJvd1wiIGZsZXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLWNoaXAgbGV0LWNoaXA9XCJjaGlwXCIgKm5nSWY9XCJmaWVsZC5jaGlwVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbb3V0ZXJIVE1MXT1cImZpZWxkLmNoaXBUZW1wbGF0ZShjaGlwLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1hdXRvY29tcGxldGUtb3B0aW9uIGxldC1vcHRpb249XCJvcHRpb25cIiAqbmdJZj1cImZpZWxkLmF1dG9jb21wbGV0ZVRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW291dGVySFRNTF09XCJmaWVsZC5hdXRvY29tcGxldGVUZW1wbGF0ZShvcHRpb24sIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3ZkLWNoaXBzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cInZkQ2hpcC5lbXB0eVJlc3VsdFwiIGNsYXNzPVwidGMtcmVkLTQwMFwiIGkxOG49XCJAQG5vUmVzdWx0c0ZvdW5kXCI+Tm8gcmVzdWx0cyB3ZXJlIGZvdW5kLjwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gU2VsZWN0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuU2VsZWN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCIgW2Rpc2FibGVDb250cm9sXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mICRhbnkoZmllbGQub3B0aW9ucylcIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+e3tvcHRpb24ubmFtZX19PC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIEF1dG9jb21wbGV0ZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkF1dG9jb21wbGV0ZVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFttaW5dPVwiZmllbGQubWluXCIgW21heF09XCJmaWVsZC5tYXhcIiBbbWF0QXV0b2NvbXBsZXRlXT1cImF1dG9cIiAjYXV0b2NvbXBsZXRlSW5wdXQgKGlucHV0KT1cImZpbHRlckF1dG9jb21wbGV0ZShmaWVsZCwgYXV0b2NvbXBsZXRlSW5wdXQpXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW3JlYWRvbmx5XT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWF1dG9jb21wbGV0ZSBhdXRvQWN0aXZlRmlyc3RPcHRpb24gI2F1dG89XCJtYXRBdXRvY29tcGxldGVcIiBbY2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGF1dG9jb21wbGV0ZUZpbHRlcmVkT3B0aW9uc1tmaWVsZC5uYW1lIV1cIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9uLm5hbWV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGZvbnRTZXQ9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBEYXRlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuRGF0ZVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbbWluXT1cImZpZWxkLm1pblwiIFttYXhdPVwiZmllbGQubWF4XCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW21hdERhdGVwaWNrZXJdPVwiZGF0ZVBpY2tlclwiIFttYXREYXRlcGlja2VyRmlsdGVyXT1cImZpZWxkLmRhdGVGaWx0ZXJcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgZmllbGQuZm9yY2VTZWxlY3QgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZGF0ZXBpY2tlci10b2dnbGUgbWF0U3VmZml4IFtmb3JdPVwiZGF0ZVBpY2tlclwiPjwvbWF0LWRhdGVwaWNrZXItdG9nZ2xlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlcGlja2VyICNkYXRlUGlja2VyIFtkaXNhYmxlZF09XCIocmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSkpPz9mYWxzZVwiIChtb250aFNlbGVjdGVkKT1cImhhbmRsZURhdGVQaWNrZXJGaWx0ZXJBc3luYyhkYXRlUGlja2VyLCBmaWVsZCwgJGV2ZW50IClcIiAob3BlbmVkKT1cImhhbmRsZURhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgZmllbGQpXCIgW2NhbGVuZGFySGVhZGVyQ29tcG9uZW50XT1cImRhdGVQaWNrZXJIZWFkZXJDb21wb25lbnRcIj48L21hdC1kYXRlcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDYWxlbmRhciAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkNhbGVuZGFyXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgZmxvYXRMYWJlbD1cImFsd2F5c1wiIGNsYXNzPVwiZm9ybS1maWVsZC10eXBlLWNhbGVuZGFyXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaW5wdXQ9XCJoaWRkZW5cIiBoaWRkZW4gbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jYWxlbmRhciAjY2FsZW5kYXIgW3NlbGVjdGVkXT1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSEpPy52YWx1ZVwiIChzZWxlY3RlZENoYW5nZSk9XCJmb3JtR3JvdXAuZ2V0KGZpZWxkLm5hbWUhKT8uc2V0VmFsdWUoJGV2ZW50KTtcIiAobW9udGhTZWxlY3RlZCk9XCJoYW5kbGVDYWxlbmRhckZpbHRlckFzeW5jKGNhbGVuZGFyLCBmaWVsZCwgJGV2ZW50IClcIiBbaGVhZGVyQ29tcG9uZW50XT1cImRhdGVQaWNrZXJIZWFkZXJDb21wb25lbnRcIiBzdHlsZT1cIndpZHRoOiAxMDAlO1wiPjwvbWF0LWNhbGVuZGFyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWUhXSlbJ2Vycm9yTWVzc2FnZXMnXVwiIGxheW91dC1tYXJnaW4+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gQ29sb3IgaW5wdXQgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5Db2xvclwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cImZpZWxkLmlucHV0VHlwZSA/PyAndGV4dCdcIiBbbWlubGVuZ3RoXT1cImZpZWxkLm1pbkxlbmd0aHx8bnVsbFwiIFttYXhsZW5ndGhdPVwiZmllbGQubWF4TGVuZ3RofHxudWxsXCIgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiIG1hdElucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZSFcIiBbcmVhZG9ubHldPVwiKHJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpKT8/ZmFsc2VcIiBbcGF0dGVybl09XCIoZmllbGQucGF0dGVybj8/JycpXCIgW29ubHlOdW1iZXJdPVwiKGZpZWxkLm51bWJlcnNPbmx5Pz9mYWxzZSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZ3gtY29sb3JzIG1hdFN1ZmZpeCBuZ3gtY29sb3JzLXRyaWdnZXIgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lIVwiIFtoaWRlVGV4dElucHV0XT1cInRydWVcIiAoY2xvc2UpPVwidGhpcy5mb3JtR3JvdXAuZ2V0KGZpZWxkLm5hbWUhKT8uc2V0VmFsdWUoJGV2ZW50KVwiIGZvcm1hdD1cImhleFwiIGNsYXNzPVwiY29sb3ItcGlja2VyXCI+PC9uZ3gtY29sb3JzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mICRhbnkoJGFueShmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZSFdKSlbJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gQ2hlY2tib3ggLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5DaGVja2JveFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIGNsYXNzPVwibWF0LWNoZWNrYm94LXdyYXBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgW2Rpc2FibGVDb250cm9sXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCI+e3tmaWVsZC5sYWJlbH19PC9tYXQtY2hlY2tib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiAkYW55KGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lIV0pWydlcnJvck1lc3NhZ2VzJ11cIiBsYXlvdXQtbWFyZ2luPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBFZGl0b3IgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5FZGl0b3JcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiZWRpdG9yVGVtcGxhdGU/LnRlbXBsYXRlUmVmIVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImVkaXRvclRlbXBsYXRlPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBmaWVsZDogZmllbGQsIGZvcm1Hcm91cDogZm9ybUdyb3VwIH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENvZGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5Db2RlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImNvZGVUZW1wbGF0ZT8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29kZVRlbXBsYXRlPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBmaWVsZDogZmllbGQsIGZvcm1Hcm91cDogZm9ybUdyb3VwIH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIEZpbGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5GaWxlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgdmQtZmlsZS1pbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWUhXCIgKHNlbGVjdCk9XCJmaWVsZC5jaGFuZ2UgJiYgZmllbGQuY2hhbmdlKGZpZWxkLCAkZXZlbnQsIGZvcm1Hcm91cCwgY29udGV4dClcIiBbYWNjZXB0XT1cImZpZWxkLmZpbGVFeHRlbnNpb25zXCIgW2Rpc2FibGVDb250cm9sXT1cIihyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKSk/P2ZhbHNlXCIgZmxleD48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDdXN0b20gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5DdXN0b21cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiY3VzdG9tVGVtcGxhdGU/LnRlbXBsYXRlUmVmIVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbVRlbXBsYXRlPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBmaWVsZDogZmllbGQsIGZvcm1Hcm91cDogZm9ybUdyb3VwIH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZW1wbGF0ZSBmb3IgY3VzdG9tIGZpZWxkcyAtLT5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY3VzdG9tRmllbGQgb2YgY3VzdG9tRmllbGRzVGVtcGxhdGVzXCI+XHJcbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJjdXN0b21GaWVsZD8udGVtcGxhdGVSZWYgJiYgY3VzdG9tRmllbGQucm93ID09IGZpZWxkc1swXT8ucm93ICYmIGN1c3RvbUZpZWxkLmlubGluZVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZiFcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2Zvcm1Hcm91cDogZm9ybUdyb3VwfVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDwhLS0gI3JlZ2lvbiBUZW1wbGF0ZSBmb3IgY3VzdG9tIGZpZWxkcyAtLT5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY3VzdG9tRmllbGRzXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tRmllbGRzXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntmb3JtR3JvdXA6IGZvcm1Hcm91cCwgcm93OiBmaWVsZHNbMF0ucm93fVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGN1c3RvbUZpZWxkIG9mIGN1c3RvbUZpZWxkc1RlbXBsYXRlc1wiPlxyXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJjdXN0b21GaWVsZD8udGVtcGxhdGVSZWYgJiYgY3VzdG9tRmllbGQucm93ID09ICgoZmllbGRzWzBdPy5yb3c/PzApKzEpICYmICFjdXN0b21GaWVsZC5pbmxpbmVcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJjdXN0b21GaWVsZD8udGVtcGxhdGVSZWYhXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntmb3JtR3JvdXA6IGZvcm1Hcm91cH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgIDwhLS0gI3JlZ2lvbiBGb3JtIGJvdHRvbSAtLT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJib3R0b21cIiBbbmdUZW1wbGF0ZU91dGxldF09XCJib3R0b21cIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2Zvcm1Hcm91cDogZm9ybUdyb3VwfVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgIDwhLS0gI3JlZ2lvbiBUZW1wbGF0ZSBmb3Igc3VmZml4IGJ1dHRvbnMgLS0+XHJcbiAgICA8bmctdGVtcGxhdGUgI3N1ZmZpeEJ1dHRvbnMgbGV0LWZpZWxkPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1WYWx1ZSwgY29udGV4dClcIiAoY2xpY2spPVwic3VmZml4QnV0dG9uLmV2ZW50ICYmIHN1ZmZpeEJ1dHRvbi5ldmVudChmb3JtVmFsdWUsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICA8bWF0LWljb24gZm9udFNldD1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgPCEtLSAjcmVnaW9uIERlYnVnIHZhbHVlIC0tPlxyXG4gICAgPGNvZGUgKm5nSWY9XCJkZWJ1Z1ZhbHVlXCI+XHJcbiAgICAgICAgPHByZT57e2Zvcm1WYWx1ZSB8IGpzb259fTwvcHJlPlxyXG4gICAgPC9jb2RlPlxyXG4gICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG48L2Rpdj4iXX0=