@ng-flexy/form-bootstrap
Version:
Flexy components and tools to build Angular 8+ applications
329 lines • 36.1 kB
JavaScript
import { Component, Input } from '@angular/core';
import { isRequired } from '@ng-flexy/form';
import { FormControl, Validators } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "@ng-flexy/form";
import * as i2 from "@ng-flexy/toasts";
import * as i3 from "@ngx-translate/core";
import * as i4 from "@angular/common";
import * as i5 from "ngx-bootstrap/tooltip";
import * as i6 from "./field.component";
import * as i7 from "../controls/text.component";
import * as i8 from "./field-info.component";
function FlexyFormGroupComponent_span_2_span_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "span", 7);
i0.ɵɵpipe(1, "translate");
i0.ɵɵtext(2, "(");
i0.ɵɵelementStart(3, "b");
i0.ɵɵtext(4, "*");
i0.ɵɵelementEnd();
i0.ɵɵtext(5, ")");
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵproperty("tooltip", i0.ɵɵpipeBind1(1, 1, "FLEXY_FORM_FIELD_IS_REQUIRED"));
} }
function FlexyFormGroupComponent_span_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "span");
i0.ɵɵtext(1);
i0.ɵɵtemplate(2, FlexyFormGroupComponent_span_2_span_2_Template, 6, 3, "span", 6);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵtextInterpolate1(" ", ctx_r0.legend, " ");
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r0.isRequired);
} }
function FlexyFormGroupComponent_div_3_Template(rf, ctx) { if (rf & 1) {
const _r8 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "div", 8);
i0.ɵɵelementStart(1, "button", 9);
i0.ɵɵlistener("click", function FlexyFormGroupComponent_div_3_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r7 = i0.ɵɵnextContext(); ctx_r7.isAddFormVisible = true; return ctx_r7.focusOnNewInput(); });
i0.ɵɵelement(2, "i", 10);
i0.ɵɵtext(3);
i0.ɵɵpipe(4, "translate");
i0.ɵɵelementEnd();
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(4, 1, "FLEXY_FORM_ARRAY_ADD"), " ");
} }
function FlexyFormGroupComponent_ng_container_4_ng_container_1_flexy_form_container_1_button_1_Template(rf, ctx) { if (rf & 1) {
const _r16 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "button", 15);
i0.ɵɵlistener("click", function FlexyFormGroupComponent_ng_container_4_ng_container_1_flexy_form_container_1_button_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const index_r11 = i0.ɵɵnextContext(2).index; const ctx_r14 = i0.ɵɵnextContext(2); return ctx_r14.removeItem(index_r11); });
i0.ɵɵelement(1, "i", 16);
i0.ɵɵelementEnd();
} }
const _c0 = function (a0) { return [a0]; };
const _c1 = function (a0) { return { "flexy-removable-list": a0 }; };
function FlexyFormGroupComponent_ng_container_4_ng_container_1_flexy_form_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "flexy-form-container", 13);
i0.ɵɵtemplate(1, FlexyFormGroupComponent_ng_container_4_ng_container_1_flexy_form_container_1_button_1_Template, 2, 0, "button", 14);
i0.ɵɵelementEnd();
} if (rf & 2) {
const item_r10 = i0.ɵɵnextContext().$implicit;
const ctx_r12 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("form", ctx_r12.form)("schema", i0.ɵɵpureFunction1(4, _c0, item_r10))("ngClass", i0.ɵɵpureFunction1(6, _c1, !ctx_r12.readonly && ctx_r12.removable));
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx_r12.readonly && ctx_r12.removable);
} }
function FlexyFormGroupComponent_ng_container_4_ng_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵtemplate(1, FlexyFormGroupComponent_ng_container_4_ng_container_1_flexy_form_container_1_Template, 2, 8, "flexy-form-container", 12);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r9 = i0.ɵɵnextContext(2);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r9.form);
} }
function FlexyFormGroupComponent_ng_container_4_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵtemplate(1, FlexyFormGroupComponent_ng_container_4_ng_container_1_Template, 2, 1, "ng-container", 11);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngForOf", ctx_r2.layoutSchema.children);
} }
function FlexyFormGroupComponent_div_5_button_1_Template(rf, ctx) { if (rf & 1) {
const _r21 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "button", 20);
i0.ɵɵlistener("click", function FlexyFormGroupComponent_div_5_button_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r20 = i0.ɵɵnextContext(2); ctx_r20.isAddFormVisible = true; return ctx_r20.focusOnNewInput(); });
i0.ɵɵelement(1, "i", 10);
i0.ɵɵtext(2);
i0.ɵɵpipe(3, "translate");
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵadvance(2);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(3, 1, "FLEXY_FORM_ARRAY_ADD"), " ");
} }
function FlexyFormGroupComponent_div_5_flexy_form_field_2_Template(rf, ctx) { if (rf & 1) {
const _r23 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "flexy-form-field", 21);
i0.ɵɵelementStart(1, "div", 22);
i0.ɵɵelementStart(2, "flexy-control-text", 23);
i0.ɵɵlistener("entered", function FlexyFormGroupComponent_div_5_flexy_form_field_2_Template_flexy_control_text_entered_2_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r22 = i0.ɵɵnextContext(2); return ctx_r22.addNew($event); });
i0.ɵɵelementEnd();
i0.ɵɵelementStart(3, "span", 24);
i0.ɵɵelementStart(4, "button", 25);
i0.ɵɵlistener("click", function FlexyFormGroupComponent_div_5_flexy_form_field_2_Template_button_click_4_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r24 = i0.ɵɵnextContext(2); return ctx_r24.addNew($event); });
i0.ɵɵtext(5);
i0.ɵɵpipe(6, "translate");
i0.ɵɵelementEnd();
i0.ɵɵelementEnd();
i0.ɵɵelementStart(7, "span", 24);
i0.ɵɵelementStart(8, "button", 26);
i0.ɵɵlistener("click", function FlexyFormGroupComponent_div_5_flexy_form_field_2_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r23); const ctx_r25 = i0.ɵɵnextContext(2); return ctx_r25.isAddFormVisible = false; });
i0.ɵɵtext(9);
i0.ɵɵpipe(10, "translate");
i0.ɵɵelementEnd();
i0.ɵɵelementEnd();
i0.ɵɵelementEnd();
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r19 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("control", ctx_r19.addFormControl);
i0.ɵɵadvance(2);
i0.ɵɵproperty("control", ctx_r19.addFormControl);
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(6, 4, "FLEXY_FORM_ARRAY_ADD"), " ");
i0.ɵɵadvance(4);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(10, 6, "FLEXY_FORM_ARRAY_ADD_CANCEL"), " ");
} }
function FlexyFormGroupComponent_div_5_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "div", 17);
i0.ɵɵtemplate(1, FlexyFormGroupComponent_div_5_button_1_Template, 4, 3, "button", 18);
i0.ɵɵtemplate(2, FlexyFormGroupComponent_div_5_flexy_form_field_2_Template, 11, 8, "flexy-form-field", 19);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r3 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx_r3.isAddFormVisible);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r3.isAddFormVisible);
} }
function FlexyFormGroupComponent_flexy_form_field_info_6_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "flexy-form-field-info", 27);
} if (rf & 2) {
const ctx_r4 = i0.ɵɵnextContext();
i0.ɵɵproperty("control", ctx_r4.layoutSchema.formControl)("forceDirty", true);
} }
function FlexyFormGroupComponent_p_7_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "p", 28);
i0.ɵɵtext(1);
i0.ɵɵpipe(2, "translate");
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵadvance(1);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(2, 1, "FLEXY_FORM_ARRAY_NO_DATA"), " ");
} }
const _c2 = function (a0) { return { "fieldset-invalid": a0 }; };
export class FlexyFormGroupComponent {
constructor(jsonMapperService, schemaService, toasts, translate, changeDetectorRef, elementRef) {
this.jsonMapperService = jsonMapperService;
this.schemaService = schemaService;
this.toasts = toasts;
this.translate = translate;
this.changeDetectorRef = changeDetectorRef;
this.elementRef = elementRef;
this.addable = true;
this.removable = true;
this.isRequired = false;
this.isAddFormVisible = false;
}
ngOnInit() {
if (this.layoutSchema && !this.layoutSchema.children) {
this.layoutSchema.children = [];
}
this.isRequired = isRequired(this.layoutSchema.formControl);
this.addFormControl = new FormControl(this.prepareNewKey(), [
Validators.required,
this.keyValidator(this.jsonSchema, this.layoutSchema)
]);
}
addNew(event) {
event.stopPropagation();
event.preventDefault();
if (this.addFormControl.valid) {
const key = this.addFormControl.value;
this.addFormControl.reset();
if (this.schemaService.addGroupItemToSchema(this.layoutSchema, key, this.jsonSchema, this.parentGroupName + '.' + key, this.readonly)) {
const translateKey = 'key';
this.toasts.success(this.translate.instant('FLEXY_FORM_GROUP_ADD_ITEM_SUCCESS', { [translateKey]: key }));
this.addFormControl.setValue(this.prepareNewKey());
this.isAddFormVisible = false;
}
}
}
removeItem(index) {
this.toasts.confirm(this.translate.instant('FLEXY_FORM_DELETE_ITEM_CONFIRM'), '', () => {
this.schemaService.removeGroupItemToSchema(this.layoutSchema, index);
});
}
focusOnNewInput() {
this.changeDetectorRef.detectChanges();
const input = this.elementRef.nativeElement.querySelector('.key-control-text input');
if (input) {
input.focus();
}
}
prepareNewKey() {
if (this.jsonSchema.indexGenPattern) {
return randomKey(this.jsonSchema.indexGenPattern);
}
else {
return void 0;
}
}
keyValidator(jsonSchema, layoutSchema) {
return (control) => {
const patternReg = jsonSchema.indexPattern ? new RegExp(jsonSchema.indexPattern, 'g') : null;
if (patternReg && !patternReg.exec(control.value)) {
return { key_wrong_format: { key: control.value, pattern: patternReg } };
}
else if (Object.keys(layoutSchema.formControl.controls).indexOf(control.value) !== -1) {
return { key_exist: { key: control.value } };
}
return null;
};
}
}
FlexyFormGroupComponent.ɵfac = function FlexyFormGroupComponent_Factory(t) { return new (t || FlexyFormGroupComponent)(i0.ɵɵdirectiveInject(i1.FlexyFormJsonMapperService), i0.ɵɵdirectiveInject(i1.FlexyFormSchemaService), i0.ɵɵdirectiveInject(i2.FlexyToastsService), i0.ɵɵdirectiveInject(i3.TranslateService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.ElementRef)); };
FlexyFormGroupComponent.ɵcmp = i0.ɵɵdefineComponent({ type: FlexyFormGroupComponent, selectors: [["flexy-form-group"]], inputs: { layoutSchema: "layoutSchema", form: "form", legend: "legend", readonly: "readonly", addable: "addable", removable: "removable", jsonSchema: "jsonSchema", parentGroupName: "parentGroupName" }, decls: 8, vars: 9, consts: [[3, "ngClass"], [4, "ngIf"], ["class", "actions", 4, "ngIf"], ["class", "actions add-form-control", 4, "ngIf"], [3, "control", "forceDirty", 4, "ngIf"], ["class", "no-data", 4, "ngIf"], ["class", "isRequired", 3, "tooltip", 4, "ngIf"], [1, "isRequired", 3, "tooltip"], [1, "actions"], ["type", "button", 1, "btn", "btn-info", "btn-outline", "btn-sm", 3, "click"], [1, "flexy-icon-plus"], [4, "ngFor", "ngForOf"], [3, "form", "schema", "ngClass", 4, "ngIf"], [3, "form", "schema", "ngClass"], ["type", "button", "class", "btn btn-outline delete-item e2e-btn-delete-group-item", 3, "click", 4, "ngIf"], ["type", "button", 1, "btn", "btn-outline", "delete-item", "e2e-btn-delete-group-item", 3, "click"], [1, "flexy-icon-remove"], [1, "actions", "add-form-control"], ["type", "button", "class", "btn btn-info btn-outline btn-sm add-item t2e-show-add-group-btn", 3, "click", 4, "ngIf"], ["class", "input-group", 3, "control", 4, "ngIf"], ["type", "button", 1, "btn", "btn-info", "btn-outline", "btn-sm", "add-item", "t2e-show-add-group-btn", 3, "click"], [1, "input-group", 3, "control"], [1, "input-group"], [1, "key-control-text", "t2e-add-group-key", 3, "control", "entered"], [1, "input-group-btn", "input-group-append"], ["type", "button", 1, "btn", "btn-info", "btn-outline", "btn-sm", "add-item", "t2e-add-group-btn", 3, "click"], ["type", "button", 1, "btn", "btn-link", "btn-sm", "cancel", 3, "click"], [3, "control", "forceDirty"], [1, "no-data"]], template: function FlexyFormGroupComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "fieldset", 0);
i0.ɵɵelementStart(1, "h4");
i0.ɵɵtemplate(2, FlexyFormGroupComponent_span_2_Template, 3, 2, "span", 1);
i0.ɵɵtemplate(3, FlexyFormGroupComponent_div_3_Template, 5, 3, "div", 2);
i0.ɵɵelementEnd();
i0.ɵɵtemplate(4, FlexyFormGroupComponent_ng_container_4_Template, 2, 1, "ng-container", 1);
i0.ɵɵtemplate(5, FlexyFormGroupComponent_div_5_Template, 3, 2, "div", 3);
i0.ɵɵtemplate(6, FlexyFormGroupComponent_flexy_form_field_info_6_Template, 1, 2, "flexy-form-field-info", 4);
i0.ɵɵtemplate(7, FlexyFormGroupComponent_p_7_Template, 3, 3, "p", 5);
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(7, _c2, ctx.layoutSchema.formControl && !ctx.layoutSchema.formControl.valid));
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", ctx.legend);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx.readonly && ctx.addable && (ctx.layoutSchema == null ? null : ctx.layoutSchema.children == null ? null : ctx.layoutSchema.children.length) > 10);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.layoutSchema && ctx.layoutSchema.children);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx.readonly && ctx.addable);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.layoutSchema && ctx.layoutSchema.formControl);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.layoutSchema && !ctx.layoutSchema.children.length);
} }, directives: [i4.NgClass, i4.NgIf, i5.TooltipDirective, i4.NgForOf, i1.FlexyFormContainerComponent, i6.FlexyFieldComponent, i7.FlexyControlTextComponent, i8.FlexyFieldControlInfoComponent], pipes: [i3.TranslatePipe], encapsulation: 2 });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(FlexyFormGroupComponent, [{
type: Component,
args: [{
selector: 'flexy-form-group',
templateUrl: './group.component.html'
}]
}], function () { return [{ type: i1.FlexyFormJsonMapperService }, { type: i1.FlexyFormSchemaService }, { type: i2.FlexyToastsService }, { type: i3.TranslateService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, { layoutSchema: [{
type: Input
}], form: [{
type: Input
}], legend: [{
type: Input
}], readonly: [{
type: Input
}], addable: [{
type: Input
}], removable: [{
type: Input
}], jsonSchema: [{
type: Input
}], parentGroupName: [{
type: Input
}] }); })();
/**
* schema is string /(([a-zA-Z0-9]*){([sd])\.?([0-9]*)}+([a-zA-Z0-9]*))/gys
* supported {s}: string {d}: number with defined size (default :8 max 32) {s.2}
*
* for example:
*
* AA{d.2}BB{s}
*
* generate: AA23BBasewASDq
*/
function randomKey(schema) {
let newKey = '';
const re = /(([a-zA-Z0-9_-]*){([sd])\.?([0-9]*)}+([a-zA-Z0-9]*))/gy;
let xArray = re.exec(schema);
while (xArray) {
newKey += xArray[2] + generateRandom(xArray[3], parseInt(xArray[4], 10)) + xArray[5];
xArray = re.exec(schema);
}
return newKey;
}
function generateRandom(type, length) {
if (!length) {
length = 2;
}
length = Math.min(length, 32);
const shuffleSource = type === 'd' ? '12345678901234567890123456789012345678901234567890' : 'abcdefghijklmnoprqstwxzABCDEFGHIJKLMNOPRQSTWXZ';
const s = shuffle(shuffleSource.split(''));
if (length) {
s.length = length;
}
return s.join('');
}
function shuffle(array) {
let counter = array.length;
// While there are elements in the array
while (counter > 0) {
// Pick a random index
const index = Math.floor(Math.random() * counter);
// Decrease counter by 1
counter--;
// And swap the last element with it
const temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
return array;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZm9ybS1ib290c3RyYXAvc3JjL2xpYi9jb21wb25lbnRzL2dyb3VwLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Zvcm0tYm9vdHN0cmFwL3NyYy9saWIvY29tcG9uZW50cy9ncm91cC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXFCLFNBQVMsRUFBYyxLQUFLLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDeEYsT0FBTyxFQU1MLFVBQVUsRUFDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBbUIsV0FBVyxFQUEwQixVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7SUNMNUYsK0JBQW1HOztJQUFBLGlCQUFDO0lBQUEseUJBQUc7SUFBQSxpQkFBQztJQUFBLGlCQUFJO0lBQUEsaUJBQUM7SUFBQSxpQkFBTzs7SUFBeEUsOEVBQXNEOzs7SUFGcEcsNEJBQ0U7SUFBQSxZQUNBO0lBQUEsaUZBQW1HO0lBQ3JHLGlCQUFPOzs7SUFGTCxlQUNBO0lBREEsOENBQ0E7SUFBTSxlQUFrQjtJQUFsQix3Q0FBa0I7Ozs7SUFFMUIsOEJBQ0U7SUFBQSxpQ0FDRTtJQUQ0RCx1TEFBNEIsSUFBSSxxQ0FBb0I7SUFDaEgsd0JBQStCO0lBQUMsWUFDbEM7O0lBQUEsaUJBQVM7SUFDWCxpQkFBTTs7SUFGOEIsZUFDbEM7SUFEa0MsNkVBQ2xDOzs7O0lBT0Usa0NBTUU7SUFGQSw2U0FBMkI7SUFFM0Isd0JBQWlDO0lBQ25DLGlCQUFTOzs7OztJQVJYLGdEQUNFO0lBQUEsb0lBTUU7SUFFSixpQkFBdUI7Ozs7SUFUWSxtQ0FBYSxnREFBQSwrRUFBQTtJQUU1QyxlQUE4QjtJQUE5Qiw2REFBOEI7OztJQUhwQyw2QkFDRTtJQUFBLHlJQUNFO0lBU0osMEJBQWU7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QUFvRCxDQUFDLENBQUMsQ0FBQyxnREFBZ0QsQ0FBQztJQUV6SCxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzNDLElBQUksTUFBTSxFQUFFO1FBQ1YsQ0FBQyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7S0FDbkI7SUFDRCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsQ0FBQztBQUVELFNBQVMsT0FBTyxDQUFDLEtBQUs7SUFDcEIsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUUzQix3Q0FBd0M7SUFDeEMsT0FBTyxPQUFPLEdBQUcsQ0FBQyxFQUFFO1FBQ2xCLHNCQUFzQjtRQUN0QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUVsRCx3QkFBd0I7UUFDeEIsT0FBTyxFQUFFLENBQUM7UUFFVixvQ0FBb0M7UUFDcEMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVCLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztLQUNyQjtJQUVELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEZsZXh5Rm9ybSxcbiAgRmxleHlGb3JtQ29tcGxleEZpZWxkTGF5b3V0SnNvblNjaGVtYSxcbiAgRmxleHlGb3JtRmllbGRMYXlvdXRTY2hlbWEsXG4gIEZsZXh5Rm9ybUpzb25NYXBwZXJTZXJ2aWNlLFxuICBGbGV4eUZvcm1TY2hlbWFTZXJ2aWNlLFxuICBpc1JlcXVpcmVkXG59IGZyb20gJ0BuZy1mbGV4eS9mb3JtJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBGbGV4eVRvYXN0c1NlcnZpY2UgfSBmcm9tICdAbmctZmxleHkvdG9hc3RzJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZmxleHktZm9ybS1ncm91cCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9ncm91cC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgRmxleHlGb3JtR3JvdXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBsYXlvdXRTY2hlbWE6IEZsZXh5Rm9ybUZpZWxkTGF5b3V0U2NoZW1hO1xuICBASW5wdXQoKSBmb3JtOiBGbGV4eUZvcm07XG4gIEBJbnB1dCgpIGxlZ2VuZDogc3RyaW5nO1xuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbjtcbiAgQElucHV0KCkgYWRkYWJsZSA9IHRydWU7XG4gIEBJbnB1dCgpIHJlbW92YWJsZSA9IHRydWU7XG5cbiAgQElucHV0KCkganNvblNjaGVtYTogRmxleHlGb3JtQ29tcGxleEZpZWxkTGF5b3V0SnNvblNjaGVtYTtcbiAgQElucHV0KCkgcGFyZW50R3JvdXBOYW1lOiBzdHJpbmc7XG5cbiAgaXNSZXF1aXJlZCA9IGZhbHNlO1xuXG4gIGlzQWRkRm9ybVZpc2libGUgPSBmYWxzZTtcbiAgYWRkRm9ybUNvbnRyb2w6IEZvcm1Db250cm9sO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUganNvbk1hcHBlclNlcnZpY2U6IEZsZXh5Rm9ybUpzb25NYXBwZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2NoZW1hU2VydmljZTogRmxleHlGb3JtU2NoZW1hU2VydmljZSxcbiAgICBwcml2YXRlIHRvYXN0czogRmxleHlUb2FzdHNTZXJ2aWNlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZlxuICApIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0U2NoZW1hICYmICF0aGlzLmxheW91dFNjaGVtYS5jaGlsZHJlbikge1xuICAgICAgdGhpcy5sYXlvdXRTY2hlbWEuY2hpbGRyZW4gPSBbXTtcbiAgICB9XG4gICAgdGhpcy5pc1JlcXVpcmVkID0gaXNSZXF1aXJlZCh0aGlzLmxheW91dFNjaGVtYS5mb3JtQ29udHJvbCk7XG5cbiAgICB0aGlzLmFkZEZvcm1Db250cm9sID0gbmV3IEZvcm1Db250cm9sKHRoaXMucHJlcGFyZU5ld0tleSgpLCBbXG4gICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgdGhpcy5rZXlWYWxpZGF0b3IodGhpcy5qc29uU2NoZW1hLCB0aGlzLmxheW91dFNjaGVtYSlcbiAgICBdKTtcbiAgfVxuXG4gIGFkZE5ldyhldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgaWYgKHRoaXMuYWRkRm9ybUNvbnRyb2wudmFsaWQpIHtcbiAgICAgIGNvbnN0IGtleSA9IHRoaXMuYWRkRm9ybUNvbnRyb2wudmFsdWU7XG4gICAgICB0aGlzLmFkZEZvcm1Db250cm9sLnJlc2V0KCk7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuc2NoZW1hU2VydmljZS5hZGRHcm91cEl0ZW1Ub1NjaGVtYSh0aGlzLmxheW91dFNjaGVtYSwga2V5LCB0aGlzLmpzb25TY2hlbWEsIHRoaXMucGFyZW50R3JvdXBOYW1lICsgJy4nICsga2V5LCB0aGlzLnJlYWRvbmx5KVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHRyYW5zbGF0ZUtleSA9ICdrZXknO1xuICAgICAgICB0aGlzLnRvYXN0cy5zdWNjZXNzKHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ0ZMRVhZX0ZPUk1fR1JPVVBfQUREX0lURU1fU1VDQ0VTUycsIHsgW3RyYW5zbGF0ZUtleV06IGtleSB9KSk7XG4gICAgICAgIHRoaXMuYWRkRm9ybUNvbnRyb2wuc2V0VmFsdWUodGhpcy5wcmVwYXJlTmV3S2V5KCkpO1xuICAgICAgICB0aGlzLmlzQWRkRm9ybVZpc2libGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZW1vdmVJdGVtKGluZGV4KSB7XG4gICAgdGhpcy50b2FzdHMuY29uZmlybSh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdGTEVYWV9GT1JNX0RFTEVURV9JVEVNX0NPTkZJUk0nKSwgJycsICgpID0+IHtcbiAgICAgIHRoaXMuc2NoZW1hU2VydmljZS5yZW1vdmVHcm91cEl0ZW1Ub1NjaGVtYSh0aGlzLmxheW91dFNjaGVtYSwgaW5kZXgpO1xuICAgIH0pO1xuICB9XG5cbiAgZm9jdXNPbk5ld0lucHV0KCkge1xuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIGNvbnN0IGlucHV0ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmtleS1jb250cm9sLXRleHQgaW5wdXQnKTtcbiAgICBpZiAoaW5wdXQpIHtcbiAgICAgIGlucHV0LmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlTmV3S2V5KCkge1xuICAgIGlmICh0aGlzLmpzb25TY2hlbWEuaW5kZXhHZW5QYXR0ZXJuKSB7XG4gICAgICByZXR1cm4gcmFuZG9tS2V5KHRoaXMuanNvblNjaGVtYS5pbmRleEdlblBhdHRlcm4pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdm9pZCAwO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUga2V5VmFsaWRhdG9yKGpzb25TY2hlbWEsIGxheW91dFNjaGVtYSk6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHBhdHRlcm5SZWcgPSBqc29uU2NoZW1hLmluZGV4UGF0dGVybiA/IG5ldyBSZWdFeHAoanNvblNjaGVtYS5pbmRleFBhdHRlcm4sICdnJykgOiBudWxsO1xuICAgICAgaWYgKHBhdHRlcm5SZWcgJiYgIXBhdHRlcm5SZWcuZXhlYyhjb250cm9sLnZhbHVlKSkge1xuICAgICAgICByZXR1cm4geyBrZXlfd3JvbmdfZm9ybWF0OiB7IGtleTogY29udHJvbC52YWx1ZSwgcGF0dGVybjogcGF0dGVyblJlZyB9IH07XG4gICAgICB9IGVsc2UgaWYgKE9iamVjdC5rZXlzKChsYXlvdXRTY2hlbWEuZm9ybUNvbnRyb2wgYXMgRm9ybUdyb3VwKS5jb250cm9scykuaW5kZXhPZihjb250cm9sLnZhbHVlKSAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIHsga2V5X2V4aXN0OiB7IGtleTogY29udHJvbC52YWx1ZSB9IH07XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogc2NoZW1hIGlzIHN0cmluZyAvKChbYS16QS1aMC05XSopeyhbc2RdKVxcLj8oWzAtOV0qKX0rKFthLXpBLVowLTldKikpL2d5c1xuICogc3VwcG9ydGVkIHtzfTogc3RyaW5nIHtkfTogbnVtYmVyIHdpdGggZGVmaW5lZCBzaXplIChkZWZhdWx0IDo4IG1heCAzMikge3MuMn1cbiAqXG4gKiBmb3IgZXhhbXBsZTpcbiAqXG4gKiBBQXtkLjJ9QkJ7c31cbiAqXG4gKiBnZW5lcmF0ZTogQUEyM0JCYXNld0FTRHFcbiAqL1xuZnVuY3Rpb24gcmFuZG9tS2V5KHNjaGVtYTogc3RyaW5nKSB7XG4gIGxldCBuZXdLZXkgPSAnJztcbiAgY29uc3QgcmUgPSAvKChbYS16QS1aMC05Xy1dKil7KFtzZF0pXFwuPyhbMC05XSopfSsoW2EtekEtWjAtOV0qKSkvZ3k7XG4gIGxldCB4QXJyYXkgPSByZS5leGVjKHNjaGVtYSk7XG4gIHdoaWxlICh4QXJyYXkpIHtcbiAgICBuZXdLZXkgKz0geEFycmF5WzJdICsgZ2VuZXJhdGVSYW5kb20oeEFycmF5WzNdLCBwYXJzZUludCh4QXJyYXlbNF0sIDEwKSkgKyB4QXJyYXlbNV07XG4gICAgeEFycmF5ID0gcmUuZXhlYyhzY2hlbWEpO1xuICB9XG4gIHJldHVybiBuZXdLZXk7XG59XG5cbmZ1bmN0aW9uIGdlbmVyYXRlUmFuZG9tKHR5cGU6IHN0cmluZywgbGVuZ3RoOiBudW1iZXIpIHtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSAyO1xuICB9XG4gIGxlbmd0aCA9IE1hdGgubWluKGxlbmd0aCwgMzIpO1xuICBjb25zdCBzaHVmZmxlU291cmNlID1cbiAgICB0eXBlID09PSAnZCcgPyAnMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnIDogJ2FiY2RlZmdoaWprbG1ub3BycXN0d3h6QUJDREVGR0hJSktMTU5PUFJRU1RXWFonO1xuXG4gIGNvbnN0IHMgPSBzaHVmZmxlKHNodWZmbGVTb3VyY2Uuc3BsaXQoJycpKTtcbiAgaWYgKGxlbmd0aCkge1xuICAgIHMubGVuZ3RoID0gbGVuZ3RoO1xuICB9XG4gIHJldHVybiBzLmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBzaHVmZmxlKGFycmF5KSB7XG4gIGxldCBjb3VudGVyID0gYXJyYXkubGVuZ3RoO1xuXG4gIC8vIFdoaWxlIHRoZXJlIGFyZSBlbGVtZW50cyBpbiB0aGUgYXJyYXlcbiAgd2hpbGUgKGNvdW50ZXIgPiAwKSB7XG4gICAgLy8gUGljayBhIHJhbmRvbSBpbmRleFxuICAgIGNvbnN0IGluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY291bnRlcik7XG5cbiAgICAvLyBEZWNyZWFzZSBjb3VudGVyIGJ5IDFcbiAgICBjb3VudGVyLS07XG5cbiAgICAvLyBBbmQgc3dhcCB0aGUgbGFzdCBlbGVtZW50IHdpdGggaXRcbiAgICBjb25zdCB0ZW1wID0gYXJyYXlbY291bnRlcl07XG4gICAgYXJyYXlbY291bnRlcl0gPSBhcnJheVtpbmRleF07XG4gICAgYXJyYXlbaW5kZXhdID0gdGVtcDtcbiAgfVxuXG4gIHJldHVybiBhcnJheTtcbn1cbiIsIjxmaWVsZHNldCBbbmdDbGFzc109XCJ7ICdmaWVsZHNldC1pbnZhbGlkJzogbGF5b3V0U2NoZW1hLmZvcm1Db250cm9sICYmICFsYXlvdXRTY2hlbWEuZm9ybUNvbnRyb2wudmFsaWQgfVwiPlxuICA8aDQ+XG4gICAgPHNwYW4gKm5nSWY9XCJsZWdlbmRcIj5cbiAgICAgIHt7IGxlZ2VuZCB9fVxuICAgICAgPHNwYW4gKm5nSWY9XCJpc1JlcXVpcmVkXCIgY2xhc3M9XCJpc1JlcXVpcmVkXCIgW3Rvb2x0aXBdPVwiJ0ZMRVhZX0ZPUk1fRklFTERfSVNfUkVRVUlSRUQnIHwgdHJhbnNsYXRlXCI+KDxiPio8L2I+KTwvc3Bhbj5cbiAgICA8L3NwYW4+XG4gICAgPGRpdiBjbGFzcz1cImFjdGlvbnNcIiAqbmdJZj1cIiFyZWFkb25seSAmJiBhZGRhYmxlICYmIGxheW91dFNjaGVtYT8uY2hpbGRyZW4/Lmxlbmd0aCA+IDEwXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4taW5mbyBidG4tb3V0bGluZSBidG4tc21cIiAoY2xpY2spPVwiaXNBZGRGb3JtVmlzaWJsZSA9IHRydWU7IGZvY3VzT25OZXdJbnB1dCgpXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiZmxleHktaWNvbi1wbHVzXCI+PC9pPiB7eyAnRkxFWFlfRk9STV9BUlJBWV9BREQnIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9oND5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwibGF5b3V0U2NoZW1hICYmIGxheW91dFNjaGVtYS5jaGlsZHJlblwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbGF5b3V0U2NoZW1hLmNoaWxkcmVuOyBsZXQgaW5kZXggPSBpbmRleFwiPlxuICAgICAgPGZsZXh5LWZvcm0tY29udGFpbmVyICpuZ0lmPVwiZm9ybVwiIFtmb3JtXT1cImZvcm1cIiBbc2NoZW1hXT1cIltpdGVtXVwiIFtuZ0NsYXNzXT1cInsgJ2ZsZXh5LXJlbW92YWJsZS1saXN0JzogIXJlYWRvbmx5ICYmIHJlbW92YWJsZSB9XCI+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAqbmdJZj1cIiFyZWFkb25seSAmJiByZW1vdmFibGVcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lIGRlbGV0ZS1pdGVtIGUyZS1idG4tZGVsZXRlLWdyb3VwLWl0ZW1cIlxuICAgICAgICAgIChjbGljayk9XCJyZW1vdmVJdGVtKGluZGV4KVwiXG4gICAgICAgID5cbiAgICAgICAgICA8aSBjbGFzcz1cImZsZXh5LWljb24tcmVtb3ZlXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZmxleHktZm9ybS1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxkaXYgY2xhc3M9XCJhY3Rpb25zIGFkZC1mb3JtLWNvbnRyb2xcIiAqbmdJZj1cIiFyZWFkb25seSAmJiBhZGRhYmxlXCI+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAqbmdJZj1cIiFpc0FkZEZvcm1WaXNpYmxlXCJcbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1pbmZvIGJ0bi1vdXRsaW5lIGJ0bi1zbSBhZGQtaXRlbSB0MmUtc2hvdy1hZGQtZ3JvdXAtYnRuXCJcbiAgICAgIChjbGljayk9XCJpc0FkZEZvcm1WaXNpYmxlID0gdHJ1ZTsgZm9jdXNPbk5ld0lucHV0KClcIlxuICAgID5cbiAgICAgIDxpIGNsYXNzPVwiZmxleHktaWNvbi1wbHVzXCI+PC9pPiB7eyAnRkxFWFlfRk9STV9BUlJBWV9BREQnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9idXR0b24+XG4gICAgPGZsZXh5LWZvcm0tZmllbGQgKm5nSWY9XCJpc0FkZEZvcm1WaXNpYmxlXCIgY2xhc3M9XCJpbnB1dC1ncm91cFwiIFtjb250cm9sXT1cImFkZEZvcm1Db250cm9sXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgPGZsZXh5LWNvbnRyb2wtdGV4dFxuICAgICAgICAgIGNsYXNzPVwia2V5LWNvbnRyb2wtdGV4dCB0MmUtYWRkLWdyb3VwLWtleVwiXG4gICAgICAgICAgW2NvbnRyb2xdPVwiYWRkRm9ybUNvbnRyb2xcIlxuICAgICAgICAgIChlbnRlcmVkKT1cImFkZE5ldygkZXZlbnQpXCJcbiAgICAgICAgPjwvZmxleHktY29udHJvbC10ZXh0PlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLWJ0biBpbnB1dC1ncm91cC1hcHBlbmRcIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4taW5mbyBidG4tb3V0bGluZSBidG4tc20gYWRkLWl0ZW0gdDJlLWFkZC1ncm91cC1idG5cIiAoY2xpY2spPVwiYWRkTmV3KCRldmVudClcIj5cbiAgICAgICAgICAgIHt7ICdGTEVYWV9GT1JNX0FSUkFZX0FERCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLWJ0biBpbnB1dC1ncm91cC1hcHBlbmRcIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tbGluayBidG4tc20gY2FuY2VsXCIgKGNsaWNrKT1cImlzQWRkRm9ybVZpc2libGUgPSBmYWxzZVwiPlxuICAgICAgICAgICAge3sgJ0ZMRVhZX0ZPUk1fQVJSQVlfQUREX0NBTkNFTCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9mbGV4eS1mb3JtLWZpZWxkPlxuICA8L2Rpdj5cblxuICA8ZmxleHktZm9ybS1maWVsZC1pbmZvXG4gICAgKm5nSWY9XCJsYXlvdXRTY2hlbWEgJiYgbGF5b3V0U2NoZW1hLmZvcm1Db250cm9sXCJcbiAgICBbY29udHJvbF09XCJsYXlvdXRTY2hlbWEuZm9ybUNvbnRyb2xcIlxuICAgIFtmb3JjZURpcnR5XT1cInRydWVcIlxuICA+PC9mbGV4eS1mb3JtLWZpZWxkLWluZm8+XG5cbiAgPHAgY2xhc3M9XCJuby1kYXRhXCIgKm5nSWY9XCJsYXlvdXRTY2hlbWEgJiYgIWxheW91dFNjaGVtYS5jaGlsZHJlbi5sZW5ndGhcIj5cbiAgICB7eyAnRkxFWFlfRk9STV9BUlJBWV9OT19EQVRBJyB8IHRyYW5zbGF0ZSB9fVxuICA8L3A+XG48L2ZpZWxkc2V0PlxuIl19