@alfresco/adf-content-services
Version:
Alfresco ADF content services
147 lines • 36.6 kB
JavaScript
import { Component, DestroyRef, EventEmitter, inject, Inject, Optional, Output, ViewEncapsulation } from '@angular/core';
import { ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { TranslationService } from '@alfresco/adf-core';
import { NodesApiService } from '../../common/services/nodes-api.service';
import { forbidEndingDot, forbidOnlySpaces, forbidSpecialCharacters } from './folder-name.validators';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { AutoFocusDirective } from '../../directives';
import { MatButtonModule } from '@angular/material/button';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@angular/material/dialog";
import * as i3 from "../../common/services/nodes-api.service";
import * as i4 from "@alfresco/adf-core";
import * as i5 from "@angular/common";
import * as i6 from "@ngx-translate/core";
import * as i7 from "@angular/material/form-field";
import * as i8 from "@angular/material/input";
import * as i9 from "@angular/material/button";
export class FolderDialogComponent {
get editing() {
return !!this.data.folder;
}
get name() {
return this.getTrimmedValue(this.form.value.name);
}
get title() {
return this.getTrimmedValue(this.form.value.title);
}
get description() {
return this.getTrimmedValue(this.form.value.description);
}
get properties() {
return {
'cm:title': this.title,
'cm:description': this.description
};
}
constructor(formBuilder, dialog, nodesApi, translation, data) {
this.formBuilder = formBuilder;
this.dialog = dialog;
this.nodesApi = nodesApi;
this.translation = translation;
this.data = data;
/**
* Emitted when the edit/create folder give error for example a folder with same name already exist
*/
this.error = new EventEmitter();
/**
* Emitted when the edit/create folder is successfully created/modified
*/
this.success = new EventEmitter();
this.folder = null;
this.editTitle = 'CORE.FOLDER_DIALOG.EDIT_FOLDER_TITLE';
this.createTitle = 'CORE.FOLDER_DIALOG.CREATE_FOLDER_TITLE';
this.nodeType = 'cm:folder';
this.disableSubmitButton = false;
this.destroyRef = inject(DestroyRef);
if (data) {
this.editTitle = data.editTitle || this.editTitle;
this.createTitle = data.createTitle || this.createTitle;
this.nodeType = data.nodeType || this.nodeType;
}
}
ngOnInit() {
const { folder } = this.data;
let name = '';
let title = '';
let description = '';
if (folder) {
const { properties } = folder;
name = folder.name || '';
title = properties?.['cm:title'] ?? '';
description = properties?.['cm:description'] ?? '';
}
const validators = {
name: [Validators.required, forbidSpecialCharacters, forbidEndingDot, forbidOnlySpaces]
};
this.form = this.formBuilder.group({
name: [name, validators.name],
title: [title],
description: [description]
});
this.form.controls['name'].valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => (this.disableSubmitButton = false));
}
submit() {
this.disableSubmitButton = true;
(this.editing ? this.edit() : this.create()).subscribe((folder) => {
this.success.emit(folder);
this.dialog.close(folder);
}, (error) => this.handleError(error));
}
handleError(error) {
let errorMessage = 'CORE.MESSAGES.ERRORS.GENERIC';
try {
const { error: { statusCode } } = JSON.parse(error.message);
if (statusCode === 409) {
errorMessage = 'CORE.MESSAGES.ERRORS.EXISTENT_FOLDER';
}
}
catch (err) {
/* Do nothing, keep the original message */
}
this.error.emit(this.translation.instant(errorMessage));
return error;
}
create() {
const parentNodeId = this.data.parentNodeId;
return this.nodesApi.createFolder(parentNodeId, { name: this.name, properties: this.properties, nodeType: this.nodeType });
}
edit() {
const nodeId = this.data.folder.id;
return this.nodesApi.updateNode(nodeId, { name: this.name, properties: this.properties });
}
getTrimmedValue(value) {
return (value || '').trim();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: FolderDialogComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.MatDialogRef }, { token: i3.NodesApiService }, { token: i4.TranslationService }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: FolderDialogComponent, isStandalone: true, selector: "adf-folder-dialog", outputs: { error: "error", success: "success" }, host: { classAttribute: "adf-folder-dialog" }, ngImport: i0, template: "<h2 data-automation-id=\"adf-folder-dialog-title\" class=\"adf-folder-dialog-title\" mat-dialog-title>\n {{ (editing ? editTitle : createTitle) | translate }}\n</h2>\n\n<mat-dialog-content class=\"adf-folder-dialog-content\">\n <form [formGroup]=\"form\" (submit)=\"submit()\">\n <mat-form-field class=\"adf-full-width\">\n <mat-label>{{ 'CORE.FOLDER_DIALOG.FOLDER_NAME.LABEL' | translate }}</mat-label>\n <input\n id=\"adf-folder-name-input\"\n [attr.aria-label]=\"'CORE.FOLDER_DIALOG.FOLDER_NAME.LABEL' | translate\"\n matInput\n required\n [formControlName]=\"'name'\"\n adf-auto-focus\n />\n\n <mat-hint *ngIf=\"form.controls['name'].dirty\">\n <span *ngIf=\"form.controls['name'].errors?.required\">\n {{ 'CORE.FOLDER_DIALOG.FOLDER_NAME.ERRORS.REQUIRED' | translate }}\n </span>\n\n <span *ngIf=\"!form.controls['name'].errors?.required && form.controls['name'].errors?.message\">\n {{ form.controls['name'].errors?.message | translate }}\n </span>\n </mat-hint>\n </mat-form-field>\n\n <mat-form-field class=\"adf-full-width\">\n <mat-label>{{ 'CORE.FOLDER_DIALOG.FOLDER_TITLE.LABEL' | translate }}</mat-label>\n <input\n id=\"adf-folder-title-input\"\n matInput\n [attr.aria-label]=\"'CORE.FOLDER_DIALOG.FOLDER_TITLE.LABEL' | translate\"\n [formControlName]=\"'title'\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"adf-full-width\">\n <mat-label>{{ 'CORE.FOLDER_DIALOG.FOLDER_DESCRIPTION.LABEL' | translate }}</mat-label>\n <textarea\n id=\"adf-folder-description-input\"\n matInput\n [attr.aria-label]=\"'CORE.FOLDER_DIALOG.FOLDER_DESCRIPTION.LABEL' | translate\"\n rows=\"4\"\n [formControlName]=\"'description'\">\n </textarea>\n </mat-form-field>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions class=\"adf-dialog-buttons\">\n <span class=\"adf-fill-remaining-space\"></span>\n\n <button\n mat-button\n id=\"adf-folder-cancel-button\"\n mat-dialog-close>\n {{ 'CORE.FOLDER_DIALOG.CANCEL_BUTTON.LABEL' | translate }}\n </button>\n\n <button class=\"adf-dialog-action-button\"\n id=\"adf-folder-create-button\"\n mat-button\n (click)=\"submit()\"\n [disabled]=\"!form.valid || disableSubmitButton\">\n {{\n (editing\n ? 'CORE.FOLDER_DIALOG.UPDATE_BUTTON.LABEL'\n : 'CORE.FOLDER_DIALOG.CREATE_BUTTON.LABEL'\n ) | translate\n }}\n </button>\n</mat-dialog-actions>\n", styles: [".adf-folder-dialog .adf-folder-dialog-content{padding:0;overflow:unset}.adf-folder-dialog .adf-folder-dialog-content .mat-mdc-form-field-infix{padding-bottom:3.5px}.adf-folder-dialog .adf-folder-dialog-content .mat-form-field-hide-placeholder .mdc-floating-label{padding-top:20px}.adf-folder-dialog .adf-folder-dialog-content .mat-mdc-form-field-hint-wrapper{padding-left:0;margin-left:-2px;color:var(--adf-theme-foreground-secondary-text-color);font-size:10.5px}.adf-folder-dialog .adf-folder-dialog-title{display:inline-flex}.adf-fill-remaining-space{flex:1 1 auto}.adf-full-width{width:100%}.adf-dialog-buttons button{text-transform:uppercase}.adf-dialog-action-button:enabled{color:var(--theme-primary-color)}.adf-dialog-action-button:disabled>span{color:var(--adf-theme-foreground-text-color-054)}@media screen and (width <= 380px){.adf-folder-dialog-title{margin:0}.adf-dialog-buttons{padding:0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.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: "directive", type: AutoFocusDirective, selector: "[adf-auto-focus]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i9.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: FolderDialogComponent, decorators: [{
type: Component,
args: [{ selector: 'adf-folder-dialog', standalone: true, imports: [
CommonModule,
MatDialogModule,
TranslateModule,
ReactiveFormsModule,
MatFormFieldModule,
MatInputModule,
AutoFocusDirective,
MatButtonModule
], encapsulation: ViewEncapsulation.None, host: { class: 'adf-folder-dialog' }, template: "<h2 data-automation-id=\"adf-folder-dialog-title\" class=\"adf-folder-dialog-title\" mat-dialog-title>\n {{ (editing ? editTitle : createTitle) | translate }}\n</h2>\n\n<mat-dialog-content class=\"adf-folder-dialog-content\">\n <form [formGroup]=\"form\" (submit)=\"submit()\">\n <mat-form-field class=\"adf-full-width\">\n <mat-label>{{ 'CORE.FOLDER_DIALOG.FOLDER_NAME.LABEL' | translate }}</mat-label>\n <input\n id=\"adf-folder-name-input\"\n [attr.aria-label]=\"'CORE.FOLDER_DIALOG.FOLDER_NAME.LABEL' | translate\"\n matInput\n required\n [formControlName]=\"'name'\"\n adf-auto-focus\n />\n\n <mat-hint *ngIf=\"form.controls['name'].dirty\">\n <span *ngIf=\"form.controls['name'].errors?.required\">\n {{ 'CORE.FOLDER_DIALOG.FOLDER_NAME.ERRORS.REQUIRED' | translate }}\n </span>\n\n <span *ngIf=\"!form.controls['name'].errors?.required && form.controls['name'].errors?.message\">\n {{ form.controls['name'].errors?.message | translate }}\n </span>\n </mat-hint>\n </mat-form-field>\n\n <mat-form-field class=\"adf-full-width\">\n <mat-label>{{ 'CORE.FOLDER_DIALOG.FOLDER_TITLE.LABEL' | translate }}</mat-label>\n <input\n id=\"adf-folder-title-input\"\n matInput\n [attr.aria-label]=\"'CORE.FOLDER_DIALOG.FOLDER_TITLE.LABEL' | translate\"\n [formControlName]=\"'title'\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"adf-full-width\">\n <mat-label>{{ 'CORE.FOLDER_DIALOG.FOLDER_DESCRIPTION.LABEL' | translate }}</mat-label>\n <textarea\n id=\"adf-folder-description-input\"\n matInput\n [attr.aria-label]=\"'CORE.FOLDER_DIALOG.FOLDER_DESCRIPTION.LABEL' | translate\"\n rows=\"4\"\n [formControlName]=\"'description'\">\n </textarea>\n </mat-form-field>\n </form>\n</mat-dialog-content>\n\n<mat-dialog-actions class=\"adf-dialog-buttons\">\n <span class=\"adf-fill-remaining-space\"></span>\n\n <button\n mat-button\n id=\"adf-folder-cancel-button\"\n mat-dialog-close>\n {{ 'CORE.FOLDER_DIALOG.CANCEL_BUTTON.LABEL' | translate }}\n </button>\n\n <button class=\"adf-dialog-action-button\"\n id=\"adf-folder-create-button\"\n mat-button\n (click)=\"submit()\"\n [disabled]=\"!form.valid || disableSubmitButton\">\n {{\n (editing\n ? 'CORE.FOLDER_DIALOG.UPDATE_BUTTON.LABEL'\n : 'CORE.FOLDER_DIALOG.CREATE_BUTTON.LABEL'\n ) | translate\n }}\n </button>\n</mat-dialog-actions>\n", styles: [".adf-folder-dialog .adf-folder-dialog-content{padding:0;overflow:unset}.adf-folder-dialog .adf-folder-dialog-content .mat-mdc-form-field-infix{padding-bottom:3.5px}.adf-folder-dialog .adf-folder-dialog-content .mat-form-field-hide-placeholder .mdc-floating-label{padding-top:20px}.adf-folder-dialog .adf-folder-dialog-content .mat-mdc-form-field-hint-wrapper{padding-left:0;margin-left:-2px;color:var(--adf-theme-foreground-secondary-text-color);font-size:10.5px}.adf-folder-dialog .adf-folder-dialog-title{display:inline-flex}.adf-fill-remaining-space{flex:1 1 auto}.adf-full-width{width:100%}.adf-dialog-buttons button{text-transform:uppercase}.adf-dialog-action-button:enabled{color:var(--theme-primary-color)}.adf-dialog-action-button:disabled>span{color:var(--adf-theme-foreground-text-color-054)}@media screen and (width <= 380px){.adf-folder-dialog-title{margin:0}.adf-dialog-buttons{padding:0}}\n"] }]
}], ctorParameters: () => [{ type: i1.UntypedFormBuilder }, { type: i2.MatDialogRef }, { type: i3.NodesApiService }, { type: i4.TranslationService }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [MAT_DIALOG_DATA]
}] }], propDecorators: { error: [{
type: Output
}], success: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9sZGVyLmRpYWxvZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYi9jb250ZW50LXNlcnZpY2VzL3NyYy9saWIvZGlhbG9ncy9mb2xkZXIvZm9sZGVyLmRpYWxvZy50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYi9jb250ZW50LXNlcnZpY2VzL3NyYy9saWIvZGlhbG9ncy9mb2xkZXIvZm9sZGVyLmRpYWxvZy5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBVSxRQUFRLEVBQUUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pJLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBb0IsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkcsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFMUYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDeEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN0RyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsZUFBZSxF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eXFDQUNuQixrQkFBa0Isa1lBQ2xCLGNBQWMsMldBQ2Qsa0JBQWtCLDREQUNsQixlQUFlOzsyRkFPVixxQkFBcUI7a0JBbEJqQyxTQUFTOytCQUNJLG1CQUFtQixjQUNqQixJQUFJLFdBQ1A7d0JBQ0wsWUFBWTt3QkFDWixlQUFlO3dCQUNmLGVBQWU7d0JBQ2YsbUJBQW1CO3dCQUNuQixrQkFBa0I7d0JBQ2xCLGNBQWM7d0JBQ2Qsa0JBQWtCO3dCQUNsQixlQUFlO3FCQUNsQixpQkFHYyxpQkFBaUIsQ0FBQyxJQUFJLFFBQy9CLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFFOzswQkFzRC9CLFFBQVE7OzBCQUNSLE1BQU07MkJBQUMsZUFBZTt5Q0FoRDNCLEtBQUs7c0JBREosTUFBTTtnQkFPUCxPQUFPO3NCQUROLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgwqkgMjAwNS0yMDI1IEh5bGFuZCBTb2Z0d2FyZSwgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IENvbXBvbmVudCwgRGVzdHJveVJlZiwgRXZlbnRFbWl0dGVyLCBpbmplY3QsIEluamVjdCwgT25Jbml0LCBPcHRpb25hbCwgT3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVhY3RpdmVGb3Jtc01vZHVsZSwgVW50eXBlZEZvcm1CdWlsZGVyLCBVbnR5cGVkRm9ybUdyb3VwLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTUFUX0RJQUxPR19EQVRBLCBNYXREaWFsb2dNb2R1bGUsIE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnQGFsZnJlc2NvL2pzLWFwaSc7XG5pbXBvcnQgeyBUcmFuc2xhdGlvblNlcnZpY2UgfSBmcm9tICdAYWxmcmVzY28vYWRmLWNvcmUnO1xuaW1wb3J0IHsgTm9kZXNBcGlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29tbW9uL3NlcnZpY2VzL25vZGVzLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IGZvcmJpZEVuZGluZ0RvdCwgZm9yYmlkT25seVNwYWNlcywgZm9yYmlkU3BlY2lhbENoYXJhY3RlcnMgfSBmcm9tICcuL2ZvbGRlci1uYW1lLnZhbGlkYXRvcnMnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFRyYW5zbGF0ZU1vZHVsZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IEF1dG9Gb2N1c0RpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMnO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhZGYtZm9sZGVyLWRpYWxvZycsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIENvbW1vbk1vZHVsZSxcbiAgICAgICAgTWF0RGlhbG9nTW9kdWxlLFxuICAgICAgICBUcmFuc2xhdGVNb2R1bGUsXG4gICAgICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgICAgIE1hdEZvcm1GaWVsZE1vZHVsZSxcbiAgICAgICAgTWF0SW5wdXRNb2R1bGUsXG4gICAgICAgIEF1dG9Gb2N1c0RpcmVjdGl2ZSxcbiAgICAgICAgTWF0QnV0dG9uTW9kdWxlXG4gICAgXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZm9sZGVyLmRpYWxvZy5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9mb2xkZXIuZGlhbG9nLnNjc3MnXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIGhvc3Q6IHsgY2xhc3M6ICdhZGYtZm9sZGVyLWRpYWxvZycgfVxufSlcbmV4cG9ydCBjbGFzcyBGb2xkZXJEaWFsb2dDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgd2hlbiB0aGUgZWRpdC9jcmVhdGUgZm9sZGVyIGdpdmUgZXJyb3IgZm9yIGV4YW1wbGUgYSBmb2xkZXIgd2l0aCBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIGVycm9yOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCB3aGVuIHRoZSBlZGl0L2NyZWF0ZSBmb2xkZXIgaXMgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQvbW9kaWZpZWRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBzdWNjZXNzOiBFdmVudEVtaXR0ZXI8Tm9kZT4gPSBuZXcgRXZlbnRFbWl0dGVyPE5vZGU+KCk7XG5cbiAgICBmb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICAgIGZvbGRlcjogTm9kZSA9IG51bGw7XG5cbiAgICBlZGl0VGl0bGUgPSAnQ09SRS5GT0xERVJfRElBTE9HLkVESVRfRk9MREVSX1RJVExFJztcbiAgICBjcmVhdGVUaXRsZSA9ICdDT1JFLkZPTERFUl9ESUFMT0cuQ1JFQVRFX0ZPTERFUl9USVRMRSc7XG4gICAgbm9kZVR5cGUgPSAnY206Zm9sZGVyJztcblxuICAgIGRpc2FibGVTdWJtaXRCdXR0b24gPSBmYWxzZTtcblxuICAgIGdldCBlZGl0aW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLmRhdGEuZm9sZGVyO1xuICAgIH1cblxuICAgIGdldCBuYW1lKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRyaW1tZWRWYWx1ZSh0aGlzLmZvcm0udmFsdWUubmFtZSk7XG4gICAgfVxuXG4gICAgZ2V0IHRpdGxlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRyaW1tZWRWYWx1ZSh0aGlzLmZvcm0udmFsdWUudGl0bGUpO1xuICAgIH1cblxuICAgIGdldCBkZXNjcmlwdGlvbigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUcmltbWVkVmFsdWUodGhpcy5mb3JtLnZhbHVlLmRlc2NyaXB0aW9uKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldCBwcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgJ2NtOnRpdGxlJzogdGhpcy50aXRsZSxcbiAgICAgICAgICAgICdjbTpkZXNjcmlwdGlvbic6IHRoaXMuZGVzY3JpcHRpb25cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgICAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nUmVmPEZvbGRlckRpYWxvZ0NvbXBvbmVudD4sXG4gICAgICAgIHByaXZhdGUgbm9kZXNBcGk6IE5vZGVzQXBpU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGlvbjogVHJhbnNsYXRpb25TZXJ2aWNlLFxuICAgICAgICBAT3B0aW9uYWwoKVxuICAgICAgICBASW5qZWN0KE1BVF9ESUFMT0dfREFUQSlcbiAgICAgICAgcHVibGljIGRhdGE6IGFueVxuICAgICkge1xuICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5lZGl0VGl0bGUgPSBkYXRhLmVkaXRUaXRsZSB8fCB0aGlzLmVkaXRUaXRsZTtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlVGl0bGUgPSBkYXRhLmNyZWF0ZVRpdGxlIHx8IHRoaXMuY3JlYXRlVGl0bGU7XG4gICAgICAgICAgICB0aGlzLm5vZGVUeXBlID0gZGF0YS5ub2RlVHlwZSB8fCB0aGlzLm5vZGVUeXBlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIGNvbnN0IHsgZm9sZGVyIH0gPSB0aGlzLmRhdGE7XG4gICAgICAgIGxldCBuYW1lID0gJyc7XG4gICAgICAgIGxldCB0aXRsZSA9ICcnO1xuICAgICAgICBsZXQgZGVzY3JpcHRpb24gPSAnJztcblxuICAgICAgICBpZiAoZm9sZGVyKSB7XG4gICAgICAgICAgICBjb25zdCB7IHByb3BlcnRpZXMgfSA9IGZvbGRlcjtcblxuICAgICAgICAgICAgbmFtZSA9IGZvbGRlci5uYW1lIHx8ICcnO1xuICAgICAgICAgICAgdGl0bGUgPSBwcm9wZXJ0aWVzPy5bJ2NtOnRpdGxlJ10gPz8gJyc7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbiA9IHByb3BlcnRpZXM/LlsnY206ZGVzY3JpcHRpb24nXSA/PyAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZhbGlkYXRvcnMgPSB7XG4gICAgICAgICAgICBuYW1lOiBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgZm9yYmlkU3BlY2lhbENoYXJhY3RlcnMsIGZvcmJpZEVuZGluZ0RvdCwgZm9yYmlkT25seVNwYWNlc11cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmZvcm0gPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgICAgICAgIG5hbWU6IFtuYW1lLCB2YWxpZGF0b3JzLm5hbWVdLFxuICAgICAgICAgICAgdGl0bGU6IFt0aXRsZV0sXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogW2Rlc2NyaXB0aW9uXVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmZvcm0uY29udHJvbHNbJ25hbWUnXS52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKCgpID0+ICh0aGlzLmRpc2FibGVTdWJtaXRCdXR0b24gPSBmYWxzZSkpO1xuICAgIH1cblxuICAgIHN1Ym1pdCgpIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlU3VibWl0QnV0dG9uID0gdHJ1ZTtcblxuICAgICAgICAodGhpcy5lZGl0aW5nID8gdGhpcy5lZGl0KCkgOiB0aGlzLmNyZWF0ZSgpKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAoZm9sZGVyOiBOb2RlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzLmVtaXQoZm9sZGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZy5jbG9zZShmb2xkZXIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvcikgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnJvcilcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBoYW5kbGVFcnJvcihlcnJvcjogYW55KTogYW55IHtcbiAgICAgICAgbGV0IGVycm9yTWVzc2FnZSA9ICdDT1JFLk1FU1NBR0VTLkVSUk9SUy5HRU5FUklDJztcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgIGVycm9yOiB7IHN0YXR1c0NvZGUgfVxuICAgICAgICAgICAgfSA9IEpTT04ucGFyc2UoZXJyb3IubWVzc2FnZSk7XG5cbiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID09PSA0MDkpIHtcbiAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSAnQ09SRS5NRVNTQUdFUy5FUlJPUlMuRVhJU1RFTlRfRk9MREVSJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvKiBEbyBub3RoaW5nLCBrZWVwIHRoZSBvcmlnaW5hbCBtZXNzYWdlICovXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmVycm9yLmVtaXQodGhpcy50cmFuc2xhdGlvbi5pbnN0YW50KGVycm9yTWVzc2FnZSkpO1xuXG4gICAgICAgIHJldHVybiBlcnJvcjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZSgpOiBPYnNlcnZhYmxlPE5vZGU+IHtcbiAgICAgICAgY29uc3QgcGFyZW50Tm9kZUlkID0gdGhpcy5kYXRhLnBhcmVudE5vZGVJZDtcblxuICAgICAgICByZXR1cm4gdGhpcy5ub2Rlc0FwaS5jcmVhdGVGb2xkZXIocGFyZW50Tm9kZUlkLCB7IG5hbWU6IHRoaXMubmFtZSwgcHJvcGVydGllczogdGhpcy5wcm9wZXJ0aWVzLCBub2RlVHlwZTogdGhpcy5ub2RlVHlwZSB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGVkaXQoKTogT2JzZXJ2YWJsZTxOb2RlPiB7XG4gICAgICAgIGNvbnN0IG5vZGVJZCA9IHRoaXMuZGF0YS5mb2xkZXIuaWQ7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZXNBcGkudXBkYXRlTm9kZShub2RlSWQsIHsgbmFtZTogdGhpcy5uYW1lLCBwcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXMgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRUcmltbWVkVmFsdWUodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAodmFsdWUgfHwgJycpLnRyaW0oKTtcbiAgICB9XG59XG4iLCI8aDIgZGF0YS1hdXRvbWF0aW9uLWlkPVwiYWRmLWZvbGRlci1kaWFsb2ctdGl0bGVcIiBjbGFzcz1cImFkZi1mb2xkZXItZGlhbG9nLXRpdGxlXCIgbWF0LWRpYWxvZy10aXRsZT5cbiAgICB7eyAoZWRpdGluZyA/IGVkaXRUaXRsZSA6IGNyZWF0ZVRpdGxlKSB8IHRyYW5zbGF0ZSB9fVxuPC9oMj5cblxuPG1hdC1kaWFsb2ctY29udGVudCBjbGFzcz1cImFkZi1mb2xkZXItZGlhbG9nLWNvbnRlbnRcIj5cbiAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIiAoc3VibWl0KT1cInN1Ym1pdCgpXCI+XG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImFkZi1mdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdDT1JFLkZPTERFUl9ESUFMT0cuRk9MREVSX05BTUUuTEFCRUwnIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICBpZD1cImFkZi1mb2xkZXItbmFtZS1pbnB1dFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInQ09SRS5GT0xERVJfRElBTE9HLkZPTERFUl9OQU1FLkxBQkVMJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICByZXF1aXJlZFxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiJ25hbWUnXCJcbiAgICAgICAgICAgICAgICBhZGYtYXV0by1mb2N1c1xuICAgICAgICAgICAgLz5cblxuICAgICAgICAgICAgPG1hdC1oaW50ICpuZ0lmPVwiZm9ybS5jb250cm9sc1snbmFtZSddLmRpcnR5XCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJmb3JtLmNvbnRyb2xzWyduYW1lJ10uZXJyb3JzPy5yZXF1aXJlZFwiPlxuICAgICAgICAgICAgICAgICAgICB7eyAnQ09SRS5GT0xERVJfRElBTE9HLkZPTERFUl9OQU1FLkVSUk9SUy5SRVFVSVJFRCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFmb3JtLmNvbnRyb2xzWyduYW1lJ10uZXJyb3JzPy5yZXF1aXJlZCAmJiBmb3JtLmNvbnRyb2xzWyduYW1lJ10uZXJyb3JzPy5tZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGZvcm0uY29udHJvbHNbJ25hbWUnXS5lcnJvcnM/Lm1lc3NhZ2UgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImFkZi1mdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdDT1JFLkZPTERFUl9ESUFMT0cuRk9MREVSX1RJVExFLkxBQkVMJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgaWQ9XCJhZGYtZm9sZGVyLXRpdGxlLWlucHV0XCJcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0NPUkUuRk9MREVSX0RJQUxPRy5GT0xERVJfVElUTEUuTEFCRUwnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cIid0aXRsZSdcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJhZGYtZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgPG1hdC1sYWJlbD57eyAnQ09SRS5GT0xERVJfRElBTE9HLkZPTERFUl9ERVNDUklQVElPTi5MQUJFTCcgfCB0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDx0ZXh0YXJlYVxuICAgICAgICAgICAgICAgIGlkPVwiYWRmLWZvbGRlci1kZXNjcmlwdGlvbi1pbnB1dFwiXG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidDT1JFLkZPTERFUl9ESUFMT0cuRk9MREVSX0RFU0NSSVBUSU9OLkxBQkVMJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgcm93cz1cIjRcIlxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiJ2Rlc2NyaXB0aW9uJ1wiPlxuICAgICAgICAgICAgPC90ZXh0YXJlYT5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICA8L2Zvcm0+XG48L21hdC1kaWFsb2ctY29udGVudD5cblxuPG1hdC1kaWFsb2ctYWN0aW9ucyBjbGFzcz1cImFkZi1kaWFsb2ctYnV0dG9uc1wiPlxuICAgIDxzcGFuIGNsYXNzPVwiYWRmLWZpbGwtcmVtYWluaW5nLXNwYWNlXCI+PC9zcGFuPlxuXG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIGlkPVwiYWRmLWZvbGRlci1jYW5jZWwtYnV0dG9uXCJcbiAgICAgICAgbWF0LWRpYWxvZy1jbG9zZT5cbiAgICAgICAge3sgJ0NPUkUuRk9MREVSX0RJQUxPRy5DQU5DRUxfQlVUVE9OLkxBQkVMJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvbiBjbGFzcz1cImFkZi1kaWFsb2ctYWN0aW9uLWJ1dHRvblwiXG4gICAgICAgICAgICBpZD1cImFkZi1mb2xkZXItY3JlYXRlLWJ1dHRvblwiXG4gICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICAoY2xpY2spPVwic3VibWl0KClcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFmb3JtLnZhbGlkIHx8IGRpc2FibGVTdWJtaXRCdXR0b25cIj5cbiAgICAgICAge3tcbiAgICAgICAgKGVkaXRpbmdcbiAgICAgICAgPyAnQ09SRS5GT0xERVJfRElBTE9HLlVQREFURV9CVVRUT04uTEFCRUwnXG4gICAgICAgIDogJ0NPUkUuRk9MREVSX0RJQUxPRy5DUkVBVEVfQlVUVE9OLkxBQkVMJ1xuICAgICAgICApIHwgdHJhbnNsYXRlXG4gICAgICAgIH19XG4gICAgPC9idXR0b24+XG48L21hdC1kaWFsb2ctYWN0aW9ucz5cbiJdfQ==