@messaia/cdk 15.0.0-rc72 → 15.0.0-rc74
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.
- package/esm2020/lib/forms/components/generic-form/generic-form.component.mjs +28 -4
- package/esm2020/lib/forms/functions/decorators.mjs +2 -2
- package/esm2020/lib/forms/models/form-field-definition.mjs +1 -1
- package/fesm2015/messaia-cdk.mjs +30 -5
- package/fesm2015/messaia-cdk.mjs.map +1 -1
- package/fesm2020/messaia-cdk.mjs +28 -4
- package/fesm2020/messaia-cdk.mjs.map +1 -1
- package/lib/forms/components/generic-form/generic-form.component.d.ts +9 -1
- package/lib/forms/models/form-field-definition.d.ts +10 -10
- package/package.json +1 -1
|
@@ -113,6 +113,10 @@ export class VdGenericFormComponent {
|
|
|
113
113
|
*/
|
|
114
114
|
this.autocompleteFilteredOptions = {};
|
|
115
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Form raw value
|
|
118
|
+
*/
|
|
119
|
+
get formValue() { return this.formGroup?.getRawValue(); }
|
|
116
120
|
/**
|
|
117
121
|
* A callback method that is invoked immediately after the
|
|
118
122
|
* default change detector has checked the directive's
|
|
@@ -131,10 +135,30 @@ export class VdGenericFormComponent {
|
|
|
131
135
|
if (this.fieldSets) {
|
|
132
136
|
this.fieldRows = this.fieldRows.map(x => x = x.filter(y => y.fieldSets?.some(z => this.fieldSets?.some(a => a?.trim()?.toLowerCase() == z?.trim()?.toLowerCase())))).filter(x => x.length);
|
|
133
137
|
}
|
|
138
|
+
/* Get all fields */
|
|
139
|
+
let fields = this.fieldRows?.reduce((a, b) => a.concat(b), []);
|
|
140
|
+
this.fields = [...fields];
|
|
134
141
|
/* Subscrie to change event */
|
|
135
|
-
|
|
142
|
+
fields?.filter(y => y.type != FormFieldType.File && y.change)?.forEach(x => {
|
|
136
143
|
this.formGroup?.get(x.name)?.valueChanges?.subscribe(y => x.change(y, this.formGroup?.value, this.formGroup, this.context));
|
|
137
144
|
});
|
|
145
|
+
/* Update some values (label, type, ...) */
|
|
146
|
+
fields.forEach(x => {
|
|
147
|
+
var orgField = this.fields.filter(y => y.name == x.name)[0];
|
|
148
|
+
/* Get the type and the label of the field */
|
|
149
|
+
let type = orgField?.type;
|
|
150
|
+
let label = orgField?.label;
|
|
151
|
+
/* Render the field type */
|
|
152
|
+
x.type = (typeof type === 'function') ? type(this.formValue, this.formGroup, this.context) : x.type;
|
|
153
|
+
/* Render the field label */
|
|
154
|
+
x.label = (typeof label === 'function') ? label(this.formValue, this.formGroup, this.context) : x.label;
|
|
155
|
+
this.formGroup?.valueChanges?.subscribe(y => {
|
|
156
|
+
/* Render the field type */
|
|
157
|
+
x.type = (typeof type === 'function') ? type(y, this.formGroup, this.context) : x.type;
|
|
158
|
+
/* Render the field label */
|
|
159
|
+
x.label = (typeof label === 'function') ? label(y, this.formGroup, this.context) : x.label;
|
|
160
|
+
});
|
|
161
|
+
});
|
|
138
162
|
}
|
|
139
163
|
/**
|
|
140
164
|
* Handles autocomplete event
|
|
@@ -276,10 +300,10 @@ export class VdGenericFormComponent {
|
|
|
276
300
|
}
|
|
277
301
|
}
|
|
278
302
|
/** @nocollapse */ VdGenericFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: VdGenericFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
279
|
-
/** @nocollapse */ VdGenericFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", 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.hide || !field.hide(formGroup?.getRawValue(), 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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <textarea matInput [formControlName]=\"field.name\" rows=\"field.rows||2\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-select [formControlName]=\"field.name\" [enum]=\"field.enumType\" [enumFilter]=\"field.enumFilter | func:formGroup?.getRawValue():formGroup:context\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" [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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-select [formControlName]=\"field.name\" [endpoint]=\"field.endpoint | func:formGroup?.getRawValue():formGroup:context\" [params]=\"field.params | func:formGroup?.getRawValue():formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formGroup?.getRawValue():formGroup:context\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formGroup?.getRawValue(), formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-list [formControlName]=\"field.name\" [endpoint]=\"field.endpoint | func:formGroup?.getRawValue():formGroup:context\" [params]=\"field.params | func:formGroup?.getRawValue():formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formGroup?.getRawValue():formGroup:context\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formGroup?.getRawValue(), formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name\" [disableControl]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\">\r\n <mat-chip-row *ngFor=\"let chip of 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>cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"field.header | func:formGroup?.getRawValue():formGroup:context\" #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\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-chips #vdChip [formControlName]=\"field.name\" [endpoint]=\"field.endpoint | func:formGroup?.getRawValue():formGroup:context\" [params]=\"field.params | func:formGroup?.getRawValue():formGroup:context\" [searchField]=\"field.searchField\" [classType]=\"field.classType\" [projection]=\"field.projection\" [key]=\"field.optionValue\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" [removable]=\"!field.clear\" [context]=\"context\" [suffixButtons]=\"field.suffixButtons\" [autocompleteCssClass]=\"field.autocompleteCssClass\" (initSelect)=\"field.itemSelect && field.itemSelect($event, formGroup?.getRawValue(), formGroup, context);\" (selected)=\"field.itemChange && field.itemChange($event, formGroup?.getRawValue(), formGroup, context);\" (cleared)=\"field.clear && field.clear(formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <mat-select [formControlName]=\"field.name\" [multiple]=\"field.multiple\" [disableControl]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" flex>\r\n <mat-option *ngFor=\"let option of field.options\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\">\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\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" (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 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.header | func:formGroup?.getRawValue():formGroup:context}}</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 formGroup.controls[field.name]['errorMessages']\" layout-margin>{{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]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name\" [disableControl]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\">{{field.header | func:formGroup?.getRawValue():formGroup:context}}</mat-checkbox>\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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\" 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 [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0]?.row + 1}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == (fields[0]?.row+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 [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formGroup?.getRawValue() | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>", styles: [""], 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: "component", type: i3.VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass", "triggerMode"] }, { kind: "directive", type: i4.VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: i5.VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "component", type: i6.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: i7.VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "directive", type: i8.VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "component", type: i9.VdFileInputComponent, selector: "[vd-file-input]", inputs: ["accept", "placeholder", "required", "multiple", "disabled", "errorState"], outputs: ["select", "clear"] }, { kind: "component", type: i10.VdListComponent, selector: "vd-list" }, { kind: "directive", type: i11.VdListOptionDirective, selector: "[vd-list-option]ng-template" }, { kind: "directive", type: i12.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: i12.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i12.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i12.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i12.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i12.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i12.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i13.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i13.MatLabel, selector: "mat-label" }, { kind: "directive", type: i13.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i13.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i13.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i14.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i15.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i16.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i17.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: i18.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i19.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: i19.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i19.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i19.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i20.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i21.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i21.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i22.MatChipGrid, selector: "mat-chip-grid", inputs: ["tabIndex", "disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i22.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i22.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i22.MatChipRow, selector: "mat-chip-row, mat-basic-chip-row", inputs: ["color", "disabled", "disableRipple", "tabIndex", "editable"], outputs: ["edited"] }, { kind: "directive", type: i23.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i24.MatFormFieldReadonlyDirective, selector: "mat-form-field" }, { kind: "directive", type: i25.EmptyStringResetDirective, selector: "[ngModel],[formControlName],[formControl]" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }, { kind: "pipe", type: i26.FuncPipe, name: "func" }] });
|
|
303
|
+
/** @nocollapse */ VdGenericFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", 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.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))\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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))\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" [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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" [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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" (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 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))\">\r\n <mat-chip-row *ngFor=\"let chip of 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>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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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.optionValue\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" [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 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))\" flex>\r\n <mat-option *ngFor=\"let option of field.options\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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))\">\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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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))\" (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 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 formGroup.controls[field.name]['errorMessages']\" layout-margin>{{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]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name\" [disableControl]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\">{{field.label}}</mat-checkbox>\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))\" 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 [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0]?.row + 1}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == (fields[0]?.row+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 [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\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: [""], 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: "component", type: i3.VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass", "triggerMode"] }, { kind: "directive", type: i4.VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: i5.VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "component", type: i6.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: i7.VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "directive", type: i8.VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "component", type: i9.VdFileInputComponent, selector: "[vd-file-input]", inputs: ["accept", "placeholder", "required", "multiple", "disabled", "errorState"], outputs: ["select", "clear"] }, { kind: "component", type: i10.VdListComponent, selector: "vd-list" }, { kind: "directive", type: i11.VdListOptionDirective, selector: "[vd-list-option]ng-template" }, { kind: "directive", type: i12.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: i12.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i12.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i12.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i12.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i12.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i12.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i13.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i13.MatLabel, selector: "mat-label" }, { kind: "directive", type: i13.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i13.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i13.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i14.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i15.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i16.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i17.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: i18.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i19.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: i19.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i19.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i19.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i20.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i21.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i21.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i22.MatChipGrid, selector: "mat-chip-grid", inputs: ["tabIndex", "disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i22.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i22.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i22.MatChipRow, selector: "mat-chip-row, mat-basic-chip-row", inputs: ["color", "disabled", "disableRipple", "tabIndex", "editable"], outputs: ["edited"] }, { kind: "directive", type: i23.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i24.MatFormFieldReadonlyDirective, selector: "mat-form-field" }, { kind: "directive", type: i25.EmptyStringResetDirective, selector: "[ngModel],[formControlName],[formControl]" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }, { kind: "pipe", type: i26.FuncPipe, name: "func" }] });
|
|
280
304
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: VdGenericFormComponent, decorators: [{
|
|
281
305
|
type: Component,
|
|
282
|
-
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.hide || !field.hide(formGroup?.getRawValue(), 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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <textarea matInput [formControlName]=\"field.name\" rows=\"field.rows||2\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-select [formControlName]=\"field.name\" [enum]=\"field.enumType\" [enumFilter]=\"field.enumFilter | func:formGroup?.getRawValue():formGroup:context\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" [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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-select [formControlName]=\"field.name\" [endpoint]=\"field.endpoint | func:formGroup?.getRawValue():formGroup:context\" [params]=\"field.params | func:formGroup?.getRawValue():formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formGroup?.getRawValue():formGroup:context\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" [triggerCssClass]=\"field.triggerCssClass\" [triggerMode]=\"field.triggerMode\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formGroup?.getRawValue(), formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), formGroup, context)\"></span>\r\n </ng-template>\r\n </vd-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-list [formControlName]=\"field.name\" [endpoint]=\"field.endpoint | func:formGroup?.getRawValue():formGroup:context\" [params]=\"field.params | func:formGroup?.getRawValue():formGroup:context\" [projection]=\"field.projection\" [mapper]=\"field.mapper\" [compareWith]=\"field.compareWith\" [loadData]=\"field.fetchCondition | func:formGroup?.getRawValue():formGroup:context\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" (itemSelected)=\"field.itemSelect && field.itemSelect($event, formGroup?.getRawValue(), formGroup, context);\" (itemChange)=\"field.itemChange && field.itemChange($event, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <mat-chip-grid #chipList [formControlName]=\"field.name\" [disableControl]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\">\r\n <mat-chip-row *ngFor=\"let chip of 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>cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n <input [placeholder]=\"field.header | func:formGroup?.getRawValue():formGroup:context\" #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\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <vd-chips #vdChip [formControlName]=\"field.name\" [endpoint]=\"field.endpoint | func:formGroup?.getRawValue():formGroup:context\" [params]=\"field.params | func:formGroup?.getRawValue():formGroup:context\" [searchField]=\"field.searchField\" [classType]=\"field.classType\" [projection]=\"field.projection\" [key]=\"field.optionValue\" [readonly]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" [removable]=\"!field.clear\" [context]=\"context\" [suffixButtons]=\"field.suffixButtons\" [autocompleteCssClass]=\"field.autocompleteCssClass\" (initSelect)=\"field.itemSelect && field.itemSelect($event, formGroup?.getRawValue(), formGroup, context);\" (selected)=\"field.itemChange && field.itemChange($event, formGroup?.getRawValue(), formGroup, context);\" (cleared)=\"field.clear && field.clear(formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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, formGroup?.getRawValue(), 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 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.header | func:formGroup?.getRawValue():formGroup:context}}</mat-label>\r\n <mat-select [formControlName]=\"field.name\" [multiple]=\"field.multiple\" [disableControl]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" flex>\r\n <mat-option *ngFor=\"let option of field.options\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\">\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\" (click)=\"suffixButton.event && suffixButton.event(formGroup?.getRawValue(), context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formGroup?.getRawValue(), context)\">\r\n <mat-icon>{{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 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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\">\r\n <mat-datepicker-toggle matSuffix [for]=\"datePicker\"></mat-datepicker-toggle>\r\n <mat-datepicker #datePicker [disabled]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\" (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 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.header | func:formGroup?.getRawValue():formGroup:context}}</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 formGroup.controls[field.name]['errorMessages']\" layout-margin>{{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]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name\" [disableControl]=\"readonly || (field.readonly && field.readonly(formGroup?.getRawValue(), formGroup, context))\">{{field.header | func:formGroup?.getRawValue():formGroup:context}}</mat-checkbox>\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.header | func:formGroup?.getRawValue():formGroup:context}}</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(formGroup?.getRawValue(), formGroup, context))\" 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 [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0]?.row + 1}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == (fields[0]?.row+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 [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Debug value -->\r\n <code *ngIf=\"debugValue\">\r\n <pre>{{formGroup?.getRawValue() | json}}</pre>\r\n </code>\r\n <!-- #endregion -->\r\n</div>" }]
|
|
306
|
+
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.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))\">\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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))\"></textarea>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" [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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" [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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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\" [key]=\"field.optionValue\" [text]=\"field.optionText\" [multiple]=\"field.multiple\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" (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 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))\">\r\n <mat-chip-row *ngFor=\"let chip of 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>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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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.optionValue\" [readonly]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\" [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 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))\" flex>\r\n <mat-option *ngFor=\"let option of field.options\" [value]=\"option.id\">{{option.name}}</mat-option>\r\n </mat-select>\r\n <ng-container *ngFor=\"let suffixButton of field.suffixButtons\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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))\">\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\" (click)=\"suffixButton.event && suffixButton.event(formValue, context)\" matSuffix>\r\n <button type=\"button\" mat-icon-button *ngIf=\"!suffixButton.hide || !suffixButton.hide(formValue, context)\">\r\n <mat-icon>{{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 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))\" (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 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 formGroup.controls[field.name]['errorMessages']\" layout-margin>{{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]=\"field.cssClass\">\r\n <mat-checkbox [formControlName]=\"field.name\" [disableControl]=\"readonly || (field.readonly && field.readonly(formValue, formGroup, context))\">{{field.label}}</mat-checkbox>\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))\" 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 [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0]?.row + 1}\"></ng-container>\r\n <ng-container *ngFor=\"let customField of customFieldsTemplates\">\r\n <ng-template *ngIf=\"customField?.templateRef && customField.row == (fields[0]?.row+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 [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\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>" }]
|
|
283
307
|
}], propDecorators: { formGroup: [{
|
|
284
308
|
type: Input
|
|
285
309
|
}], classType: [{
|
|
@@ -322,4 +346,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImpor
|
|
|
322
346
|
type: ContentChildren,
|
|
323
347
|
args: [VdGenericFormCustomFieldDirective]
|
|
324
348
|
}] } });
|
|
325
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nkay9zcmMvbGliL2Zvcm1zL2NvbXBvbmVudHMvZ2VuZXJpYy1mb3JtL2dlbmVyaWMtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZGsvc3JjL2xpYi9mb3Jtcy9jb21wb25lbnRzL2dlbmVyaWMtZm9ybS9nZW5lcmljLWZvcm0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsU0FBUyxFQUFFLFlBQVksRUFBaUIsV0FBVyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoTCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJM0MsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0seURBQXlELENBQUM7QUFDNUcsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzVELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUc5RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV0Rjs7R0FFRztBQUVILE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxTQUFTO0lBQzVDLFlBQVksV0FBNkIsRUFBRSxnQkFBa0M7UUFDekUs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RHhCLEtBQUs7Z0JBaUJDLGNBQWM7c0JBRHBCLFlBQVk7dUJBQUMsaUJBQWlCO2dCQU94QixZQUFZO3NCQURsQixZQUFZO3VCQUFDLGVBQWU7Z0JBT3RCLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsZUFBZTtnQkFPdEIsY0FBYztzQkFEcEIsWUFBWTt1QkFBQyxpQkFBaUI7Z0JBWXhCLE1BQU07c0JBRFosWUFBWTt1QkFBQyxRQUFRO2dCQU9mLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsY0FBYztnQkFPckIscUJBQXFCO3NCQUQzQixlQUFlO3VCQUFDLGlDQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENPTU1BLCBFTlRFUiB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9rZXljb2Rlcyc7XHJcbmltcG9ydCB7IENka1BvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIENvbnRlbnRDaGlsZCwgQ29udGVudENoaWxkcmVuLCBEaXJlY3RpdmUsIElucHV0LCBPbkluaXQsIFF1ZXJ5TGlzdCwgU2ltcGxlQ2hhbmdlLCBTaW1wbGVDaGFuZ2VzLCBUZW1wbGF0ZVJlZiwgVHlwZSwgVmlld0NvbnRhaW5lclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE1hdEF1dG9jb21wbGV0ZVNlbGVjdGVkRXZlbnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9hdXRvY29tcGxldGUnO1xyXG5pbXBvcnQgeyBNYXRDaGlwSW5wdXRFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NoaXBzJztcclxuaW1wb3J0IHsgTWF0Q2FsZW5kYXIsIE1hdERhdGVwaWNrZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcclxuaW1wb3J0IHsgVmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy92ZC1nZW5lcmljLWZvcm0tY3VzdG9tLWZpZWxkLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEZvcm1GaWVsZFR5cGUgfSBmcm9tICcuLi8uLi9lbnVtcy9mb3JtLWZpZWxkLXR5cGUnO1xyXG5pbXBvcnQgeyBnZXRGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBGb3JtRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBGb3JtRmllbGREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Zvcm0tZmllbGQtZGVmaW5pdGlvbic7XHJcbmltcG9ydCB7IEZvcm1GaWVsZEdyb3VwRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9mb3JtLWZpZWxkLWdyb3VwLWRlZmluaXRpb24nO1xyXG5pbXBvcnQgeyBEYXRlUGlja2VySGVhZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vZGF0ZXBpY2tlci9kYXRlcGlja2VyLWhlYWRlci5jb21wb25lbnQnO1xyXG5cclxuLyoqXHJcbiAqIFZkRWRpdG9yRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtZWRpdG9yXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRFZGl0b3JEaXJlY3RpdmUgZXh0ZW5kcyBDZGtQb3J0YWwge1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBWZENvZGVEaXJlY3RpdmUgY2xhc3NcclxuICovXHJcbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1t2ZC1jb2RlXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRDb2RlRGlyZWN0aXZlIGV4dGVuZHMgQ2RrUG9ydGFsIHtcclxuICAgIGNvbnN0cnVjdG9yKHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+LCB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmKSB7XHJcbiAgICAgICAgc3VwZXIodGVtcGxhdGVSZWYsIHZpZXdDb250YWluZXJSZWYpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogVmRGaWxlRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtZmlsZV1uZy10ZW1wbGF0ZScgfSlcclxuZXhwb3J0IGNsYXNzIFZkRmlsZURpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Piwgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZikge1xyXG4gICAgICAgIHN1cGVyKHRlbXBsYXRlUmVmLCB2aWV3Q29udGFpbmVyUmVmKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFZkQ3VzdG9tRGlyZWN0aXZlIGNsYXNzXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdmQtY3VzdG9tXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRDdXN0b21EaXJlY3RpdmUgZXh0ZW5kcyBDZGtQb3J0YWwge1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICd2ZC1nZW5lcmljLWZvcm0nLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2dlbmVyaWMtZm9ybS5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9nZW5lcmljLWZvcm0uY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVmRHZW5lcmljRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgICAvKipcclxuICAgICAqIGZvcm06IEZvcm1Hcm91cFxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGZvcm1Hcm91cDogRm9ybUdyb3VwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogY2xhc3NUeXBlOiBUeXBlPGFueT5cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjbGFzc1R5cGU6IFR5cGU8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIGZvcm1EZWZpbml0aW9uOiBGb3JtRGVmaW5pdGlvblxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGZvcm1EZWZpbml0aW9uOiBGb3JtRGVmaW5pdGlvbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIGZpZWxkR3JvdXBzOiBGb3JtRmllbGRHcm91cFtdXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZmllbGRHcm91cHM6IEZvcm1GaWVsZEdyb3VwRGVmaW5pdGlvbltdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR3JvdXAgbmFtZVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGdyb3VwTmFtZTogc3RyaW5nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmllbGQgc2V0IG5hbWVcclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmaWVsZFNldHM6IHN0cmluZ1tdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogY29udGV4dDogYW55XHJcbiAgICAgKiBUaGUgY3VycmVudCBjb250ZXh0XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgY29udGV4dDogYW55O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogZGVidWdWYWx1ZTogYm9vbGVhblxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGRlYnVnVmFsdWU6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiByZWFkb25seTogYm9vbGVhblxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIHJlYWRvbmx5OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBzZXBhcmF0b3JLZXlzQ29kZXM6IG51bWJlcltdXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2VwYXJhdG9yS2V5c0NvZGVzOiBudW1iZXJbXSA9IFtFTlRFUiwgQ09NTUFdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogZmllbGRSb3dzOiBGb3JtRmllbGREZWZpbml0aW9uW11cclxuICAgICAqL1xyXG4gICAgcHVibGljIGZpZWxkUm93czogRm9ybUZpZWxkRGVmaW5pdGlvbltdW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGb3JtRmllbGRUeXBlOiB0eXBlb2YgRm9ybUZpZWxkVHlwZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgRm9ybUZpZWxkVHlwZTogdHlwZW9mIEZvcm1GaWVsZFR5cGUgPSBGb3JtRmllbGRUeXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWRpdG9yIHRlbXBsYXRlXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoVmRFZGl0b3JEaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgZWRpdG9yVGVtcGxhdGU6IFZkRWRpdG9yRGlyZWN0aXZlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29kZSB0ZW1wbGF0ZVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKFZkQ29kZURpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBjb2RlVGVtcGxhdGU6IFZkQ29kZURpcmVjdGl2ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbGUgdGVtcGxhdGVcclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZEZpbGVEaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgZmlsZVRlbXBsYXRlOiBWZEZpbGVEaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDdXN0b20gdGVtcGxhdGVcclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZEN1c3RvbURpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBjdXN0b21UZW1wbGF0ZTogVmRDdXN0b21EaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDdXN0b21lciBkYXRlIGhlYWRlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudCA9IERhdGVQaWNrZXJIZWFkZXJDb21wb25lbnQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZW1wbGF0ZSByZWYgZm9yIGN1c3RvbSBmaWVsZHMgb24gdGhlIGJvdHRvbVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKCdib3R0b20nKVxyXG4gICAgcHVibGljIGJvdHRvbTogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKCdjdXN0b21GaWVsZHMnKVxyXG4gICAgcHVibGljIGN1c3RvbUZpZWxkczogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkcyBvbiB0aGUgYm90dG9tXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oVmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlKVxyXG4gICAgcHVibGljIGN1c3RvbUZpZWxkc1RlbXBsYXRlczogUXVlcnlMaXN0PFZkR2VuZXJpY0Zvcm1DdXN0b21GaWVsZERpcmVjdGl2ZT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaWx0ZXJkIG9wdGlvbnMgZm9yIGF1dG9jb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zOiB7fSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWxsYmFjayBtZXRob2QgdGhhdCBpcyBpbnZva2VkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZVxyXG4gICAgICogZGVmYXVsdCBjaGFuZ2UgZGV0ZWN0b3IgaGFzIGNoZWNrZWQgdGhlIGRpcmVjdGl2ZSdzXHJcbiAgICAgKiBkYXRhLWJvdW5kIHByb3BlcnRpZXMgZm9yIHRoZSBmaXJzdCB0aW1lLFxyXG4gICAgICogYW5kIGJlZm9yZSBhbnkgb2YgdGhlIHZpZXcgb3IgY29udGVudCBjaGlsZHJlbiBoYXZlIGJlZW4gY2hlY2tlZC5cclxuICAgICAqIEl0IGlzIGludm9rZWQgb25seSBvbmNlIHdoZW4gdGhlIGRpcmVjdGl2ZSBpcyBpbnN0YW50aWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgICAgIC8qIEJ1aWxkIHRoZSBmb3JtIGZpZWxkcyAqL1xyXG4gICAgICAgIGlmICh0aGlzLmNsYXNzVHlwZSAmJiAhdGhpcy5maWVsZEdyb3Vwcykge1xyXG4gICAgICAgICAgICB0aGlzLmJ1aWxkRmllbGRzKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBHZXQgZmlsZWQgcm93cyAqL1xyXG4gICAgICAgIHRoaXMuZmllbGRSb3dzID0gdGhpcy5maWVsZEdyb3Vwcz8uZmlsdGVyKHggPT4geC5uYW1lPy50cmltKCkgPT0gdGhpcy5ncm91cE5hbWU/LnRyaW0oKSlbMF0/Lmdyb3VwcztcclxuXHJcbiAgICAgICAgLyogRmlsdGVyIGJ5IGZpZWxkIHNldCAqL1xyXG4gICAgICAgIGlmICh0aGlzLmZpZWxkU2V0cykge1xyXG4gICAgICAgICAgICB0aGlzLmZpZWxkUm93cyA9IHRoaXMuZmllbGRSb3dzLm1hcCh4ID0+IHggPSB4LmZpbHRlcih5ID0+IHkuZmllbGRTZXRzPy5zb21lKHogPT4gdGhpcy5maWVsZFNldHM/LnNvbWUoYSA9PiBhPy50cmltKCk/LnRvTG93ZXJDYXNlKCkgPT0gej8udHJpbSgpPy50b0xvd2VyQ2FzZSgpKSkpKS5maWx0ZXIoeCA9PiB4Lmxlbmd0aCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBTdWJzY3JpZSB0byBjaGFuZ2UgZXZlbnQgKi9cclxuICAgICAgICB0aGlzLmZpZWxkUm93cz8ucmVkdWNlKChhLCBiKSA9PiBhLmNvbmNhdChiKSwgW10pPy5maWx0ZXIoeSA9PiB5LnR5cGUgIT0gRm9ybUZpZWxkVHlwZS5GaWxlICYmIHkuY2hhbmdlKT8uZm9yRWFjaCh4ID0+IHtcclxuICAgICAgICAgICAgdGhpcy5mb3JtR3JvdXA/LmdldCh4Lm5hbWUpPy52YWx1ZUNoYW5nZXM/LnN1YnNjcmliZSh5ID0+IHguY2hhbmdlKHksIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyBhdXRvY29tcGxldGUgZXZlbnRcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSBldmVudCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGZpbHRlckF1dG9jb21wbGV0ZShmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWVdID0gZmllbGQub3B0aW9ucz8uZmlsdGVyKG9wdGlvbiA9PiBvcHRpb24ubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGV2ZW50LnZhbHVlPy50b1N0cmluZygpPy50b0xvd2VyQ2FzZSgpKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGEgY2hpcCB3aGVuIGEgYXV0b2NvbXBsZXRlIHZhbHVlIGlzIHNlbGVjdGVkXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdXRvY29tcGxldGVWYWx1ZVNlbGVjdGVkKGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBldmVudDogTWF0QXV0b2NvbXBsZXRlU2VsZWN0ZWRFdmVudCwgY2hpcElucHV0RXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2FkZENoaXAoZmllbGQsIGV2ZW50Lm9wdGlvbi52aWV3VmFsdWUpO1xyXG4gICAgICAgIGNoaXBJbnB1dEV2ZW50LnZhbHVlID0gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGEgY2hpcFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICogQHBhcmFtIGV2ZW50IFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRkQ2hpcChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgZXZlbnQ6IE1hdENoaXBJbnB1dEV2ZW50KTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fYWRkQ2hpcChmaWVsZCwgZXZlbnQudmFsdWUpO1xyXG4gICAgICAgIGV2ZW50LmNoaXBJbnB1dCEuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYSBjaGlwXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gY2hpcCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlbW92ZUNoaXAoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGNoaXA6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIC8qIEdldCB0aGUgZm9ybSBjb250cm9sIHVzaW5nIHRoZSBmaWVsZCBuYW1lICovXHJcbiAgICAgICAgbGV0IGNvbnRyb2wgPSB0aGlzLmZvcm1Hcm91cD8uY29udHJvbHNbZmllbGQubmFtZV07XHJcblxyXG4gICAgICAgIC8qIEdldCB0aGUgaW5kZXggb2YgdGhlIGNoaXAgKi9cclxuICAgICAgICBjb25zdCBpbmRleCA9IGNvbnRyb2wudmFsdWUuaW5kZXhPZihjaGlwKTtcclxuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xyXG4gICAgICAgICAgICBjb250cm9sLnZhbHVlLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIGNoaXBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSB2YWx1ZSBcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfYWRkQ2hpcChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIC8qIEdldCB0aGUgZm9ybSBjb250cm9sIHVzaW5nIHRoZSBmaWVsZCBuYW1lICovXHJcbiAgICAgICAgbGV0IGNvbnRyb2wgPSB0aGlzLmZvcm1Hcm91cD8uY29udHJvbHNbZmllbGQubmFtZV07XHJcblxyXG4gICAgICAgIC8qIEdldCB0aGUgdmFsdWUgb2YgdGhlIGNoaXAgKi9cclxuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8fCAnJykudHJpbSgpO1xyXG4gICAgICAgIGlmIChjb250cm9sICYmIHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoZmllbGQuaW5wdXRUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdudW1iZXInOlxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBudW1iZXIgPSBwYXJzZUludCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG51bWJlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2gobnVtYmVyKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgY2FzZSAnZmxvYXQnOlxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBmbG9hdCA9IHBhcnNlRmxvYXQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmbG9hdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2goZmxvYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2wudmFsdWUucHVzaCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyBkYXRlIHBpY2tlciBvcGVuZWQgZXZlbnRcclxuICAgICAqIEBwYXJhbSBkYXRlUGlja2VyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlRGF0ZVBpY2tlck9wZW5lZChkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlUGlja2VyT3BlbmVkKSB7XHJcbiAgICAgICAgICAgIGZpZWxkLmRhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGRhdGUgZmlsdGVyIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0gZGF0ZVBpY2tlciBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGhhbmRsZURhdGVQaWNrZXJGaWx0ZXJBc3luYyhkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBkYXRlOiBEYXRlIHwgYW55KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlRmlsdGVyQXN5bmMpIHtcclxuICAgICAgICAgICAgLyogRGlzYWJsZXMgYWxsIGRhdGVzICovXHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIuZGF0ZXBpY2tlcklucHV0LmRhdGVGaWx0ZXIgPSAoZDogRGF0ZSkgPT4gZmFsc2U7XHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICBmaWVsZC5kYXRlRmlsdGVyQXN5bmMoZGF0ZSwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KS5zdWJzY3JpYmUoeCA9PiB7XHJcbiAgICAgICAgICAgICAgICBkYXRlUGlja2VyLmRhdGVwaWNrZXJJbnB1dC5kYXRlRmlsdGVyID0gKGQ6IERhdGUpID0+IGQgJiYgeChkKTtcclxuICAgICAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGNhbGVuZGFyIGZpbHRlciBldmVudFxyXG4gICAgICogQHBhcmFtIGNhbGVuZGFyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlQ2FsZW5kYXJGaWx0ZXJBc3luYyhjYWxlbmRhcjogTWF0Q2FsZW5kYXI8YW55PiwgZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGRhdGU6IERhdGUgfCBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZmllbGQ/LmRhdGVGaWx0ZXJBc3luYykge1xyXG4gICAgICAgICAgICAvKiBEaXNhYmxlcyBhbGwgZGF0ZXMgKi9cclxuICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBmYWxzZTtcclxuICAgICAgICAgICAgY2FsZW5kYXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICB2YXIgc3Vic2NyaXB0aW9uID0gZmllbGQuZGF0ZUZpbHRlckFzeW5jKGRhdGUsIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkuc3Vic2NyaWJlKHggPT4ge1xyXG4gICAgICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBkICYmIHgoZCk7XHJcbiAgICAgICAgICAgICAgICBjYWxlbmRhci5uZ09uQ2hhbmdlcyg8U2ltcGxlQ2hhbmdlcz57ICdkYXRlRmlsdGVyJzogbmV3IFNpbXBsZUNoYW5nZShcIlwiLCBcIlwiLCBmYWxzZSkgfSk7XHJcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQnVpbGRzIHRoZSBmb3JtIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYnVpbGRGaWVsZHMoKTogdm9pZCB7XHJcbiAgICAgICAgLyogR2V0IGZvcm0gZGVmaW5pdGlvbiAqL1xyXG4gICAgICAgIHRoaXMuZm9ybURlZmluaXRpb24gPSBnZXRGb3JtRGVmaW5pdGlvbihuZXcgdGhpcy5jbGFzc1R5cGUoKSk7XHJcblxyXG4gICAgICAgIC8qIENyZWF0ZSB0aGUgZnJvbSBmaWVsZHMgdXNpbmcgdGhlIGVudGl0eSB0eXBlICovXHJcbiAgICAgICAgdGhpcy5maWVsZEdyb3VwcyA9IHRoaXMuZm9ybURlZmluaXRpb24/LmZpZWxkR3JvdXBzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9nIHRvIGNvbnNvbGVcclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFxyXG4gICAgICogQHBhcmFtIG9wdGlvbmFsUGFyYW1zIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9nKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2cobWVzc2FnZSwgb3B0aW9uYWxQYXJhbXMpO1xyXG4gICAgfVxyXG59IiwiPGRpdiAqbmdJZj1cImZvcm1Hcm91cCAmJiBmaWVsZFJvd3NcIiBbZm9ybUdyb3VwXT1cImZvcm1Hcm91cFwiPlxyXG4gICAgPCEtLSAjcmVnaW9uIEZpZWxkcyAtLT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkcyBvZiBmaWVsZFJvd3M7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICA8ZGl2IGxheW91dC1ndC1zbT1cInJvd1wiIGxheW91dD1cImNvbHVtblwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmaWVsZHNcIiBbbmdTd2l0Y2hdPVwiZmllbGQudHlwZVwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmaWVsZC5oaWRlIHx8ICFmaWVsZC5oaWRlKGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWVsZC53cmFwcGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZXh0IGlucHV0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVGV4dFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHR9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cImZpZWxkLmlucHV0VHlwZVwiIFttaW5sZW5ndGhdPVwiZmllbGQubWluTGVuZ3RofHxudWxsXCIgW21heGxlbmd0aF09XCJmaWVsZC5tYXhMZW5ndGh8fG51bGxcIiBbbWluXT1cImZpZWxkLm1pblwiIFttYXhdPVwiZmllbGQubWF4XCIgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW3JlYWRvbmx5XT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgY29udGV4dClcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gVGV4dGFyZWEgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5UZXh0QXJlYVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHR9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIG1hdElucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIHJvd3M9XCJmaWVsZC5yb3dzfHwyXCIgW3JlYWRvbmx5XT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCkpXCI+PC90ZXh0YXJlYT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBjb250ZXh0KVwiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBFbnVtIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuRW51bVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHR9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHZkLXNlbGVjdCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiBbZW51bV09XCJmaWVsZC5lbnVtVHlwZVwiIFtlbnVtRmlsdGVyXT1cImZpZWxkLmVudW1GaWx0ZXIgfCBmdW5jOmZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKTpmb3JtR3JvdXA6Y29udGV4dFwiIFtrZXldPVwiZmllbGQub3B0aW9uVmFsdWVcIiBbdGV4dF09XCJmaWVsZC5vcHRpb25UZXh0XCIgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCIgW3JlYWRvbmx5XT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCkpXCIgW3RyaWdnZXJDc3NDbGFzc109XCJmaWVsZC50cmlnZ2VyQ3NzQ2xhc3NcIiBbdHJpZ2dlck1vZGVdPVwiZmllbGQudHJpZ2dlck1vZGVcIiBsYXlvdXQ9XCJyb3dcIiBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3QtdHJpZ2dlciBsZXQtdHJpZ2dlcj1cInRyaWdnZXJcIiAqbmdJZj1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZSh0cmlnZ2VyLCBmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LW9wdGlvbiBsZXQtb3B0aW9uPVwib3B0aW9uXCIgKm5nSWY9XCJmaWVsZC5vcHRpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbb3V0ZXJIVE1MXT1cImZpZWxkLm9wdGlvblRlbXBsYXRlKG9wdGlvbiwgZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3ZkLXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBjb250ZXh0KVwiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZFNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlZkU2VsZWN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5oZWFkZXIgfCBmdW5jOmZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKTpmb3JtR3JvdXA6Y29udGV4dH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIFtlbmRwb2ludF09XCJmaWVsZC5lbmRwb2ludCB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0XCIgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgfCBmdW5jOmZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKTpmb3JtR3JvdXA6Y29udGV4dFwiIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIiBbbWFwcGVyXT1cImZpZWxkLm1hcHBlclwiIFtjb21wYXJlV2l0aF09XCJmaWVsZC5jb21wYXJlV2l0aFwiIFtsb2FkRGF0YV09XCJmaWVsZC5mZXRjaENvbmRpdGlvbiB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0XCIgW2tleV09XCJmaWVsZC5vcHRpb25WYWx1ZVwiIFt0ZXh0XT1cImZpZWxkLm9wdGlvblRleHRcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIiBbdHJpZ2dlckNzc0NsYXNzXT1cImZpZWxkLnRyaWdnZXJDc3NDbGFzc1wiIFt0cmlnZ2VyTW9kZV09XCJmaWVsZC50cmlnZ2VyTW9kZVwiIChpdGVtU2VsZWN0ZWQpPVwiZmllbGQuaXRlbVNlbGVjdCAmJiBmaWVsZC5pdGVtU2VsZWN0KCRldmVudCwgZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBmb3JtR3JvdXAsIGNvbnRleHQpO1wiIChpdGVtQ2hhbmdlKT1cImZpZWxkLml0ZW1DaGFuZ2UgJiYgZmllbGQuaXRlbUNoYW5nZSgkZXZlbnQsIGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiBsYXlvdXQ9XCJyb3dcIiBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3QtdHJpZ2dlciBsZXQtdHJpZ2dlcj1cInRyaWdnZXJcIiAqbmdJZj1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZSh0cmlnZ2VyLCBmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LXRyaWdnZXIgbGV0LXRyaWdnZXI9XCJ0cmlnZ2VyXCIgKm5nSWY9XCJmaWVsZC50cmlnZ2VyTWFwcGVyICYmIGZpZWxkLm11bHRpcGxlICYmIGZpZWxkLnRyaWdnZXJNb2RlID09ICdjaGlwJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiB0cmlnZ2VyXCIgY2xhc3M9XCJtYXQtbWRjLWNoaXAgbWF0LW1kYy1zdGFuZGFyZC1jaGlwIG1hdC1wcmltYXJ5IG1hdC1tZGMtY2hpcC1zZWxlY3RlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySFRNTF09XCJmaWVsZC50cmlnZ2VyTWFwcGVyKGl0ZW0sIGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiICpuZ0lmPVwiZmllbGQub3B0aW9uVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW291dGVySFRNTF09XCJmaWVsZC5vcHRpb25UZW1wbGF0ZShvcHRpb24sIGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC92ZC1zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgY29udGV4dClcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gVmRMaXN0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVmRMaXN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgZmxvYXRMYWJlbD1cImFsd2F5c1wiIGNsYXNzPVwiZm9ybS1maWVsZC10eXBlLWxpc3RcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmhlYWRlciB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0fX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx2ZC1saXN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIFtlbmRwb2ludF09XCJmaWVsZC5lbmRwb2ludCB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0XCIgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgfCBmdW5jOmZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKTpmb3JtR3JvdXA6Y29udGV4dFwiIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIiBbbWFwcGVyXT1cImZpZWxkLm1hcHBlclwiIFtjb21wYXJlV2l0aF09XCJmaWVsZC5jb21wYXJlV2l0aFwiIFtsb2FkRGF0YV09XCJmaWVsZC5mZXRjaENvbmRpdGlvbiB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0XCIgW2tleV09XCJmaWVsZC5vcHRpb25WYWx1ZVwiIFt0ZXh0XT1cImZpZWxkLm9wdGlvblRleHRcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIiAoaXRlbVNlbGVjdGVkKT1cImZpZWxkLml0ZW1TZWxlY3QgJiYgZmllbGQuaXRlbVNlbGVjdCgkZXZlbnQsIGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiAoaXRlbUNoYW5nZSk9XCJmaWVsZC5pdGVtQ2hhbmdlICYmIGZpZWxkLml0ZW1DaGFuZ2UoJGV2ZW50LCBmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgW3N0eWxlLm1heC13aWR0aF09XCJmaWVsZC5tYXhXaWR0aFwiIFtzdHlsZS5tYXgtaGVpZ2h0XT1cImZpZWxkLm1heEhlaWdodFwiIGZsZXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLWxpc3Qtb3B0aW9uIGxldC1vcHRpb249XCJvcHRpb25cIiAqbmdJZj1cImZpZWxkLm9wdGlvblRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtvdXRlckhUTUxdPVwiZmllbGQub3B0aW9uVGVtcGxhdGUob3B0aW9uLCBmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtbGlzdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDaGlwcyAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkNoaXBzXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5oZWFkZXIgfCBmdW5jOmZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKTpmb3JtR3JvdXA6Y29udGV4dH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoaXAtZ3JpZCAjY2hpcExpc3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW2Rpc2FibGVDb250cm9sXT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGlwLXJvdyAqbmdGb3I9XCJsZXQgY2hpcCBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV0/LnZhbHVlXCIgKHJlbW92ZWQpPVwicmVtb3ZlQ2hpcChmaWVsZCwgY2hpcClcIiBjb2xvcj1cInByaW1hcnlcIiBzZWxlY3RhYmxlPVwidHJ1ZVwiIHNlbGVjdGVkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57e2NoaXB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXRDaGlwUmVtb3ZlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNhbmNlbDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoaXAtcm93PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBbcGxhY2Vob2xkZXJdPVwiZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHRcIiAjY2hpcElucHV0IFttYXRDaGlwSW5wdXRGb3JdPVwiY2hpcExpc3RcIiBbbWF0Q2hpcElucHV0U2VwYXJhdG9yS2V5Q29kZXNdPVwic2VwYXJhdG9yS2V5c0NvZGVzXCIgW21hdEF1dG9jb21wbGV0ZV09XCJjaGlwQXV0b2NvbXBsZXRlXCIgKGlucHV0KT1cImZpbHRlckF1dG9jb21wbGV0ZShmaWVsZCwgY2hpcElucHV0KVwiIChtYXRDaGlwSW5wdXRUb2tlbkVuZCk9XCJhZGRDaGlwKGZpZWxkLCAkZXZlbnQpXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGlwLWdyaWQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWF1dG9jb21wbGV0ZSBhdXRvQWN0aXZlRmlyc3RPcHRpb24gI2NoaXBBdXRvY29tcGxldGU9XCJtYXRBdXRvY29tcGxldGVcIiBbY2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIiAob3B0aW9uU2VsZWN0ZWQpPVwiYXV0b2NvbXBsZXRlVmFsdWVTZWxlY3RlZChmaWVsZCwgJGV2ZW50LCBjaGlwSW5wdXQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBhdXRvY29tcGxldGVGaWx0ZXJlZE9wdGlvbnNbZmllbGQubmFtZV1cIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9uLm5hbWV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBjb250ZXh0KVwiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZENoaXBzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVmRDaGlwc1wiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHR9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHZkLWNoaXBzICN2ZENoaXAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW2VuZHBvaW50XT1cImZpZWxkLmVuZHBvaW50IHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHRcIiBbcGFyYW1zXT1cImZpZWxkLnBhcmFtcyB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0XCIgW3NlYXJjaEZpZWxkXT1cImZpZWxkLnNlYXJjaEZpZWxkXCIgW2NsYXNzVHlwZV09XCJmaWVsZC5jbGFzc1R5cGVcIiBbcHJvamVjdGlvbl09XCJmaWVsZC5wcm9qZWN0aW9uXCIgW2tleV09XCJmaWVsZC5vcHRpb25WYWx1ZVwiIFtyZWFkb25seV09XCJyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiIFtyZW1vdmFibGVdPVwiIWZpZWxkLmNsZWFyXCIgW2NvbnRleHRdPVwiY29udGV4dFwiIFtzdWZmaXhCdXR0b25zXT1cImZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBbYXV0b2NvbXBsZXRlQ3NzQ2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIiAoaW5pdFNlbGVjdCk9XCJmaWVsZC5pdGVtU2VsZWN0ICYmIGZpZWxkLml0ZW1TZWxlY3QoJGV2ZW50LCBmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgKHNlbGVjdGVkKT1cImZpZWxkLml0ZW1DaGFuZ2UgJiYgZmllbGQuaXRlbUNoYW5nZSgkZXZlbnQsIGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiAoY2xlYXJlZCk9XCJmaWVsZC5jbGVhciAmJiBmaWVsZC5jbGVhcihmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgW2N1c3RvbVZhbHVlXT1cImZpZWxkLmN1c3RvbVZhbHVlXCIgbGF5b3V0PVwicm93XCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtY2hpcCBsZXQtY2hpcD1cImNoaXBcIiAqbmdJZj1cImZpZWxkLmNoaXBUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtvdXRlckhUTUxdPVwiZmllbGQuY2hpcFRlbXBsYXRlKGNoaXAsIGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLWF1dG9jb21wbGV0ZS1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiICpuZ0lmPVwiZmllbGQuYXV0b2NvbXBsZXRlVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbb3V0ZXJIVE1MXT1cImZpZWxkLmF1dG9jb21wbGV0ZVRlbXBsYXRlKG9wdGlvbiwgZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtY2hpcHM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwidmRDaGlwLmVtcHR5UmVzdWx0XCIgY2xhc3M9XCJ0Yy1yZWQtNDAwXCIgaTE4bj1cIkBAbm9SZXN1bHRzRm91bmRcIj5ObyByZXN1bHRzIHdlcmUgZm91bmQuPC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV1bJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlNlbGVjdFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHR9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCIgW2Rpc2FibGVDb250cm9sXT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGZvcm1Hcm91cCwgY29udGV4dCkpXCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGZpZWxkLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+e3tvcHRpb24ubmFtZX19PC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiAoY2xpY2spPVwic3VmZml4QnV0dG9uLmV2ZW50ICYmIHN1ZmZpeEJ1dHRvbi5ldmVudChmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGNvbnRleHQpXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV1bJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIEF1dG9jb21wbGV0ZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkF1dG9jb21wbGV0ZVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHR9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiIFttYXRBdXRvY29tcGxldGVdPVwiYXV0b1wiICNhdXRvY29tcGxldGVJbnB1dCAoaW5wdXQpPVwiZmlsdGVyQXV0b2NvbXBsZXRlKGZpZWxkLCBhdXRvY29tcGxldGVJbnB1dClcIiBhdXRvY29tcGxldGU9XCJvZmZcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtYXV0b2NvbXBsZXRlIGF1dG9BY3RpdmVGaXJzdE9wdGlvbiAjYXV0bz1cIm1hdEF1dG9jb21wbGV0ZVwiIFtjbGFzc109XCJmaWVsZC5hdXRvY29tcGxldGVDc3NDbGFzc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWVdXCIgW3ZhbHVlXT1cIm9wdGlvbi5pZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e29wdGlvbi5uYW1lfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1hdXRvY29tcGxldGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgY29udGV4dClcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCksIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gRGF0ZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkRhdGVcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmhlYWRlciB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0fX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiBbbWluXT1cImZpZWxkLm1pblwiIFttYXhdPVwiZmllbGQubWF4XCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW21hdERhdGVwaWNrZXJdPVwiZGF0ZVBpY2tlclwiIFttYXREYXRlcGlja2VyRmlsdGVyXT1cImZpZWxkLmRhdGVGaWx0ZXJcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgZmllbGQuZm9yY2VTZWxlY3QgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZGF0ZXBpY2tlci10b2dnbGUgbWF0U3VmZml4IFtmb3JdPVwiZGF0ZVBpY2tlclwiPjwvbWF0LWRhdGVwaWNrZXItdG9nZ2xlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlcGlja2VyICNkYXRlUGlja2VyIFtkaXNhYmxlZF09XCJyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiIChtb250aFNlbGVjdGVkKT1cImhhbmRsZURhdGVQaWNrZXJGaWx0ZXJBc3luYyhkYXRlUGlja2VyLCBmaWVsZCwgJGV2ZW50IClcIiAob3BlbmVkKT1cImhhbmRsZURhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgZmllbGQpXCIgW2NhbGVuZGFySGVhZGVyQ29tcG9uZW50XT1cImRhdGVQaWNrZXJIZWFkZXJDb21wb25lbnRcIj48L21hdC1kYXRlcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV1bJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENhbGVuZGFyIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2FsZW5kYXJcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBmbG9hdExhYmVsPVwiYWx3YXlzXCIgY2xhc3M9XCJmb3JtLWZpZWxkLXR5cGUtY2FsZW5kYXJcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmhlYWRlciB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0fX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpbnB1dD1cImhpZGRlblwiIGhpZGRlbiBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2FsZW5kYXIgI2NhbGVuZGFyIFtzZWxlY3RlZF09XCJmb3JtR3JvdXAuZ2V0KGZpZWxkLm5hbWUpLnZhbHVlXCIgKHNlbGVjdGVkQ2hhbmdlKT1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSkuc2V0VmFsdWUoJGV2ZW50KTtcIiAobW9udGhTZWxlY3RlZCk9XCJoYW5kbGVDYWxlbmRhckZpbHRlckFzeW5jKGNhbGVuZGFyLCBmaWVsZCwgJGV2ZW50IClcIiBbaGVhZGVyQ29tcG9uZW50XT1cImRhdGVQaWNrZXJIZWFkZXJDb21wb25lbnRcIiBzdHlsZT1cIndpZHRoOiAxMDAlO1wiPjwvbWF0LWNhbGVuZGFyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCIgbGF5b3V0LW1hcmdpbj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENoZWNrYm94IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2hlY2tib3hcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiBbZGlzYWJsZUNvbnRyb2xdPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIj57e2ZpZWxkLmhlYWRlciB8IGZ1bmM6Zm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpOmZvcm1Hcm91cDpjb250ZXh0fX08L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBFZGl0b3IgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5FZGl0b3JcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiZWRpdG9yVGVtcGxhdGU/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiZWRpdG9yVGVtcGxhdGU/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgZmllbGQ6IGZpZWxkLCBmb3JtR3JvdXA6IGZvcm1Hcm91cCB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDb2RlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ29kZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJjb2RlVGVtcGxhdGU/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29kZVRlbXBsYXRlPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGZpZWxkOiBmaWVsZCwgZm9ybUdyb3VwOiBmb3JtR3JvdXAgfVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gRmlsZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkZpbGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQuaGVhZGVyIHwgZnVuYzpmb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk6Zm9ybUdyb3VwOmNvbnRleHR9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiB2ZC1maWxlLWlucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIChzZWxlY3QpPVwiZmllbGQuY2hhbmdlICYmIGZpZWxkLmNoYW5nZShmaWVsZCwgJGV2ZW50LCBmb3JtR3JvdXAsIGNvbnRleHQpXCIgW2FjY2VwdF09XCJmaWVsZC5maWxlRXh0ZW5zaW9uc1wiIFtkaXNhYmxlQ29udHJvbF09XCJyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybUdyb3VwPy5nZXRSYXdWYWx1ZSgpLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiIGZsZXg+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gQ3VzdG9tIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ3VzdG9tXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImN1c3RvbVRlbXBsYXRlPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbVRlbXBsYXRlPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGZpZWxkOiBmaWVsZCwgZm9ybUdyb3VwOiBmb3JtR3JvdXAgfVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFRlbXBsYXRlIGZvciBjdXN0b20gZmllbGRzIC0tPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjdXN0b21GaWVsZCBvZiBjdXN0b21GaWVsZHNUZW1wbGF0ZXNcIj5cclxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZiAmJiBjdXN0b21GaWVsZC5yb3cgPT0gZmllbGRzWzBdPy5yb3cgJiYgY3VzdG9tRmllbGQuaW5saW5lXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntmb3JtR3JvdXA6IGZvcm1Hcm91cH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tICNyZWdpb24gVGVtcGxhdGUgZm9yIGN1c3RvbSBmaWVsZHMgLS0+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjdXN0b21GaWVsZHNcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2Zvcm1Hcm91cDogZm9ybUdyb3VwLCByb3c6IGZpZWxkc1swXT8ucm93ICsgMX1cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjdXN0b21GaWVsZCBvZiBjdXN0b21GaWVsZHNUZW1wbGF0ZXNcIj5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmICYmIGN1c3RvbUZpZWxkLnJvdyA9PSAoZmllbGRzWzBdPy5yb3crMSkgJiYgIWN1c3RvbUZpZWxkLmlubGluZVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICA8IS0tICNyZWdpb24gRm9ybSBib3R0b20gLS0+XHJcbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImJvdHRvbVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXB9XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgPCEtLSAjcmVnaW9uIERlYnVnIHZhbHVlIC0tPlxyXG4gICAgPGNvZGUgKm5nSWY9XCJkZWJ1Z1ZhbHVlXCI+XHJcbiAgICAgICAgPHByZT57e2Zvcm1Hcm91cD8uZ2V0UmF3VmFsdWUoKSB8IGpzb259fTwvcHJlPlxyXG4gICAgPC9jb2RlPlxyXG4gICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG48L2Rpdj4iXX0=
|
|
349
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nkay9zcmMvbGliL2Zvcm1zL2NvbXBvbmVudHMvZ2VuZXJpYy1mb3JtL2dlbmVyaWMtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZGsvc3JjL2xpYi9mb3Jtcy9jb21wb25lbnRzL2dlbmVyaWMtZm9ybS9nZW5lcmljLWZvcm0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsU0FBUyxFQUFFLFlBQVksRUFBaUIsV0FBVyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoTCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJM0MsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0seURBQXlELENBQUM7QUFDNUcsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzVELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUc5RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV0Rjs7R0FFRztBQUVILE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxTQUFTO0lBQzVDLFlBQVksV0FBNkIsRUFBRSxnQkFBa0M7UUFDekUs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QUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7O3NJQXRWUSxzQkFBc0I7MEhBQXRCLHNCQUFzQiwyWEFxRmpCLGlCQUFpQiwrRUFNakIsZUFBZSwrRUFNZixlQUFlLGlGQU1mLGlCQUFpQiw2UEF1QmQsaUNBQWlDLDZCQzFMdEQsdW54QkErUE07MkZEbk1PLHNCQUFzQjtrQkFMbEMsU0FBUzsrQkFDSSxpQkFBaUI7OEJBU3BCLFNBQVM7c0JBRGYsS0FBSztnQkFZQyxTQUFTO3NCQURmLEtBQUs7Z0JBT0MsY0FBYztzQkFEcEIsS0FBSztnQkFPQyxXQUFXO3NCQURqQixLQUFLO2dCQU9DLFNBQVM7c0JBRGYsS0FBSztnQkFPQyxTQUFTO3NCQURmLEtBQUs7Z0JBUUMsT0FBTztzQkFEYixLQUFLO2dCQU9DLFVBQVU7c0JBRGhCLEtBQUs7Z0JBT0MsUUFBUTtzQkFEZCxLQUFLO2dCQU9DLGtCQUFrQjtzQkFEeEIsS0FBSztnQkFzQkMsY0FBYztzQkFEcEIsWUFBWTt1QkFBQyxpQkFBaUI7Z0JBT3hCLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsZUFBZTtnQkFPdEIsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxlQUFlO2dCQU90QixjQUFjO3NCQURwQixZQUFZO3VCQUFDLGlCQUFpQjtnQkFZeEIsTUFBTTtzQkFEWixZQUFZO3VCQUFDLFFBQVE7Z0JBT2YsWUFBWTtzQkFEbEIsWUFBWTt1QkFBQyxjQUFjO2dCQU9yQixxQkFBcUI7c0JBRDNCLGVBQWU7dUJBQUMsaUNBQWlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ09NTUEsIEVOVEVSIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcclxuaW1wb3J0IHsgQ2RrUG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XHJcbmltcG9ydCB7IENvbXBvbmVudCwgQ29udGVudENoaWxkLCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgSW5wdXQsIE9uSW5pdCwgUXVlcnlMaXN0LCBTaW1wbGVDaGFuZ2UsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBUeXBlLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgTWF0QXV0b2NvbXBsZXRlU2VsZWN0ZWRFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2F1dG9jb21wbGV0ZSc7XHJcbmltcG9ydCB7IE1hdENoaXBJbnB1dEV2ZW50IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY2hpcHMnO1xyXG5pbXBvcnQgeyBNYXRDYWxlbmRhciwgTWF0RGF0ZXBpY2tlciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RhdGVwaWNrZXInO1xyXG5pbXBvcnQgeyBWZEdlbmVyaWNGb3JtQ3VzdG9tRmllbGREaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL3ZkLWdlbmVyaWMtZm9ybS1jdXN0b20tZmllbGQuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgRm9ybUZpZWxkVHlwZSB9IGZyb20gJy4uLy4uL2VudW1zL2Zvcm0tZmllbGQtdHlwZSc7XHJcbmltcG9ydCB7IGdldEZvcm1EZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vZnVuY3Rpb25zL2Z1bmN0aW9ucyc7XHJcbmltcG9ydCB7IEZvcm1EZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Zvcm0tZGVmaW5pdGlvbic7XHJcbmltcG9ydCB7IEZvcm1GaWVsZERlZmluaXRpb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvZm9ybS1maWVsZC1kZWZpbml0aW9uJztcclxuaW1wb3J0IHsgRm9ybUZpZWxkR3JvdXBEZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Zvcm0tZmllbGQtZ3JvdXAtZGVmaW5pdGlvbic7XHJcbmltcG9ydCB7IERhdGVQaWNrZXJIZWFkZXJDb21wb25lbnQgfSBmcm9tICcuLi9kYXRlcGlja2VyL2RhdGVwaWNrZXItaGVhZGVyLmNvbXBvbmVudCc7XHJcblxyXG4vKipcclxuICogVmRFZGl0b3JEaXJlY3RpdmUgY2xhc3NcclxuICovXHJcbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1t2ZC1lZGl0b3JdbmctdGVtcGxhdGUnIH0pXHJcbmV4cG9ydCBjbGFzcyBWZEVkaXRvckRpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Piwgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZikge1xyXG4gICAgICAgIHN1cGVyKHRlbXBsYXRlUmVmLCB2aWV3Q29udGFpbmVyUmVmKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFZkQ29kZURpcmVjdGl2ZSBjbGFzc1xyXG4gKi9cclxuQERpcmVjdGl2ZSh7IHNlbGVjdG9yOiAnW3ZkLWNvZGVdbmctdGVtcGxhdGUnIH0pXHJcbmV4cG9ydCBjbGFzcyBWZENvZGVEaXJlY3RpdmUgZXh0ZW5kcyBDZGtQb3J0YWwge1xyXG4gICAgY29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICAgICAgICBzdXBlcih0ZW1wbGF0ZVJlZiwgdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBWZEZpbGVEaXJlY3RpdmUgY2xhc3NcclxuICovXHJcbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1t2ZC1maWxlXW5nLXRlbXBsYXRlJyB9KVxyXG5leHBvcnQgY2xhc3MgVmRGaWxlRGlyZWN0aXZlIGV4dGVuZHMgQ2RrUG9ydGFsIHtcclxuICAgIGNvbnN0cnVjdG9yKHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+LCB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmKSB7XHJcbiAgICAgICAgc3VwZXIodGVtcGxhdGVSZWYsIHZpZXdDb250YWluZXJSZWYpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogVmRDdXN0b21EaXJlY3RpdmUgY2xhc3NcclxuICovXHJcbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1t2ZC1jdXN0b21dbmctdGVtcGxhdGUnIH0pXHJcbmV4cG9ydCBjbGFzcyBWZEN1c3RvbURpcmVjdGl2ZSBleHRlbmRzIENka1BvcnRhbCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Piwgdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZikge1xyXG4gICAgICAgIHN1cGVyKHRlbXBsYXRlUmVmLCB2aWV3Q29udGFpbmVyUmVmKTtcclxuICAgIH1cclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3ZkLWdlbmVyaWMtZm9ybScsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZ2VuZXJpYy1mb3JtLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2dlbmVyaWMtZm9ybS5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBWZEdlbmVyaWNGb3JtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuICAgIC8qKlxyXG4gICAgICogZm9ybTogRm9ybUdyb3VwXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZm9ybUdyb3VwOiBGb3JtR3JvdXA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGb3JtIHJhdyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGZvcm1WYWx1ZSgpOiBhbnkgeyByZXR1cm4gdGhpcy5mb3JtR3JvdXA/LmdldFJhd1ZhbHVlKCk7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIGNsYXNzVHlwZTogVHlwZTxhbnk+XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgY2xhc3NUeXBlOiBUeXBlPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBmb3JtRGVmaW5pdGlvbjogRm9ybURlZmluaXRpb25cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmb3JtRGVmaW5pdGlvbjogRm9ybURlZmluaXRpb247XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBmaWVsZEdyb3VwczogRm9ybUZpZWxkR3JvdXBbXVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGZpZWxkR3JvdXBzOiBGb3JtRmllbGRHcm91cERlZmluaXRpb25bXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdyb3VwIG5hbWVcclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBncm91cE5hbWU6IHN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpZWxkIHNldCBuYW1lXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZmllbGRTZXRzOiBzdHJpbmdbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIGNvbnRleHQ6IGFueVxyXG4gICAgICogVGhlIGN1cnJlbnQgY29udGV4dFxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGNvbnRleHQ6IGFueTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIGRlYnVnVmFsdWU6IGJvb2xlYW5cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBkZWJ1Z1ZhbHVlOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogcmVhZG9ubHk6IGJvb2xlYW5cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogc2VwYXJhdG9yS2V5c0NvZGVzOiBudW1iZXJbXVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIHNlcGFyYXRvcktleXNDb2RlczogbnVtYmVyW10gPSBbRU5URVIsIENPTU1BXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIGZpZWxkUm93czogRm9ybUZpZWxkRGVmaW5pdGlvbltdW11cclxuICAgICAqL1xyXG4gICAgcHVibGljIGZpZWxkUm93czogRm9ybUZpZWxkRGVmaW5pdGlvbltdW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBmaWVsZHM6IEZvcm1GaWVsZERlZmluaXRpb25bXVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmllbGRzOiBGb3JtRmllbGREZWZpbml0aW9uW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGb3JtRmllbGRUeXBlOiB0eXBlb2YgRm9ybUZpZWxkVHlwZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgRm9ybUZpZWxkVHlwZTogdHlwZW9mIEZvcm1GaWVsZFR5cGUgPSBGb3JtRmllbGRUeXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWRpdG9yIHRlbXBsYXRlXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoVmRFZGl0b3JEaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgZWRpdG9yVGVtcGxhdGU6IFZkRWRpdG9yRGlyZWN0aXZlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29kZSB0ZW1wbGF0ZVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKFZkQ29kZURpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBjb2RlVGVtcGxhdGU6IFZkQ29kZURpcmVjdGl2ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbGUgdGVtcGxhdGVcclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZEZpbGVEaXJlY3RpdmUpXHJcbiAgICBwdWJsaWMgZmlsZVRlbXBsYXRlOiBWZEZpbGVEaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDdXN0b20gdGVtcGxhdGVcclxuICAgICAqL1xyXG4gICAgQENvbnRlbnRDaGlsZChWZEN1c3RvbURpcmVjdGl2ZSlcclxuICAgIHB1YmxpYyBjdXN0b21UZW1wbGF0ZTogVmRDdXN0b21EaXJlY3RpdmU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDdXN0b21lciBkYXRlIGhlYWRlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZGF0ZVBpY2tlckhlYWRlckNvbXBvbmVudCA9IERhdGVQaWNrZXJIZWFkZXJDb21wb25lbnQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZW1wbGF0ZSByZWYgZm9yIGN1c3RvbSBmaWVsZHMgb24gdGhlIGJvdHRvbVxyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKCdib3R0b20nKVxyXG4gICAgcHVibGljIGJvdHRvbTogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBAQ29udGVudENoaWxkKCdjdXN0b21GaWVsZHMnKVxyXG4gICAgcHVibGljIGN1c3RvbUZpZWxkczogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIHJlZiBmb3IgY3VzdG9tIGZpZWxkcyBvbiB0aGUgYm90dG9tXHJcbiAgICAgKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oVmRHZW5lcmljRm9ybUN1c3RvbUZpZWxkRGlyZWN0aXZlKVxyXG4gICAgcHVibGljIGN1c3RvbUZpZWxkc1RlbXBsYXRlczogUXVlcnlMaXN0PFZkR2VuZXJpY0Zvcm1DdXN0b21GaWVsZERpcmVjdGl2ZT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaWx0ZXJkIG9wdGlvbnMgZm9yIGF1dG9jb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zOiB7fSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWxsYmFjayBtZXRob2QgdGhhdCBpcyBpbnZva2VkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZVxyXG4gICAgICogZGVmYXVsdCBjaGFuZ2UgZGV0ZWN0b3IgaGFzIGNoZWNrZWQgdGhlIGRpcmVjdGl2ZSdzXHJcbiAgICAgKiBkYXRhLWJvdW5kIHByb3BlcnRpZXMgZm9yIHRoZSBmaXJzdCB0aW1lLFxyXG4gICAgICogYW5kIGJlZm9yZSBhbnkgb2YgdGhlIHZpZXcgb3IgY29udGVudCBjaGlsZHJlbiBoYXZlIGJlZW4gY2hlY2tlZC5cclxuICAgICAqIEl0IGlzIGludm9rZWQgb25seSBvbmNlIHdoZW4gdGhlIGRpcmVjdGl2ZSBpcyBpbnN0YW50aWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgICAgIC8qIEJ1aWxkIHRoZSBmb3JtIGZpZWxkcyAqL1xyXG4gICAgICAgIGlmICh0aGlzLmNsYXNzVHlwZSAmJiAhdGhpcy5maWVsZEdyb3Vwcykge1xyXG4gICAgICAgICAgICB0aGlzLmJ1aWxkRmllbGRzKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBHZXQgZmlsZWQgcm93cyAqL1xyXG4gICAgICAgIHRoaXMuZmllbGRSb3dzID0gdGhpcy5maWVsZEdyb3Vwcz8uZmlsdGVyKHggPT4geC5uYW1lPy50cmltKCkgPT0gdGhpcy5ncm91cE5hbWU/LnRyaW0oKSlbMF0/Lmdyb3VwcztcclxuXHJcbiAgICAgICAgLyogRmlsdGVyIGJ5IGZpZWxkIHNldCAqL1xyXG4gICAgICAgIGlmICh0aGlzLmZpZWxkU2V0cykge1xyXG4gICAgICAgICAgICB0aGlzLmZpZWxkUm93cyA9IHRoaXMuZmllbGRSb3dzLm1hcCh4ID0+IHggPSB4LmZpbHRlcih5ID0+IHkuZmllbGRTZXRzPy5zb21lKHogPT4gdGhpcy5maWVsZFNldHM/LnNvbWUoYSA9PiBhPy50cmltKCk/LnRvTG93ZXJDYXNlKCkgPT0gej8udHJpbSgpPy50b0xvd2VyQ2FzZSgpKSkpKS5maWx0ZXIoeCA9PiB4Lmxlbmd0aCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBHZXQgYWxsIGZpZWxkcyAqL1xyXG4gICAgICAgIGxldCBmaWVsZHMgPSB0aGlzLmZpZWxkUm93cz8ucmVkdWNlKChhLCBiKSA9PiBhLmNvbmNhdChiKSwgW10pO1xyXG4gICAgICAgIHRoaXMuZmllbGRzID0gWy4uLmZpZWxkc107XHJcblxyXG4gICAgICAgIC8qIFN1YnNjcmllIHRvIGNoYW5nZSBldmVudCAqL1xyXG4gICAgICAgIGZpZWxkcz8uZmlsdGVyKHkgPT4geS50eXBlICE9IEZvcm1GaWVsZFR5cGUuRmlsZSAmJiB5LmNoYW5nZSk/LmZvckVhY2goeCA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUdyb3VwPy5nZXQoeC5uYW1lKT8udmFsdWVDaGFuZ2VzPy5zdWJzY3JpYmUoeSA9PiB4LmNoYW5nZSh5LCB0aGlzLmZvcm1Hcm91cD8udmFsdWUsIHRoaXMuZm9ybUdyb3VwLCB0aGlzLmNvbnRleHQpKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLyogVXBkYXRlIHNvbWUgdmFsdWVzIChsYWJlbCwgdHlwZSwgLi4uKSAqL1xyXG4gICAgICAgIGZpZWxkcy5mb3JFYWNoKHggPT4ge1xyXG4gICAgICAgICAgICB2YXIgb3JnRmllbGQgPSB0aGlzLmZpZWxkcy5maWx0ZXIoeSA9PiB5Lm5hbWUgPT0geC5uYW1lKVswXTtcclxuXHJcbiAgICAgICAgICAgIC8qIEdldCB0aGUgdHlwZSBhbmQgdGhlIGxhYmVsIG9mIHRoZSBmaWVsZCAqL1xyXG4gICAgICAgICAgICBsZXQgdHlwZSA9IG9yZ0ZpZWxkPy50eXBlO1xyXG4gICAgICAgICAgICBsZXQgbGFiZWwgPSBvcmdGaWVsZD8ubGFiZWw7XHJcblxyXG4gICAgICAgICAgICAvKiBSZW5kZXIgdGhlIGZpZWxkIHR5cGUgKi9cclxuICAgICAgICAgICAgeC50eXBlID0gKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSA/IHR5cGUodGhpcy5mb3JtVmFsdWUsIHRoaXMuZm9ybUdyb3VwLCB0aGlzLmNvbnRleHQpIDogeC50eXBlO1xyXG5cclxuICAgICAgICAgICAgLyogUmVuZGVyIHRoZSBmaWVsZCBsYWJlbCAqL1xyXG4gICAgICAgICAgICB4LmxhYmVsID0gKHR5cGVvZiBsYWJlbCA9PT0gJ2Z1bmN0aW9uJykgPyBsYWJlbCh0aGlzLmZvcm1WYWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkgOiB4LmxhYmVsO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mb3JtR3JvdXA/LnZhbHVlQ2hhbmdlcz8uc3Vic2NyaWJlKHkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLyogUmVuZGVyIHRoZSBmaWVsZCB0eXBlICovXHJcbiAgICAgICAgICAgICAgICB4LnR5cGUgPSAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpID8gdHlwZSh5LCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KSA6IHgudHlwZTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKiBSZW5kZXIgdGhlIGZpZWxkIGxhYmVsICovXHJcbiAgICAgICAgICAgICAgICB4LmxhYmVsID0gKHR5cGVvZiBsYWJlbCA9PT0gJ2Z1bmN0aW9uJykgPyBsYWJlbCh5LCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KSA6IHgubGFiZWw7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyBhdXRvY29tcGxldGUgZXZlbnRcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSBldmVudCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGZpbHRlckF1dG9jb21wbGV0ZShmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWVdID0gZmllbGQub3B0aW9ucz8uZmlsdGVyKG9wdGlvbiA9PiBvcHRpb24ubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGV2ZW50LnZhbHVlPy50b1N0cmluZygpPy50b0xvd2VyQ2FzZSgpKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGEgY2hpcCB3aGVuIGEgYXV0b2NvbXBsZXRlIHZhbHVlIGlzIHNlbGVjdGVkXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdXRvY29tcGxldGVWYWx1ZVNlbGVjdGVkKGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBldmVudDogTWF0QXV0b2NvbXBsZXRlU2VsZWN0ZWRFdmVudCwgY2hpcElucHV0RXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2FkZENoaXAoZmllbGQsIGV2ZW50Lm9wdGlvbi52aWV3VmFsdWUpO1xyXG4gICAgICAgIGNoaXBJbnB1dEV2ZW50LnZhbHVlID0gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGEgY2hpcFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICogQHBhcmFtIGV2ZW50IFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRkQ2hpcChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgZXZlbnQ6IE1hdENoaXBJbnB1dEV2ZW50KTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fYWRkQ2hpcChmaWVsZCwgZXZlbnQudmFsdWUpO1xyXG4gICAgICAgIGV2ZW50LmNoaXBJbnB1dCEuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYSBjaGlwXHJcbiAgICAgKiBAcGFyYW0gZmllbGQgXHJcbiAgICAgKiBAcGFyYW0gY2hpcCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlbW92ZUNoaXAoZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGNoaXA6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIC8qIEdldCB0aGUgZm9ybSBjb250cm9sIHVzaW5nIHRoZSBmaWVsZCBuYW1lICovXHJcbiAgICAgICAgbGV0IGNvbnRyb2wgPSB0aGlzLmZvcm1Hcm91cD8uY29udHJvbHNbZmllbGQubmFtZV07XHJcblxyXG4gICAgICAgIC8qIEdldCB0aGUgaW5kZXggb2YgdGhlIGNoaXAgKi9cclxuICAgICAgICBjb25zdCBpbmRleCA9IGNvbnRyb2wudmFsdWUuaW5kZXhPZihjaGlwKTtcclxuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xyXG4gICAgICAgICAgICBjb250cm9sLnZhbHVlLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIGNoaXBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqIEBwYXJhbSB2YWx1ZSBcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfYWRkQ2hpcChmaWVsZDogRm9ybUZpZWxkRGVmaW5pdGlvbiwgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIC8qIEdldCB0aGUgZm9ybSBjb250cm9sIHVzaW5nIHRoZSBmaWVsZCBuYW1lICovXHJcbiAgICAgICAgbGV0IGNvbnRyb2wgPSB0aGlzLmZvcm1Hcm91cD8uY29udHJvbHNbZmllbGQubmFtZV07XHJcblxyXG4gICAgICAgIC8qIEdldCB0aGUgdmFsdWUgb2YgdGhlIGNoaXAgKi9cclxuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8fCAnJykudHJpbSgpO1xyXG4gICAgICAgIGlmIChjb250cm9sICYmIHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoZmllbGQuaW5wdXRUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdudW1iZXInOlxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBudW1iZXIgPSBwYXJzZUludCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG51bWJlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2gobnVtYmVyKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgY2FzZSAnZmxvYXQnOlxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBmbG9hdCA9IHBhcnNlRmxvYXQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmbG9hdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLnZhbHVlLnB1c2goZmxvYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2wudmFsdWUucHVzaCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcyBkYXRlIHBpY2tlciBvcGVuZWQgZXZlbnRcclxuICAgICAqIEBwYXJhbSBkYXRlUGlja2VyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlRGF0ZVBpY2tlck9wZW5lZChkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlUGlja2VyT3BlbmVkKSB7XHJcbiAgICAgICAgICAgIGZpZWxkLmRhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGRhdGUgZmlsdGVyIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0gZGF0ZVBpY2tlciBcclxuICAgICAqIEBwYXJhbSBmaWVsZCBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGhhbmRsZURhdGVQaWNrZXJGaWx0ZXJBc3luYyhkYXRlUGlja2VyOiBNYXREYXRlcGlja2VyPGFueT4sIGZpZWxkOiBGb3JtRmllbGREZWZpbml0aW9uLCBkYXRlOiBEYXRlIHwgYW55KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZpZWxkPy5kYXRlRmlsdGVyQXN5bmMpIHtcclxuICAgICAgICAgICAgLyogRGlzYWJsZXMgYWxsIGRhdGVzICovXHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIuZGF0ZXBpY2tlcklucHV0LmRhdGVGaWx0ZXIgPSAoZDogRGF0ZSkgPT4gZmFsc2U7XHJcbiAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICBmaWVsZC5kYXRlRmlsdGVyQXN5bmMoZGF0ZSwgdGhpcy5mb3JtR3JvdXA/LnZhbHVlLCB0aGlzLmZvcm1Hcm91cCwgdGhpcy5jb250ZXh0KS5zdWJzY3JpYmUoeCA9PiB7XHJcbiAgICAgICAgICAgICAgICBkYXRlUGlja2VyLmRhdGVwaWNrZXJJbnB1dC5kYXRlRmlsdGVyID0gKGQ6IERhdGUpID0+IGQgJiYgeChkKTtcclxuICAgICAgICAgICAgICAgIGRhdGVQaWNrZXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIGNhbGVuZGFyIGZpbHRlciBldmVudFxyXG4gICAgICogQHBhcmFtIGNhbGVuZGFyIFxyXG4gICAgICogQHBhcmFtIGZpZWxkIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlQ2FsZW5kYXJGaWx0ZXJBc3luYyhjYWxlbmRhcjogTWF0Q2FsZW5kYXI8YW55PiwgZmllbGQ6IEZvcm1GaWVsZERlZmluaXRpb24sIGRhdGU6IERhdGUgfCBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZmllbGQ/LmRhdGVGaWx0ZXJBc3luYykge1xyXG4gICAgICAgICAgICAvKiBEaXNhYmxlcyBhbGwgZGF0ZXMgKi9cclxuICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBmYWxzZTtcclxuICAgICAgICAgICAgY2FsZW5kYXIubmdPbkNoYW5nZXMoPFNpbXBsZUNoYW5nZXM+eyAnZGF0ZUZpbHRlcic6IG5ldyBTaW1wbGVDaGFuZ2UoXCJcIiwgXCJcIiwgZmFsc2UpIH0pO1xyXG5cclxuICAgICAgICAgICAgLyogVmFsaWRhdGUgZGF0ZSBhc3luY2x5LiAqL1xyXG4gICAgICAgICAgICB2YXIgc3Vic2NyaXB0aW9uID0gZmllbGQuZGF0ZUZpbHRlckFzeW5jKGRhdGUsIHRoaXMuZm9ybUdyb3VwPy52YWx1ZSwgdGhpcy5mb3JtR3JvdXAsIHRoaXMuY29udGV4dCkuc3Vic2NyaWJlKHggPT4ge1xyXG4gICAgICAgICAgICAgICAgY2FsZW5kYXIuZGF0ZUZpbHRlciA9IChkOiBEYXRlKSA9PiBkICYmIHgoZCk7XHJcbiAgICAgICAgICAgICAgICBjYWxlbmRhci5uZ09uQ2hhbmdlcyg8U2ltcGxlQ2hhbmdlcz57ICdkYXRlRmlsdGVyJzogbmV3IFNpbXBsZUNoYW5nZShcIlwiLCBcIlwiLCBmYWxzZSkgfSk7XHJcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQnVpbGRzIHRoZSBmb3JtIGZpZWxkc1xyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYnVpbGRGaWVsZHMoKTogdm9pZCB7XHJcbiAgICAgICAgLyogR2V0IGZvcm0gZGVmaW5pdGlvbiAqL1xyXG4gICAgICAgIHRoaXMuZm9ybURlZmluaXRpb24gPSBnZXRGb3JtRGVmaW5pdGlvbihuZXcgdGhpcy5jbGFzc1R5cGUoKSk7XHJcblxyXG4gICAgICAgIC8qIENyZWF0ZSB0aGUgZnJvbSBmaWVsZHMgdXNpbmcgdGhlIGVudGl0eSB0eXBlICovXHJcbiAgICAgICAgdGhpcy5maWVsZEdyb3VwcyA9IHRoaXMuZm9ybURlZmluaXRpb24/LmZpZWxkR3JvdXBzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9nIHRvIGNvbnNvbGVcclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFxyXG4gICAgICogQHBhcmFtIG9wdGlvbmFsUGFyYW1zIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9nKG1lc3NhZ2U6IGFueSwgLi4ub3B0aW9uYWxQYXJhbXM6IGFueVtdKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2cobWVzc2FnZSwgb3B0aW9uYWxQYXJhbXMpO1xyXG4gICAgfVxyXG59IiwiPGRpdiAqbmdJZj1cImZvcm1Hcm91cCAmJiBmaWVsZFJvd3NcIiBbZm9ybUdyb3VwXT1cImZvcm1Hcm91cFwiPlxyXG4gICAgPCEtLSAjcmVnaW9uIEZpZWxkcyAtLT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkcyBvZiBmaWVsZFJvd3M7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICA8ZGl2IGxheW91dC1ndC1zbT1cInJvd1wiIGxheW91dD1cImNvbHVtblwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmaWVsZHNcIiBbbmdTd2l0Y2hdPVwiZmllbGQudHlwZVwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmaWVsZC5oaWRlIHx8ICFmaWVsZC5oaWRlKGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWVsZC53cmFwcGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBUZXh0IGlucHV0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVGV4dFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cImZpZWxkLmlucHV0VHlwZVwiIFttaW5sZW5ndGhdPVwiZmllbGQubWluTGVuZ3RofHxudWxsXCIgW21heGxlbmd0aF09XCJmaWVsZC5tYXhMZW5ndGh8fG51bGxcIiBbbWluXT1cImZpZWxkLm1pblwiIFttYXhdPVwiZmllbGQubWF4XCIgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW3JlYWRvbmx5XT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gVGV4dGFyZWEgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5UZXh0QXJlYVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIG1hdElucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIHJvd3M9XCJmaWVsZC5yb3dzfHwyXCIgW3JlYWRvbmx5XT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpXCI+PC90ZXh0YXJlYT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBFbnVtIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuRW51bVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHZkLXNlbGVjdCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiBbZW51bV09XCJmaWVsZC5lbnVtVHlwZVwiIFtlbnVtRmlsdGVyXT1cImZpZWxkLmVudW1GaWx0ZXIgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtrZXldPVwiZmllbGQub3B0aW9uVmFsdWVcIiBbdGV4dF09XCJmaWVsZC5vcHRpb25UZXh0XCIgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCIgW3JlYWRvbmx5XT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpXCIgW3RyaWdnZXJDc3NDbGFzc109XCJmaWVsZC50cmlnZ2VyQ3NzQ2xhc3NcIiBbdHJpZ2dlck1vZGVdPVwiZmllbGQudHJpZ2dlck1vZGVcIiBsYXlvdXQ9XCJyb3dcIiBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3QtdHJpZ2dlciBsZXQtdHJpZ2dlcj1cInRyaWdnZXJcIiAqbmdJZj1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZSh0cmlnZ2VyLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LW9wdGlvbiBsZXQtb3B0aW9uPVwib3B0aW9uXCIgKm5nSWY9XCJmaWVsZC5vcHRpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbb3V0ZXJIVE1MXT1cImZpZWxkLm9wdGlvblRlbXBsYXRlKG9wdGlvbiwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3ZkLXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZFNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlZkU2VsZWN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmQtc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIFtlbmRwb2ludF09XCJmaWVsZC5lbmRwb2ludCB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIiBbbWFwcGVyXT1cImZpZWxkLm1hcHBlclwiIFtjb21wYXJlV2l0aF09XCJmaWVsZC5jb21wYXJlV2l0aFwiIFtsb2FkRGF0YV09XCJmaWVsZC5mZXRjaENvbmRpdGlvbiB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW2tleV09XCJmaWVsZC5vcHRpb25WYWx1ZVwiIFt0ZXh0XT1cImZpZWxkLm9wdGlvblRleHRcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIiBbdHJpZ2dlckNzc0NsYXNzXT1cImZpZWxkLnRyaWdnZXJDc3NDbGFzc1wiIFt0cmlnZ2VyTW9kZV09XCJmaWVsZC50cmlnZ2VyTW9kZVwiIChpdGVtU2VsZWN0ZWQpPVwiZmllbGQuaXRlbVNlbGVjdCAmJiBmaWVsZC5pdGVtU2VsZWN0KCRldmVudCwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpO1wiIChpdGVtQ2hhbmdlKT1cImZpZWxkLml0ZW1DaGFuZ2UgJiYgZmllbGQuaXRlbUNoYW5nZSgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiBsYXlvdXQ9XCJyb3dcIiBmbGV4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSB2ZC1zZWxlY3QtdHJpZ2dlciBsZXQtdHJpZ2dlcj1cInRyaWdnZXJcIiAqbmdJZj1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIVE1MXT1cImZpZWxkLnRyaWdnZXJUZW1wbGF0ZSh0cmlnZ2VyLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtc2VsZWN0LXRyaWdnZXIgbGV0LXRyaWdnZXI9XCJ0cmlnZ2VyXCIgKm5nSWY9XCJmaWVsZC50cmlnZ2VyTWFwcGVyICYmIGZpZWxkLm11bHRpcGxlICYmIGZpZWxkLnRyaWdnZXJNb2RlID09ICdjaGlwJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiB0cmlnZ2VyXCIgY2xhc3M9XCJtYXQtbWRjLWNoaXAgbWF0LW1kYy1zdGFuZGFyZC1jaGlwIG1hdC1wcmltYXJ5IG1hdC1tZGMtY2hpcC1zZWxlY3RlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySFRNTF09XCJmaWVsZC50cmlnZ2VyTWFwcGVyKGl0ZW0sIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLXNlbGVjdC1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiICpuZ0lmPVwiZmllbGQub3B0aW9uVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW291dGVySFRNTF09XCJmaWVsZC5vcHRpb25UZW1wbGF0ZShvcHRpb24sIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC92ZC1zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gVmRMaXN0IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVmRMaXN0XCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgZmxvYXRMYWJlbD1cImFsd2F5c1wiIGNsYXNzPVwiZm9ybS1maWVsZC10eXBlLWxpc3RcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx2ZC1saXN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIFtlbmRwb2ludF09XCJmaWVsZC5lbmRwb2ludCB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW3BhcmFtc109XCJmaWVsZC5wYXJhbXMgfCBmdW5jOmZvcm1WYWx1ZTpmb3JtR3JvdXA6Y29udGV4dFwiIFtwcm9qZWN0aW9uXT1cImZpZWxkLnByb2plY3Rpb25cIiBbbWFwcGVyXT1cImZpZWxkLm1hcHBlclwiIFtjb21wYXJlV2l0aF09XCJmaWVsZC5jb21wYXJlV2l0aFwiIFtsb2FkRGF0YV09XCJmaWVsZC5mZXRjaENvbmRpdGlvbiB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW2tleV09XCJmaWVsZC5vcHRpb25WYWx1ZVwiIFt0ZXh0XT1cImZpZWxkLm9wdGlvblRleHRcIiBbbXVsdGlwbGVdPVwiZmllbGQubXVsdGlwbGVcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIiAoaXRlbVNlbGVjdGVkKT1cImZpZWxkLml0ZW1TZWxlY3QgJiYgZmllbGQuaXRlbVNlbGVjdCgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiAoaXRlbUNoYW5nZSk9XCJmaWVsZC5pdGVtQ2hhbmdlICYmIGZpZWxkLml0ZW1DaGFuZ2UoJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgW3N0eWxlLm1heC13aWR0aF09XCJmaWVsZC5tYXhXaWR0aFwiIFtzdHlsZS5tYXgtaGVpZ2h0XT1cImZpZWxkLm1heEhlaWdodFwiIGZsZXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLWxpc3Qtb3B0aW9uIGxldC1vcHRpb249XCJvcHRpb25cIiAqbmdJZj1cImZpZWxkLm9wdGlvblRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtvdXRlckhUTUxdPVwiZmllbGQub3B0aW9uVGVtcGxhdGUob3B0aW9uLCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dClcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtbGlzdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDaGlwcyAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkNoaXBzXCIgW2F0dHIuZmxleF09XCJmaWVsZC5mbGV4fHwwXCIgW2NsYXNzXT1cImZpZWxkLmNzc0NsYXNzXCIgbGF5b3V0LW1hcmdpbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3tmaWVsZC5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoaXAtZ3JpZCAjY2hpcExpc3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW2Rpc2FibGVDb250cm9sXT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGlwLXJvdyAqbmdGb3I9XCJsZXQgY2hpcCBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV0/LnZhbHVlXCIgKHJlbW92ZWQpPVwicmVtb3ZlQ2hpcChmaWVsZCwgY2hpcClcIiBjb2xvcj1cInByaW1hcnlcIiBzZWxlY3RhYmxlPVwidHJ1ZVwiIHNlbGVjdGVkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57e2NoaXB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXRDaGlwUmVtb3ZlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNhbmNlbDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoaXAtcm93PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBbcGxhY2Vob2xkZXJdPVwiJGFueShmaWVsZC5sYWJlbClcIiAjY2hpcElucHV0IFttYXRDaGlwSW5wdXRGb3JdPVwiY2hpcExpc3RcIiBbbWF0Q2hpcElucHV0U2VwYXJhdG9yS2V5Q29kZXNdPVwic2VwYXJhdG9yS2V5c0NvZGVzXCIgW21hdEF1dG9jb21wbGV0ZV09XCJjaGlwQXV0b2NvbXBsZXRlXCIgKGlucHV0KT1cImZpbHRlckF1dG9jb21wbGV0ZShmaWVsZCwgY2hpcElucHV0KVwiIChtYXRDaGlwSW5wdXRUb2tlbkVuZCk9XCJhZGRDaGlwKGZpZWxkLCAkZXZlbnQpXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGlwLWdyaWQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWF1dG9jb21wbGV0ZSBhdXRvQWN0aXZlRmlyc3RPcHRpb24gI2NoaXBBdXRvY29tcGxldGU9XCJtYXRBdXRvY29tcGxldGVcIiBbY2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIiAob3B0aW9uU2VsZWN0ZWQpPVwiYXV0b2NvbXBsZXRlVmFsdWVTZWxlY3RlZChmaWVsZCwgJGV2ZW50LCBjaGlwSW5wdXQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBhdXRvY29tcGxldGVGaWx0ZXJlZE9wdGlvbnNbZmllbGQubmFtZV1cIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9uLm5hbWV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWF1dG9jb21wbGV0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN1ZmZpeEJ1dHRvbiBvZiBmaWVsZC5zdWZmaXhCdXR0b25zXCIgKGNsaWNrKT1cInN1ZmZpeEJ1dHRvbi5ldmVudCAmJiBzdWZmaXhCdXR0b24uZXZlbnQoZm9ybVZhbHVlLCBjb250ZXh0KVwiIG1hdFN1ZmZpeD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCIhc3VmZml4QnV0dG9uLmhpZGUgfHwgIXN1ZmZpeEJ1dHRvbi5oaWRlKGZvcm1WYWx1ZSwgY29udGV4dClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7c3VmZml4QnV0dG9uLmljb259fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCAqbmdJZj1cImZpZWxkLmhpbnRcIj57e2ZpZWxkLmhpbnR9fTwvbWF0LWhpbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0Zvcj1cImxldCBlcnJvck1lc3NhZ2Ugb2YgZm9ybUdyb3VwLmNvbnRyb2xzW2ZpZWxkLm5hbWVdWydlcnJvck1lc3NhZ2VzJ11cIj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBWZENoaXBzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuVmRDaGlwc1wiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHZkLWNoaXBzICN2ZENoaXAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW2VuZHBvaW50XT1cImZpZWxkLmVuZHBvaW50IHwgZnVuYzpmb3JtVmFsdWU6Zm9ybUdyb3VwOmNvbnRleHRcIiBbcGFyYW1zXT1cImZpZWxkLnBhcmFtcyB8IGZ1bmM6Zm9ybVZhbHVlOmZvcm1Hcm91cDpjb250ZXh0XCIgW3NlYXJjaEZpZWxkXT1cImZpZWxkLnNlYXJjaEZpZWxkXCIgW2NsYXNzVHlwZV09XCJmaWVsZC5jbGFzc1R5cGVcIiBbcHJvamVjdGlvbl09XCJmaWVsZC5wcm9qZWN0aW9uXCIgW2tleV09XCJmaWVsZC5vcHRpb25WYWx1ZVwiIFtyZWFkb25seV09XCJyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiIFtyZW1vdmFibGVdPVwiIWZpZWxkLmNsZWFyXCIgW2NvbnRleHRdPVwiY29udGV4dFwiIFtzdWZmaXhCdXR0b25zXT1cImZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiBbYXV0b2NvbXBsZXRlQ3NzQ2xhc3NdPVwiZmllbGQuYXV0b2NvbXBsZXRlQ3NzQ2xhc3NcIiAoaW5pdFNlbGVjdCk9XCJmaWVsZC5pdGVtU2VsZWN0ICYmIGZpZWxkLml0ZW1TZWxlY3QoJGV2ZW50LCBmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgKHNlbGVjdGVkKT1cImZpZWxkLml0ZW1DaGFuZ2UgJiYgZmllbGQuaXRlbUNoYW5nZSgkZXZlbnQsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KTtcIiAoY2xlYXJlZCk9XCJmaWVsZC5jbGVhciAmJiBmaWVsZC5jbGVhcihmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCk7XCIgW2N1c3RvbVZhbHVlXT1cImZpZWxkLmN1c3RvbVZhbHVlXCIgbGF5b3V0PVwicm93XCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgdmQtY2hpcCBsZXQtY2hpcD1cImNoaXBcIiAqbmdJZj1cImZpZWxkLmNoaXBUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtvdXRlckhUTUxdPVwiZmllbGQuY2hpcFRlbXBsYXRlKGNoaXAsIGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHZkLWF1dG9jb21wbGV0ZS1vcHRpb24gbGV0LW9wdGlvbj1cIm9wdGlvblwiICpuZ0lmPVwiZmllbGQuYXV0b2NvbXBsZXRlVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbb3V0ZXJIVE1MXT1cImZpZWxkLmF1dG9jb21wbGV0ZVRlbXBsYXRlKG9wdGlvbiwgZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdmQtY2hpcHM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwidmRDaGlwLmVtcHR5UmVzdWx0XCIgY2xhc3M9XCJ0Yy1yZWQtNDAwXCIgaTE4bj1cIkBAbm9SZXN1bHRzRm91bmRcIj5ObyByZXN1bHRzIHdlcmUgZm91bmQuPC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV1bJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLlNlbGVjdFwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW211bHRpcGxlXT1cImZpZWxkLm11bHRpcGxlXCIgW2Rpc2FibGVDb250cm9sXT1cInJlYWRvbmx5IHx8IChmaWVsZC5yZWFkb25seSAmJiBmaWVsZC5yZWFkb25seShmb3JtVmFsdWUsIGZvcm1Hcm91cCwgY29udGV4dCkpXCIgZmxleD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGZpZWxkLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLmlkXCI+e3tvcHRpb24ubmFtZX19PC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3VmZml4QnV0dG9uIG9mIGZpZWxkLnN1ZmZpeEJ1dHRvbnNcIiAoY2xpY2spPVwic3VmZml4QnV0dG9uLmV2ZW50ICYmIHN1ZmZpeEJ1dHRvbi5ldmVudChmb3JtVmFsdWUsIGNvbnRleHQpXCIgbWF0U3VmZml4PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAqbmdJZj1cIiFzdWZmaXhCdXR0b24uaGlkZSB8fCAhc3VmZml4QnV0dG9uLmhpZGUoZm9ybVZhbHVlLCBjb250ZXh0KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+e3tzdWZmaXhCdXR0b24uaWNvbn19PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV1bJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIEF1dG9jb21wbGV0ZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkF1dG9jb21wbGV0ZVwiIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIFtjbGFzc109XCJmaWVsZC5jc3NDbGFzc1wiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgbWF0SW5wdXQgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgW21pbl09XCJmaWVsZC5taW5cIiBbbWF4XT1cImZpZWxkLm1heFwiIFttYXRBdXRvY29tcGxldGVdPVwiYXV0b1wiICNhdXRvY29tcGxldGVJbnB1dCAoaW5wdXQpPVwiZmlsdGVyQXV0b2NvbXBsZXRlKGZpZWxkLCBhdXRvY29tcGxldGVJbnB1dClcIiBhdXRvY29tcGxldGU9XCJvZmZcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtYXV0b2NvbXBsZXRlIGF1dG9BY3RpdmVGaXJzdE9wdGlvbiAjYXV0bz1cIm1hdEF1dG9jb21wbGV0ZVwiIFtjbGFzc109XCJmaWVsZC5hdXRvY29tcGxldGVDc3NDbGFzc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgYXV0b2NvbXBsZXRlRmlsdGVyZWRPcHRpb25zW2ZpZWxkLm5hbWVdXCIgW3ZhbHVlXT1cIm9wdGlvbi5pZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e29wdGlvbi5uYW1lfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1hdXRvY29tcGxldGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdWZmaXhCdXR0b24gb2YgZmllbGQuc3VmZml4QnV0dG9uc1wiIChjbGljayk9XCJzdWZmaXhCdXR0b24uZXZlbnQgJiYgc3VmZml4QnV0dG9uLmV2ZW50KGZvcm1WYWx1ZSwgY29udGV4dClcIiBtYXRTdWZmaXg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIXN1ZmZpeEJ1dHRvbi5oaWRlIHx8ICFzdWZmaXhCdXR0b24uaGlkZShmb3JtVmFsdWUsIGNvbnRleHQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57e3N1ZmZpeEJ1dHRvbi5pY29ufX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQgKm5nSWY9XCJmaWVsZC5oaW50XCI+e3tmaWVsZC5oaW50fX08L21hdC1oaW50PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCI+e3tlcnJvck1lc3NhZ2V9fTwvbWF0LWVycm9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gRGF0ZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkRhdGVcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiBbbWluXT1cImZpZWxkLm1pblwiIFttYXhdPVwiZmllbGQubWF4XCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW21hdERhdGVwaWNrZXJdPVwiZGF0ZVBpY2tlclwiIFttYXREYXRlcGlja2VyRmlsdGVyXT1cImZpZWxkLmRhdGVGaWx0ZXJcIiBbcmVhZG9ubHldPVwicmVhZG9ubHkgfHwgZmllbGQuZm9yY2VTZWxlY3QgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZGF0ZXBpY2tlci10b2dnbGUgbWF0U3VmZml4IFtmb3JdPVwiZGF0ZVBpY2tlclwiPjwvbWF0LWRhdGVwaWNrZXItdG9nZ2xlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlcGlja2VyICNkYXRlUGlja2VyIFtkaXNhYmxlZF09XCJyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiIChtb250aFNlbGVjdGVkKT1cImhhbmRsZURhdGVQaWNrZXJGaWx0ZXJBc3luYyhkYXRlUGlja2VyLCBmaWVsZCwgJGV2ZW50IClcIiAob3BlbmVkKT1cImhhbmRsZURhdGVQaWNrZXJPcGVuZWQoZGF0ZVBpY2tlciwgZmllbGQpXCIgW2NhbGVuZGFySGVhZGVyQ29tcG9uZW50XT1cImRhdGVQaWNrZXJIZWFkZXJDb21wb25lbnRcIj48L21hdC1kYXRlcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZmllbGQuaGludFwiPnt7ZmllbGQuaGludH19PC9tYXQtaGludD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yTWVzc2FnZSBvZiBmb3JtR3JvdXAuY29udHJvbHNbZmllbGQubmFtZV1bJ2Vycm9yTWVzc2FnZXMnXVwiPnt7ZXJyb3JNZXNzYWdlfX08L21hdC1lcnJvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENhbGVuZGFyIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2FsZW5kYXJcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIiBmbG9hdExhYmVsPVwiYWx3YXlzXCIgY2xhc3M9XCJmb3JtLWZpZWxkLXR5cGUtY2FsZW5kYXJcIiBsYXlvdXQtbWFyZ2luPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57e2ZpZWxkLmxhYmVsfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpbnB1dD1cImhpZGRlblwiIGhpZGRlbiBtYXRJbnB1dCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2FsZW5kYXIgI2NhbGVuZGFyIFtzZWxlY3RlZF09XCJmb3JtR3JvdXAuZ2V0KGZpZWxkLm5hbWUpLnZhbHVlXCIgKHNlbGVjdGVkQ2hhbmdlKT1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSkuc2V0VmFsdWUoJGV2ZW50KTtcIiAobW9udGhTZWxlY3RlZCk9XCJoYW5kbGVDYWxlbmRhckZpbHRlckFzeW5jKGNhbGVuZGFyLCBmaWVsZCwgJGV2ZW50IClcIiBbaGVhZGVyQ29tcG9uZW50XT1cImRhdGVQaWNrZXJIZWFkZXJDb21wb25lbnRcIiBzdHlsZT1cIndpZHRoOiAxMDAlO1wiPjwvbWF0LWNhbGVuZGFyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3JNZXNzYWdlIG9mIGZvcm1Hcm91cC5jb250cm9sc1tmaWVsZC5uYW1lXVsnZXJyb3JNZXNzYWdlcyddXCIgbGF5b3V0LW1hcmdpbj57e2Vycm9yTWVzc2FnZX19PC9tYXQtZXJyb3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjcmVnaW9uIENoZWNrYm94IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ2hlY2tib3hcIiBbYXR0ci5mbGV4XT1cImZpZWxkLmZsZXh8fDBcIiBbY2xhc3NdPVwiZmllbGQuY3NzQ2xhc3NcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiBbZGlzYWJsZUNvbnRyb2xdPVwicmVhZG9ubHkgfHwgKGZpZWxkLnJlYWRvbmx5ICYmIGZpZWxkLnJlYWRvbmx5KGZvcm1WYWx1ZSwgZm9ybUdyb3VwLCBjb250ZXh0KSlcIj57e2ZpZWxkLmxhYmVsfX08L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBFZGl0b3IgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiRm9ybUZpZWxkVHlwZS5FZGl0b3JcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiZWRpdG9yVGVtcGxhdGU/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiZWRpdG9yVGVtcGxhdGU/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgZmllbGQ6IGZpZWxkLCBmb3JtR3JvdXA6IGZvcm1Hcm91cCB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gI3JlZ2lvbiBDb2RlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ29kZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJjb2RlVGVtcGxhdGU/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29kZVRlbXBsYXRlPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGZpZWxkOiBmaWVsZCwgZm9ybUdyb3VwOiBmb3JtR3JvdXAgfVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gRmlsZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJGb3JtRmllbGRUeXBlLkZpbGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFthdHRyLmZsZXhdPVwiZmllbGQuZmxleHx8MFwiIGxheW91dC1tYXJnaW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ZmllbGQubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiB2ZC1maWxlLWlucHV0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIChzZWxlY3QpPVwiZmllbGQuY2hhbmdlICYmIGZpZWxkLmNoYW5nZShmaWVsZCwgJGV2ZW50LCBmb3JtR3JvdXAsIGNvbnRleHQpXCIgW2FjY2VwdF09XCJmaWVsZC5maWxlRXh0ZW5zaW9uc1wiIFtkaXNhYmxlQ29udHJvbF09XCJyZWFkb25seSB8fCAoZmllbGQucmVhZG9ubHkgJiYgZmllbGQucmVhZG9ubHkoZm9ybVZhbHVlLCBmb3JtR3JvdXAsIGNvbnRleHQpKVwiIGZsZXg+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tICNyZWdpb24gQ3VzdG9tIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkZvcm1GaWVsZFR5cGUuQ3VzdG9tXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImN1c3RvbVRlbXBsYXRlPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbVRlbXBsYXRlPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGZpZWxkOiBmaWVsZCwgZm9ybUdyb3VwOiBmb3JtR3JvdXAgfVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPCEtLSAjcmVnaW9uIFRlbXBsYXRlIGZvciBjdXN0b20gZmllbGRzIC0tPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjdXN0b21GaWVsZCBvZiBjdXN0b21GaWVsZHNUZW1wbGF0ZXNcIj5cclxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdJZj1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZiAmJiBjdXN0b21GaWVsZC5yb3cgPT0gZmllbGRzWzBdPy5yb3cgJiYgY3VzdG9tRmllbGQuaW5saW5lXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntmb3JtR3JvdXA6IGZvcm1Hcm91cH1cIj48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tICNyZWdpb24gVGVtcGxhdGUgZm9yIGN1c3RvbSBmaWVsZHMgLS0+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjdXN0b21GaWVsZHNcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2Zvcm1Hcm91cDogZm9ybUdyb3VwLCByb3c6IGZpZWxkc1swXT8ucm93ICsgMX1cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjdXN0b21GaWVsZCBvZiBjdXN0b21GaWVsZHNUZW1wbGF0ZXNcIj5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiY3VzdG9tRmllbGQ/LnRlbXBsYXRlUmVmICYmIGN1c3RvbUZpZWxkLnJvdyA9PSAoZmllbGRzWzBdPy5yb3crMSkgJiYgIWN1c3RvbUZpZWxkLmlubGluZVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbUZpZWxkPy50ZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXB9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwhLS0gI2VuZHJlZ2lvbiAtLT5cclxuXHJcbiAgICA8IS0tICNyZWdpb24gRm9ybSBib3R0b20gLS0+XHJcbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImJvdHRvbVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Zm9ybUdyb3VwOiBmb3JtR3JvdXB9XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICA8IS0tICNlbmRyZWdpb24gLS0+XHJcblxyXG4gICAgPCEtLSAjcmVnaW9uIERlYnVnIHZhbHVlIC0tPlxyXG4gICAgPGNvZGUgKm5nSWY9XCJkZWJ1Z1ZhbHVlXCI+XHJcbiAgICAgICAgPHByZT57e2Zvcm1WYWx1ZSB8IGpzb259fTwvcHJlPlxyXG4gICAgPC9jb2RlPlxyXG4gICAgPCEtLSAjZW5kcmVnaW9uIC0tPlxyXG48L2Rpdj4iXX0=
|