UNPKG

ngx-surveys

Version:
168 lines (167 loc) 38.7 kB
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "./ngx-survey.service"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; import * as i4 from "@angular/material/button"; import * as i5 from "@angular/material/stepper"; import * as i6 from "./form-item/form-item.component"; export class NgxSurveyComponent { get submitDisabled() { return !!this.form.find(section => section.items.find(item => item.busy)); } //private _bpSub: Subscription; constructor( //private bpObserver: BreakpointObserver, elRef, service) { this.elRef = elRef; this.service = service; this.value = {}; this.validateByStepChange = true; this.editable = true; this.valueChange = new EventEmitter(); this.stepChanged = new EventEmitter(); this.submit = new EventEmitter(); this.selectedIndex = 0; } ngOnInit() { //console.log(this.value); this.form = this.service.initForm(this.form, this.value); if (this.splitBySteps) { this.form.forEach(section => { section.isEditable = true; }); } /* this._bpSub = this.bpObserver .observe(['(max-width: 599px)']) .subscribe((state: BreakpointState) => { this.setMobileStepper(state.matches); }); */ } ngAfterViewInit() { //console.log(this.stepper); } onResized(event) { //TODO } /* onResized(event: ResizedEvent) { if (event.newRect.width<600 && !this.isMobile){ this.setMobileStepper(true); } else if (event.newRect.width>=600 && this.isMobile){ this.setMobileStepper(false); } this.resized.emit(event); //this.width = event.newWidth; //this.height = event.newHeight; }*/ scrollToField(field) { let el = this.elRef.nativeElement.querySelector('#form_item_' + field.name); if (el) { el.scrollIntoView(); } } ; isStepEnabled(section) { const prevSection = this.form[this.form.indexOf(section) - 1]; return !this.validateByStepChange || !prevSection || (prevSection && prevSection.submited && !prevSection.hasError); } onItemChanges(item) { if (!this.editable) { return; } item.errors = this.service.getErrors(item); const { value } = this.service.getValue(this.form, false); this.valueChange.emit(value); } selectionChanged(event) { this.selectedIndex = event.selectedIndex; } setMobileStepper(isMobile) { this.isMobile = isMobile; setTimeout(() => { if (this.stepper) { this.stepper.selectedIndex = this.selectedIndex; } }); } onStepChange(step) { //console.log(step); this.stepChanged.emit(step); if (this.validateByStepChange && step.previouslySelectedIndex >= 0 && this.form[step.previouslySelectedIndex]) { this.submitStep(this.form[step.previouslySelectedIndex], false); } // this.stepper.selectedIndex=0; } submitForm() { const { valid, value, firstError } = this.service.getValue(this.form, true); if (valid) { this.submit.emit(value); } else { this.scrollToField(firstError); } } submitStep(section, goToNext) { if (!this.editable) { return; } //console.log(section); const { valid, firstError } = this.service.getValue([section], true); //console.log({valid, value, firstError}); if (valid) { section.hasError = false; section.submited = true; //console.log(this.stepper); if (goToNext) { setTimeout(() => { this.stepper.next(); }, 100); } } else { //console.log(firstError); this.scrollToField(firstError); section.hasError = true; if (firstError && firstError.errors && firstError.errors[0]) { section.firstErrorText = firstError.label + ': ' + firstError.errors[0].message; } } } ngOnDestroy() { //this._bpSub.unsubscribe(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NgxSurveyComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxSurveyService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: NgxSurveyComponent, selector: "ngx-survey", inputs: { form: "form", value: "value", splitBySteps: "splitBySteps", validateByStepChange: "validateByStepChange", submitInProgress: "submitInProgress", submitErrorText: "submitErrorText", editable: "editable" }, outputs: { valueChange: "valueChange", stepChanged: "stepChanged", submit: "submit" }, viewQueries: [{ propertyName: "stepper", first: true, predicate: ["stepper"], descendants: true }], ngImport: i0, template: "<div (resized)=\"onResized($event)\">\n <form name=\"surveyForm\" *ngIf=\"!splitBySteps\">\n <fieldset class=\"form-fieldset\" *ngFor=\"let section of form\">\n <ng-container *ngIf=\"service.isSectionVisible(form, section)\">\n <legend class=\"form-legend\" *ngIf=\"section.title || section.subtitle\">\n <span [ngClass]=\"'section-style-'+section.sectionStyle\" [innerHtml]=\"section.title\"></span>\n <span *ngIf=\"section.subtitle\"><br /><small [innerHtml]=\"section.subtitle\"></small></span>\n </legend>\n\n <div class=\"form-fieldset-content\">\n <div *ngFor=\"let item of section.items\" [attr.id]=\"'form_item_'+item.name\">\n <ngx-survey-form-item\n *ngIf=\"service.isItemVisible(form, section, item)\"\n [type]=\"item.type\"\n [item]=\"item\"\n [editable]=\"editable\"\n [isMobile]=\"isMobile\"\n (changes)=\"onItemChanges($event)\"\n ></ngx-survey-form-item>\n </div>\n </div>\n </ng-container>\n </fieldset>\n </form>\n\n <div *ngIf=\"splitBySteps\">\n <mat-horizontal-stepper #stepper *ngIf=\"!isMobile\"\n (selectionChange)=\"onStepChange($event)\"\n >\n <!--\n <ng-template matStepperIcon=\"done\" let-index=\"index\">\n {{index+1}}\n </ng-template>\n\n -->\n\n <mat-step *ngFor=\"let section of form; index as i;\"\n [editable]=\"isStepEnabled(section)\"\n [completed]=\"section.submited\"\n\n [hasError]=\"section.hasError\"\n [errorMessage]=\"section.firstErrorText\"\n >\n\n <form>\n <ng-template matStepLabel>{{section.title}}</ng-template>\n <h3 *ngIf=\"section.subtitle\">{{section.subtitle}}</h3>\n <div *ngFor=\"let item of section.items\" [attr.id]=\"'form_item_'+item.name\">\n <ngx-survey-form-item\n *ngIf=\"service.isItemVisible(form, section, item)\"\n [type]=\"item.type\"\n [item]=\"item\"\n [editable]=\"editable\"\n [isMobile]=\"isMobile\"\n (changes)=\"onItemChanges($event)\"\n ></ngx-survey-form-item>\n </div>\n </form>\n <div *ngIf=\"i<form.length-1\">\n <button mat-button type=\"button\" class=\"btn btn-primary btn-block\" (click)=\"submitStep(section, true)\">Continue</button>\n </div>\n <div *ngIf=\"i>=form.length-1\">\n <div class=\"text-center text-danger global-error\" *ngIf=\"submitErrorText\">{{submitErrorText}}<br /></div>\n <button mat-button type=\"button\" class=\"btn btn-success btn-block\" (click)=\"submitForm()\" [disabled]=\"submitInProgress || submitDisabled\"><i class=\"fa fa-spinner fa-spin\" *ngIf=\"submitInProgress\"></i> Submit</button>\n </div>\n </mat-step>\n </mat-horizontal-stepper>\n\n <mat-vertical-stepper #stepper *ngIf=\"isMobile\"\n (selectionChange)=\"onStepChange($event)\"\n >\n <!--\n <ng-template matStepperIcon=\"done\" let-index=\"index\">\n {{index+1}}\n </ng-template>\n\n -->\n\n <mat-step *ngFor=\"let section of form; index as i;\"\n [editable]=\"isStepEnabled(section)\"\n [completed]=\"section.submited\"\n\n [hasError]=\"section.hasError\"\n [errorMessage]=\"section.firstErrorText\"\n >\n\n <form>\n <ng-template matStepLabel>{{section.title}}</ng-template>\n <h3 *ngIf=\"section.subtitle\">{{section.subtitle}}</h3>\n <div *ngFor=\"let item of section.items\" [attr.id]=\"'form_item_'+item.name\">\n <ngx-survey-form-item\n *ngIf=\"service.isItemVisible(form, section, item)\"\n [type]=\"item.type\"\n [item]=\"item\"\n [editable]=\"editable\"\n (changes)=\"onItemChanges($event)\"\n [isMobile]=\"isMobile\"\n ></ngx-survey-form-item>\n </div>\n </form>\n <div *ngIf=\"i<form.length-1\">\n <button mat-button type=\"button\" class=\"btn btn-primary btn-block\" (click)=\"submitStep(section, true)\">Continue</button>\n </div>\n <div *ngIf=\"i>=form.length-1\">\n <div class=\"text-center text-danger global-error\" *ngIf=\"submitErrorText\">{{submitErrorText}}<br /></div>\n <button mat-button type=\"button\" class=\"btn btn-success btn-block\" (click)=\"submitForm()\" [disabled]=\"submitInProgress || submitDisabled\"><i class=\"fa fa-spinner fa-spin\" *ngIf=\"submitInProgress\"></i> Submit</button>\n </div>\n </mat-step>\n </mat-vertical-stepper>\n </div>\n</div>\n", styles: ["::ng-deep .mat-step-header.mat-disabled{cursor:default}::ng-deep .mat-step-header.mat-disabled .mat-step-icon-state-done{background-color:#0000008a}::ng-deep .mat-step-header.mat-disabled .mat-step-label.mat-step-label-active{color:#0000008a}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i5.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i5.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i5.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "component", type: i6.FormItemComponent, selector: "ngx-survey-form-item", inputs: ["type", "item", "editable", "isMobile", "id"], outputs: ["changes"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NgxSurveyComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-survey', template: "<div (resized)=\"onResized($event)\">\n <form name=\"surveyForm\" *ngIf=\"!splitBySteps\">\n <fieldset class=\"form-fieldset\" *ngFor=\"let section of form\">\n <ng-container *ngIf=\"service.isSectionVisible(form, section)\">\n <legend class=\"form-legend\" *ngIf=\"section.title || section.subtitle\">\n <span [ngClass]=\"'section-style-'+section.sectionStyle\" [innerHtml]=\"section.title\"></span>\n <span *ngIf=\"section.subtitle\"><br /><small [innerHtml]=\"section.subtitle\"></small></span>\n </legend>\n\n <div class=\"form-fieldset-content\">\n <div *ngFor=\"let item of section.items\" [attr.id]=\"'form_item_'+item.name\">\n <ngx-survey-form-item\n *ngIf=\"service.isItemVisible(form, section, item)\"\n [type]=\"item.type\"\n [item]=\"item\"\n [editable]=\"editable\"\n [isMobile]=\"isMobile\"\n (changes)=\"onItemChanges($event)\"\n ></ngx-survey-form-item>\n </div>\n </div>\n </ng-container>\n </fieldset>\n </form>\n\n <div *ngIf=\"splitBySteps\">\n <mat-horizontal-stepper #stepper *ngIf=\"!isMobile\"\n (selectionChange)=\"onStepChange($event)\"\n >\n <!--\n <ng-template matStepperIcon=\"done\" let-index=\"index\">\n {{index+1}}\n </ng-template>\n\n -->\n\n <mat-step *ngFor=\"let section of form; index as i;\"\n [editable]=\"isStepEnabled(section)\"\n [completed]=\"section.submited\"\n\n [hasError]=\"section.hasError\"\n [errorMessage]=\"section.firstErrorText\"\n >\n\n <form>\n <ng-template matStepLabel>{{section.title}}</ng-template>\n <h3 *ngIf=\"section.subtitle\">{{section.subtitle}}</h3>\n <div *ngFor=\"let item of section.items\" [attr.id]=\"'form_item_'+item.name\">\n <ngx-survey-form-item\n *ngIf=\"service.isItemVisible(form, section, item)\"\n [type]=\"item.type\"\n [item]=\"item\"\n [editable]=\"editable\"\n [isMobile]=\"isMobile\"\n (changes)=\"onItemChanges($event)\"\n ></ngx-survey-form-item>\n </div>\n </form>\n <div *ngIf=\"i<form.length-1\">\n <button mat-button type=\"button\" class=\"btn btn-primary btn-block\" (click)=\"submitStep(section, true)\">Continue</button>\n </div>\n <div *ngIf=\"i>=form.length-1\">\n <div class=\"text-center text-danger global-error\" *ngIf=\"submitErrorText\">{{submitErrorText}}<br /></div>\n <button mat-button type=\"button\" class=\"btn btn-success btn-block\" (click)=\"submitForm()\" [disabled]=\"submitInProgress || submitDisabled\"><i class=\"fa fa-spinner fa-spin\" *ngIf=\"submitInProgress\"></i> Submit</button>\n </div>\n </mat-step>\n </mat-horizontal-stepper>\n\n <mat-vertical-stepper #stepper *ngIf=\"isMobile\"\n (selectionChange)=\"onStepChange($event)\"\n >\n <!--\n <ng-template matStepperIcon=\"done\" let-index=\"index\">\n {{index+1}}\n </ng-template>\n\n -->\n\n <mat-step *ngFor=\"let section of form; index as i;\"\n [editable]=\"isStepEnabled(section)\"\n [completed]=\"section.submited\"\n\n [hasError]=\"section.hasError\"\n [errorMessage]=\"section.firstErrorText\"\n >\n\n <form>\n <ng-template matStepLabel>{{section.title}}</ng-template>\n <h3 *ngIf=\"section.subtitle\">{{section.subtitle}}</h3>\n <div *ngFor=\"let item of section.items\" [attr.id]=\"'form_item_'+item.name\">\n <ngx-survey-form-item\n *ngIf=\"service.isItemVisible(form, section, item)\"\n [type]=\"item.type\"\n [item]=\"item\"\n [editable]=\"editable\"\n (changes)=\"onItemChanges($event)\"\n [isMobile]=\"isMobile\"\n ></ngx-survey-form-item>\n </div>\n </form>\n <div *ngIf=\"i<form.length-1\">\n <button mat-button type=\"button\" class=\"btn btn-primary btn-block\" (click)=\"submitStep(section, true)\">Continue</button>\n </div>\n <div *ngIf=\"i>=form.length-1\">\n <div class=\"text-center text-danger global-error\" *ngIf=\"submitErrorText\">{{submitErrorText}}<br /></div>\n <button mat-button type=\"button\" class=\"btn btn-success btn-block\" (click)=\"submitForm()\" [disabled]=\"submitInProgress || submitDisabled\"><i class=\"fa fa-spinner fa-spin\" *ngIf=\"submitInProgress\"></i> Submit</button>\n </div>\n </mat-step>\n </mat-vertical-stepper>\n </div>\n</div>\n", styles: ["::ng-deep .mat-step-header.mat-disabled{cursor:default}::ng-deep .mat-step-header.mat-disabled .mat-step-icon-state-done{background-color:#0000008a}::ng-deep .mat-step-header.mat-disabled .mat-step-label.mat-step-label-active{color:#0000008a}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxSurveyService }], propDecorators: { form: [{ type: Input }], value: [{ type: Input }], splitBySteps: [{ type: Input }], validateByStepChange: [{ type: Input }], submitInProgress: [{ type: Input }], submitErrorText: [{ type: Input }], editable: [{ type: Input }], valueChange: [{ type: Output }], stepChanged: [{ type: Output }], submit: [{ type: Output }], stepper: [{ type: ViewChild, args: ['stepper', { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXN1cnZleS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc3VydmV5cy9zcmMvbGliL25neC1zdXJ2ZXkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN1cnZleXMvc3JjL2xpYi9uZ3gtc3VydmV5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUF3QyxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7QUFhaEksTUFBTSxPQUFPLGtCQUFrQjtJQW9CM0IsSUFBSSxjQUFjO1FBQ2QsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBLEVBQUUsQ0FBQSxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUEsRUFBRSxDQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFFRCwrQkFBK0I7SUFFL0I7SUFDSSx5Q0FBeUM7SUFDakMsS0FBZ0IsRUFDakIsT0FBeUI7UUFEeEIsVUFBSyxHQUFMLEtBQUssQ0FBVztRQUNqQixZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQTFCM0IsVUFBSyxHQUFLLEVBQUUsQ0FBQztRQUViLHlCQUFvQixHQUFTLElBQUksQ0FBQztRQUdsQyxhQUFRLEdBQVMsSUFBSSxDQUFDO1FBRXJCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUN0QyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDdEMsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFLcEMsa0JBQWEsR0FBVyxDQUFDLENBQUM7SUFlakMsQ0FBQztJQUVELFFBQVE7UUFDSiwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLElBQUks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LFVBQVUsQ0FBQyxLQUFLLEdBQUMsSUFBSSxHQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQzlFLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVELFdBQVc7UUFDUCw0QkFBNEI7SUFDaEMsQ0FBQzsrR0FqS1Esa0JBQWtCO21HQUFsQixrQkFBa0IsbWNDYi9CLHFzS0ErR0E7OzRGRGxHYSxrQkFBa0I7a0JBTDlCLFNBQVM7K0JBQ0UsWUFBWTs4R0FNWCxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csb0JBQW9CO3NCQUE1QixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTTtnQkFHeUMsT0FBTztzQkFBdEQsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgVmlld0NoaWxkLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbi8vaW1wb3J0IHsgQnJlYWtwb2ludE9ic2VydmVyLCBCcmVha3BvaW50U3RhdGUgfSBmcm9tICdAYW5ndWxhci9jZGsvbGF5b3V0Jztcbi8vaW1wb3J0IHsgUmVzaXplZEV2ZW50IH0gZnJvbSAnYW5ndWxhci1yZXNpemUtZXZlbnQnO1xuLy9pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IE5neFN1cnZleVNlcnZpY2UgfSBmcm9tICcuL25neC1zdXJ2ZXkuc2VydmljZSc7XG5pbXBvcnQgeyBNYXRTdGVwcGVyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc3RlcHBlcic7XG5cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LXN1cnZleScsXG4gIHRlbXBsYXRlVXJsOiAnLi9uZ3gtc3VydmV5LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbmd4LXN1cnZleS5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIE5neFN1cnZleUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAgIEBJbnB1dCgpIGZvcm06YW55W107XG4gICAgQElucHV0KCkgdmFsdWU6YW55PXt9O1xuICAgIEBJbnB1dCgpIHNwbGl0QnlTdGVwczpib29sZWFuO1xuICAgIEBJbnB1dCgpIHZhbGlkYXRlQnlTdGVwQ2hhbmdlOmJvb2xlYW49dHJ1ZTtcbiAgICBASW5wdXQoKSBzdWJtaXRJblByb2dyZXNzOmJvb2xlYW47XG4gICAgQElucHV0KCkgc3VibWl0RXJyb3JUZXh0OnN0cmluZztcbiAgICBASW5wdXQoKSBlZGl0YWJsZTpib29sZWFuPXRydWU7XG5cbiAgICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgICBAT3V0cHV0KCkgc3RlcENoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgICBAT3V0cHV0KCkgc3VibWl0ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gICAgLy9AT3V0cHV0KCkgcmVzaXplZCA9IG5ldyBFdmVudEVtaXR0ZXI8UmVzaXplZEV2ZW50PigpO1xuXG4gICAgQFZpZXdDaGlsZCgnc3RlcHBlcicsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgc3RlcHBlcjpNYXRTdGVwcGVyO1xuXG4gICAgcHVibGljIHNlbGVjdGVkSW5kZXg6IG51bWJlciA9IDA7XG4gICAgcHVibGljIGlzTW9iaWxlOiBib29sZWFuO1xuXG4gICAgZ2V0IHN1Ym1pdERpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLmZvcm0uZmluZChzZWN0aW9uPT5zZWN0aW9uLml0ZW1zLmZpbmQoaXRlbT0+aXRlbS5idXN5KSk7XG4gICAgfVxuXG4gICAgLy9wcml2YXRlIF9icFN1YjogU3Vic2NyaXB0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIC8vcHJpdmF0ZSBicE9ic2VydmVyOiBCcmVha3BvaW50T2JzZXJ2ZXIsXG4gICAgICAgIHByaXZhdGUgZWxSZWY6RWxlbWVudFJlZixcbiAgICAgICAgcHVibGljIHNlcnZpY2U6IE5neFN1cnZleVNlcnZpY2UsXG4gICAgKSB7XG5cbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgLy9jb25zb2xlLmxvZyh0aGlzLnZhbHVlKTtcbiAgICAgICAgdGhpcy5mb3JtPXRoaXMuc2VydmljZS5pbml0Rm9ybSh0aGlzLmZvcm0sIHRoaXMudmFsdWUpO1xuICAgICAgICBpZiAodGhpcy5zcGxpdEJ5U3RlcHMpe1xuICAgICAgICAgICAgdGhpcy5mb3JtLmZvckVhY2goc2VjdGlvbj0+e1xuICAgICAgICAgICAgICAgIHNlY3Rpb24uaXNFZGl0YWJsZT10cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLypcbiAgICAgICAgdGhpcy5fYnBTdWIgPSB0aGlzLmJwT2JzZXJ2ZXJcbiAgICAgICAgICAub2JzZXJ2ZShbJyhtYXgtd2lkdGg6IDU5OXB4KSddKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKHN0YXRlOiBCcmVha3BvaW50U3RhdGUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0TW9iaWxlU3RlcHBlcihzdGF0ZS5tYXRjaGVzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAqL1xuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgLy9jb25zb2xlLmxvZyh0aGlzLnN0ZXBwZXIpO1xuICAgIH1cblxuICAgIG9uUmVzaXplZChldmVudCl7XG4gICAgICAgIC8vVE9ET1xuICAgIH1cblxuICAgIC8qXG4gICAgb25SZXNpemVkKGV2ZW50OiBSZXNpemVkRXZlbnQpIHtcblxuICAgICAgICBpZiAoZXZlbnQubmV3UmVjdC53aWR0aDw2MDAgJiYgIXRoaXMuaXNNb2JpbGUpe1xuICAgICAgICAgICAgdGhpcy5zZXRNb2JpbGVTdGVwcGVyKHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50Lm5ld1JlY3Qud2lkdGg+PTYwMCAmJiB0aGlzLmlzTW9iaWxlKXtcbiAgICAgICAgICAgIHRoaXMuc2V0TW9iaWxlU3RlcHBlcihmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXNpemVkLmVtaXQoZXZlbnQpO1xuICAgICAgICAvL3RoaXMud2lkdGggPSBldmVudC5uZXdXaWR0aDtcbiAgICAgICAgLy90aGlzLmhlaWdodCA9IGV2ZW50Lm5ld0hlaWdodDtcbiAgICB9Ki9cblxuICAgIHNjcm9sbFRvRmllbGQoZmllbGQpIHtcbiAgICAgICAgbGV0IGVsID0gdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJyNmb3JtX2l0ZW1fJyArIGZpZWxkLm5hbWUpO1xuICAgICAgICBpZiAoZWwpe1xuICAgICAgICAgICAgZWwuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpc1N0ZXBFbmFibGVkKHNlY3Rpb24pe1xuICAgICAgICBjb25zdCBwcmV2U2VjdGlvbj10aGlzLmZvcm1bdGhpcy5mb3JtLmluZGV4T2Yoc2VjdGlvbiktMV07XG4gICAgICAgIHJldHVybiAhdGhpcy52YWxpZGF0ZUJ5U3RlcENoYW5nZSB8fCAhcHJldlNlY3Rpb24gfHwgKHByZXZTZWN0aW9uICYmIHByZXZTZWN0aW9uLnN1Ym1pdGVkICYmICFwcmV2U2VjdGlvbi5oYXNFcnJvcik7XG4gICAgfVxuXG4gICAgb25JdGVtQ2hhbmdlcyhpdGVtKSB7XG4gICAgICAgIGlmICghdGhpcy5lZGl0YWJsZSl7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaXRlbS5lcnJvcnM9dGhpcy5zZXJ2aWNlLmdldEVycm9ycyhpdGVtKTtcbiAgICAgICAgY29uc3Qge3ZhbHVlfT10aGlzLnNlcnZpY2UuZ2V0VmFsdWUodGhpcy5mb3JtLCBmYWxzZSk7XG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgc2VsZWN0aW9uQ2hhbmdlZChldmVudDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gZXZlbnQuc2VsZWN0ZWRJbmRleDtcbiAgfVxuXG4gIHNldE1vYmlsZVN0ZXBwZXIoaXNNb2JpbGU6IGJvb2xlYW4pOiB2b2lkIHtcblxuICAgIHRoaXMuaXNNb2JpbGUgPSBpc01vYmlsZTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuc3RlcHBlcil7XG4gICAgICAgICAgICB0aGlzLnN0ZXBwZXIuc2VsZWN0ZWRJbmRleCA9IHRoaXMuc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgICBvblN0ZXBDaGFuZ2Uoc3RlcCkge1xuICAgICAgICAvL2NvbnNvbGUubG9nKHN0ZXApO1xuICAgICAgICB0aGlzLnN0ZXBDaGFuZ2VkLmVtaXQoc3RlcCk7XG4gICAgICAgIGlmICh0aGlzLnZhbGlkYXRlQnlTdGVwQ2hhbmdlICYmIHN0ZXAucHJldmlvdXNseVNlbGVjdGVkSW5kZXg+PTAgJiYgdGhpcy5mb3JtW3N0ZXAucHJldmlvdXNseVNlbGVjdGVkSW5kZXhdKXtcbiAgICAgICAgICAgIHRoaXMuc3VibWl0U3RlcCh0aGlzLmZvcm1bc3RlcC5wcmV2aW91c2x5U2VsZWN0ZWRJbmRleF0sIGZhbHNlKTtcbiAgICAgICAgfVxuXG5cbi8vICAgICAgICB0aGlzLnN0ZXBwZXIuc2VsZWN0ZWRJbmRleD0wO1xuICAgIH1cblxuICAgIHN1Ym1pdEZvcm0oKXtcblxuICAgICAgICBjb25zdCB7dmFsaWQsIHZhbHVlLCBmaXJzdEVycm9yfT10aGlzLnNlcnZpY2UuZ2V0VmFsdWUodGhpcy5mb3JtLCB0cnVlKTtcbiAgICAgICAgaWYgKHZhbGlkKXtcbiAgICAgICAgICAgIHRoaXMuc3VibWl0LmVtaXQodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxUb0ZpZWxkKGZpcnN0RXJyb3IpO1xuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBzdWJtaXRTdGVwKHNlY3Rpb24sIGdvVG9OZXh0KXtcbiAgICAgICAgaWYgKCF0aGlzLmVkaXRhYmxlKXtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvL2NvbnNvbGUubG9nKHNlY3Rpb24pO1xuICAgICAgICBjb25zdCB7dmFsaWQsIGZpcnN0RXJyb3J9PXRoaXMuc2VydmljZS5nZXRWYWx1ZShbc2VjdGlvbl0sIHRydWUpO1xuICAgICAgICAvL2NvbnNvbGUubG9nKHt2YWxpZCwgdmFsdWUsIGZpcnN0RXJyb3J9KTtcbiAgICAgICAgaWYgKHZhbGlkKXtcbiAgICAgICAgICAgIHNlY3Rpb24uaGFzRXJyb3I9ZmFsc2U7XG4gICAgICAgICAgICBzZWN0aW9uLnN1Ym1pdGVkPXRydWU7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKHRoaXMuc3RlcHBlcik7XG4gICAgICAgICAgICBpZiAoZ29Ub05leHQpe1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCk9PntcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGVwcGVyLm5leHQoKTtcbiAgICAgICAgICAgICAgICB9LCAxMDApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coZmlyc3RFcnJvcik7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbFRvRmllbGQoZmlyc3RFcnJvcik7XG4gICAgICAgICAgICBzZWN0aW9uLmhhc0Vycm9yPXRydWU7XG4gICAgICAgICAgICBpZiAoZmlyc3RFcnJvciAmJiBmaXJzdEVycm9yLmVycm9ycyAmJiBmaXJzdEVycm9yLmVycm9yc1swXSl7XG4gICAgICAgICAgICAgICAgc2VjdGlvbi5maXJzdEVycm9yVGV4dD1maXJzdEVycm9yLmxhYmVsKyc6ICcrZmlyc3RFcnJvci5lcnJvcnNbMF0ubWVzc2FnZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICAvL3RoaXMuX2JwU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG59XG4iLCI8ZGl2IChyZXNpemVkKT1cIm9uUmVzaXplZCgkZXZlbnQpXCI+XG4gICAgPGZvcm0gbmFtZT1cInN1cnZleUZvcm1cIiAqbmdJZj1cIiFzcGxpdEJ5U3RlcHNcIj5cbiAgICAgICAgPGZpZWxkc2V0IGNsYXNzPVwiZm9ybS1maWVsZHNldFwiICpuZ0Zvcj1cImxldCBzZWN0aW9uIG9mIGZvcm1cIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZXJ2aWNlLmlzU2VjdGlvblZpc2libGUoZm9ybSwgc2VjdGlvbilcIj5cbiAgICAgICAgICAgICAgICA8bGVnZW5kIGNsYXNzPVwiZm9ybS1sZWdlbmRcIiAqbmdJZj1cInNlY3Rpb24udGl0bGUgfHwgc2VjdGlvbi5zdWJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbbmdDbGFzc109XCInc2VjdGlvbi1zdHlsZS0nK3NlY3Rpb24uc2VjdGlvblN0eWxlXCIgW2lubmVySHRtbF09XCJzZWN0aW9uLnRpdGxlXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInNlY3Rpb24uc3VidGl0bGVcIj48YnIgLz48c21hbGwgW2lubmVySHRtbF09XCJzZWN0aW9uLnN1YnRpdGxlXCI+PC9zbWFsbD48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9sZWdlbmQ+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZHNldC1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygc2VjdGlvbi5pdGVtc1wiIFthdHRyLmlkXT1cIidmb3JtX2l0ZW1fJytpdGVtLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZ3gtc3VydmV5LWZvcm0taXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2VydmljZS5pc0l0ZW1WaXNpYmxlKGZvcm0sIHNlY3Rpb24sIGl0ZW0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJpdGVtLnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpdGVtXT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlZGl0YWJsZV09XCJlZGl0YWJsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzTW9iaWxlXT1cImlzTW9iaWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlcyk9XCJvbkl0ZW1DaGFuZ2VzKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPjwvbmd4LXN1cnZleS1mb3JtLWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZmllbGRzZXQ+XG4gICAgPC9mb3JtPlxuXG4gICAgPGRpdiAqbmdJZj1cInNwbGl0QnlTdGVwc1wiPlxuICAgICAgICA8bWF0LWhvcml6b250YWwtc3RlcHBlciAjc3RlcHBlciAqbmdJZj1cIiFpc01vYmlsZVwiXG4gICAgICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uU3RlcENoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgPlxuICAgIDwhLS1cbiAgICAgICAgPG5nLXRlbXBsYXRlIG1hdFN0ZXBwZXJJY29uPVwiZG9uZVwiIGxldC1pbmRleD1cImluZGV4XCI+XG4gICAgICAgICAgICB7e2luZGV4KzF9fVxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgLS0+XG5cbiAgICAgICAgPG1hdC1zdGVwICAqbmdGb3I9XCJsZXQgc2VjdGlvbiBvZiBmb3JtOyBpbmRleCBhcyBpO1wiXG4gICAgICAgICAgICBbZWRpdGFibGVdPVwiaXNTdGVwRW5hYmxlZChzZWN0aW9uKVwiXG4gICAgICAgICAgICBbY29tcGxldGVkXT1cInNlY3Rpb24uc3VibWl0ZWRcIlxuXG4gICAgICAgICAgICBbaGFzRXJyb3JdPVwic2VjdGlvbi5oYXNFcnJvclwiXG4gICAgICAgICAgICBbZXJyb3JNZXNzYWdlXT1cInNlY3Rpb24uZmlyc3RFcnJvclRleHRcIlxuICAgICAgICA+XG5cbiAgICAgICAgICAgIDxmb3JtPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBtYXRTdGVwTGFiZWw+e3tzZWN0aW9uLnRpdGxlfX08L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxoMyAqbmdJZj1cInNlY3Rpb24uc3VidGl0bGVcIj57e3NlY3Rpb24uc3VidGl0bGV9fTwvaDM+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBzZWN0aW9uLml0ZW1zXCIgW2F0dHIuaWRdPVwiJ2Zvcm1faXRlbV8nK2l0ZW0ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8bmd4LXN1cnZleS1mb3JtLWl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2VydmljZS5pc0l0ZW1WaXNpYmxlKGZvcm0sIHNlY3Rpb24sIGl0ZW0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cIml0ZW0udHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXRlbV09XCJpdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtlZGl0YWJsZV09XCJlZGl0YWJsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNNb2JpbGVdPVwiaXNNb2JpbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZXMpPVwib25JdGVtQ2hhbmdlcygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvbmd4LXN1cnZleS1mb3JtLWl0ZW0+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaTxmb3JtLmxlbmd0aC0xXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBidG4tYmxvY2tcIiAoY2xpY2spPVwic3VibWl0U3RlcChzZWN0aW9uLCB0cnVlKVwiPkNvbnRpbnVlPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpPj1mb3JtLmxlbmd0aC0xXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtY2VudGVyIHRleHQtZGFuZ2VyIGdsb2JhbC1lcnJvclwiICpuZ0lmPVwic3VibWl0RXJyb3JUZXh0XCI+e3tzdWJtaXRFcnJvclRleHR9fTxiciAvPjwvZGl2PlxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXN1Y2Nlc3MgYnRuLWJsb2NrXCIgKGNsaWNrKT1cInN1Ym1pdEZvcm0oKVwiIFtkaXNhYmxlZF09XCJzdWJtaXRJblByb2dyZXNzIHx8IHN1Ym1pdERpc2FibGVkXCI+PGkgY2xhc3M9XCJmYSBmYS1zcGlubmVyIGZhLXNwaW5cIiAqbmdJZj1cInN1Ym1pdEluUHJvZ3Jlc3NcIj48L2k+IFN1Ym1pdDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXN0ZXA+XG4gICAgICAgIDwvbWF0LWhvcml6b250YWwtc3RlcHBlcj5cblxuICAgICAgICA8bWF0LXZlcnRpY2FsLXN0ZXBwZXIgI3N0ZXBwZXIgKm5nSWY9XCJpc01vYmlsZVwiXG4gICAgICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uU3RlcENoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgPlxuICAgIDwhLS1cbiAgICAgICAgPG5nLXRlbXBsYXRlIG1hdFN0ZXBwZXJJY29uPVwiZG9uZVwiIGxldC1pbmRleD1cImluZGV4XCI+XG4gICAgICAgICAgICB7e2luZGV4KzF9fVxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgLS0+XG5cbiAgICAgICAgPG1hdC1zdGVwICAqbmdGb3I9XCJsZXQgc2VjdGlvbiBvZiBmb3JtOyBpbmRleCBhcyBpO1wiXG4gICAgICAgICAgICBbZWRpdGFibGVdPVwiaXNTdGVwRW5hYmxlZChzZWN0aW9uKVwiXG4gICAgICAgICAgICBbY29tcGxldGVkXT1cInNlY3Rpb24uc3VibWl0ZWRcIlxuXG4gICAgICAgICAgICBbaGFzRXJyb3JdPVwic2VjdGlvbi5oYXNFcnJvclwiXG4gICAgICAgICAgICBbZXJyb3JNZXNzYWdlXT1cInNlY3Rpb24uZmlyc3RFcnJvclRleHRcIlxuICAgICAgICA+XG5cbiAgICAgICAgICAgIDxmb3JtPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBtYXRTdGVwTGFiZWw+e3tzZWN0aW9uLnRpdGxlfX08L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxoMyAqbmdJZj1cInNlY3Rpb24uc3VidGl0bGVcIj57e3NlY3Rpb24uc3VidGl0bGV9fTwvaDM+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBzZWN0aW9uLml0ZW1zXCIgW2F0dHIuaWRdPVwiJ2Zvcm1faXRlbV8nK2l0ZW0ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8bmd4LXN1cnZleS1mb3JtLWl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2VydmljZS5pc0l0ZW1WaXNpYmxlKGZvcm0sIHNlY3Rpb24sIGl0ZW0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cIml0ZW0udHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXRlbV09XCJpdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtlZGl0YWJsZV09XCJlZGl0YWJsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlcyk9XCJvbkl0ZW1DaGFuZ2VzKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzTW9iaWxlXT1cImlzTW9iaWxlXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvbmd4LXN1cnZleS1mb3JtLWl0ZW0+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaTxmb3JtLmxlbmd0aC0xXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBidG4tYmxvY2tcIiAoY2xpY2spPVwic3VibWl0U3RlcChzZWN0aW9uLCB0cnVlKVwiPkNvbnRpbnVlPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpPj1mb3JtLmxlbmd0aC0xXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtY2VudGVyIHRleHQtZGFuZ2VyIGdsb2JhbC1lcnJvclwiICpuZ0lmPVwic3VibWl0RXJyb3JUZXh0XCI+e3tzdWJtaXRFcnJvclRleHR9fTxiciAvPjwvZGl2PlxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXN1Y2Nlc3MgYnRuLWJsb2NrXCIgKGNsaWNrKT1cInN1Ym1pdEZvcm0oKVwiIFtkaXNhYmxlZF09XCJzdWJtaXRJblByb2dyZXNzIHx8IHN1Ym1pdERpc2FibGVkXCI+PGkgY2xhc3M9XCJmYSBmYS1zcGlubmVyIGZhLXNwaW5cIiAqbmdJZj1cInN1Ym1pdEluUHJvZ3Jlc3NcIj48L2k+IFN1Ym1pdDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXN0ZXA+XG4gICAgICAgIDwvbWF0LXZlcnRpY2FsLXN0ZXBwZXI+XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==