lib-sketch-tool
Version:
## Installing with npm $ npm install --save lib-sketch-tool
408 lines • 55.7 kB
JavaScript
import * as tslib_1 from "tslib";
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
import { AvailableGeometricShape } from './../constants/available-geometric-shapes';
import { CanvasManagerService } from './../services/canvas-manager.service';
import { TranslateService } from '@ngx-translate/core';
import { ActionSheetController } from '@ionic/angular';
//import { GestureController } from ‘@ionic/core/dist/collection/utils/gesture/gesture-controller’;
const Black = '#000000';
const Transparent = 'transparent';
let MobileSketchToolComponent = class MobileSketchToolComponent {
constructor(actionSheetCtrl, canvasManagerService, translate) {
this.actionSheetCtrl = actionSheetCtrl;
this.canvasManagerService = canvasManagerService;
this.translate = translate;
this.canvas = new EventEmitter();
this.strokeColor = Black;
this.fillColor = Transparent;
this.isCropping = false;
this.isPanning = false;
this.isLoaded = false;
this.isUndoAvailable = false;
this.isSelectingColor = false;
}
ngOnInit() {
if (this.imageData) {
this.canvasManagerService.emptyCanvas();
if (this.loadedJson == null || this.loadedJson.length < 10) {
this.canvasManagerService.setBackgroundFromURL(this.imageData);
}
else {
this.previousJson = JSON.parse(this.loadedJson);
this.currentJson = this.previousJson;
this.canvasManagerService
.loadfromJson(JSON.parse(this.loadedJson));
}
this.isLoaded = true;
this.previousImageData = this.imageData;
}
this.emitCanvas();
}
ngOnChanges() {
if (this.isLoaded) {
if (this.loadedJson === null || this.loadedJson.length < 10 || this.imageData !== this.previousImageData) {
this.canvasManagerService.emptyCanvas();
this.canvasManagerService.setBackgroundFromURL(this.imageData);
this.previousImageData = this.imageData;
this.currentJson = null;
}
else if (this.loadedJson !== JSON.stringify(this.currentJson)) {
this.previousJson = JSON.parse(this.loadedJson);
this.currentJson = this.previousJson;
this.canvasManagerService
.loadfromJson(JSON.parse(this.loadedJson));
}
}
this.emitCanvas();
}
ngAfterViewInit() {
/*this.gesture = new Gesture(this.element.nativeElement);
this.gesture.listen();
this.gesture.on('pinch', $event => this.pinch($event));*/
}
ngOnDestroy() {
//this.gesture.destroy();
}
get hasPictograms() {
return !(!this.pictograms);
}
addText() {
this.disableAllStates();
this.canvasManagerService.addText(this.strokeColor, 'text ');
this.emitCanvas();
}
addShape(shape) {
this.disableAllStates();
this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape[shape]);
this.emitCanvas();
}
addImage(source) {
this.disableAllStates();
this.canvasManagerService.addImage(this.pictogramsPath + source);
this.emitCanvas();
}
changeStrokeColor() {
this.canvasManagerService.changeSelectedObjectsStrokeColor(this.strokeColor);
this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
this.emitCanvas();
}
bringFoward() {
this.disableAllStates();
this.canvasManagerService.bringSelectedObjectsToFront();
this.emitCanvas();
}
sendToBack() {
this.disableAllStates();
this.canvasManagerService.sendSelectedObjectsToBack();
this.emitCanvas();
}
crop() {
if (this.isCropping) {
this.disableCroppping();
}
else {
this.disableAllStates();
this.isCropping = true;
this.canvasManagerService.resetZoom();
this.canvasManagerService.disableSelection();
this.canvasManagerService.addSelectionRectangle();
this.isUndoAvailable = true;
this.previousJson = this.canvasManagerService.jsonFromCanvas();
this.emitCanvas();
}
}
disableCroppping() {
this.isCropping = false;
this.canvasManagerService.enableSlection();
this.isUndoAvailable = false;
}
deleteSelection() {
this.disableAllStates();
this.canvasManagerService.deleteSelectedObjects();
this.emitCanvas();
}
mouseUp() {
if (this.isCropping) {
this.isCropping = false;
this.canvasManagerService.cropImage();
this.isUndoAvailable = true;
this.emitCanvas();
}
}
mouseMove(event) {
if (this.isCropping) {
this.canvasManagerService.ajustCropRectangle(event);
}
else if (this.isPanning) {
this.canvasManagerService.panCanvas(event);
}
}
mouseDown(event) {
if (this.isCropping) {
this.canvasManagerService.startSelectingCropRectangle(event);
}
else if (this.isPanning) {
this.canvasManagerService.setLastPanPosition(event);
}
}
pinch(event) {
event.preventDefault();
this.disableDrawing();
this.canvasManagerService.zoom(event);
}
group() {
this.disableAllStates();
this.canvasManagerService.groupSelectedObjects();
this.emitCanvas();
}
undo() {
this.canvasManagerService.loadfromJson(this.previousJson);
this.isUndoAvailable = false;
this.emitCanvas();
}
onColorClicked() {
this.isSelectingColor = true;
this.stopPanning();
}
onMoveClicked() {
this.isPanning = !this.isPanning;
this.disableDrawing();
if (this.isPanning) {
this.canvasManagerService.disableSelection();
}
else {
this.canvasManagerService.enableSlection();
}
}
disablePanning() {
this.isPanning = false;
this.canvasManagerService.enableSlection();
}
disableAllStates() {
this.disableDrawing();
this.disablePanning();
}
stopPanning() {
if (this.isPanning) {
this.isPanning = false;
this.canvasManagerService.enableSlection();
}
}
setColor(color) {
this.strokeColor = color;
this.changeStrokeColor();
this.isSelectingColor = false;
this.emitCanvas();
}
draw() {
this.isDrawing = !this.isDrawing;
this.canvasManagerService.toggleFreeDrawing();
this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
if (this.isDrawing) {
this.isPanning = false;
}
}
disableDrawing() {
if (this.isDrawing) {
this.isDrawing = false;
this.canvasManagerService.toggleFreeDrawing();
}
}
translateShapeButtonsText() {
const translationArray = [];
translationArray.push(this.translate.instant('rectangle'));
translationArray.push(this.translate.instant('triangle'));
translationArray.push(this.translate.instant('circle'));
translationArray.push(this.translate.instant('line'));
translationArray.push(this.translate.instant('cross'));
translationArray.push(this.translate.instant('text'));
return translationArray;
}
presentShapeActionSheet() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.disableDrawing();
const titleText = this.translate.instant('addGeometricShape');
const buttonsText = this.translateShapeButtonsText();
let i = 0;
const actionSheet = yield this.actionSheetCtrl.create({
header: titleText,
buttons: [
{
text: '\uf0c8 ' + buttonsText[i++],
handler: () => {
this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Rectangle);
}
},
{
text: '\uf0d8 ' + buttonsText[i++],
handler: () => {
this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Triangle);
}
},
{
text: '\uf111 ' + buttonsText[i++],
handler: () => {
this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Circle);
}
},
{
text: '\uf068 ' + buttonsText[i++],
handler: () => {
this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Line);
}
},
{
text: '\uf067 ' + buttonsText[i++],
handler: () => {
this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Cross);
}
},
{
text: '\uf031 ' + buttonsText[i++],
handler: () => {
this.canvasManagerService.addText(this.strokeColor, '');
}
}
]
});
yield actionSheet.present();
});
}
translateEditButtonsText() {
const translationArray = [];
translationArray.push(this.translate.instant('crop'));
translationArray.push(this.translate.instant('group'));
translationArray.push(this.translate.instant('bringToFront'));
translationArray.push(this.translate.instant('sendToBack'));
translationArray.push(this.translate.instant('delete'));
return translationArray;
}
presentEditActionSheet() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.disableDrawing();
const titleText = this.translate.instant('edition');
const buttonsText = this.translateEditButtonsText();
let i = 0;
const actionSheet = yield this.actionSheetCtrl.create({
header: titleText,
buttons: [
{
text: '\uf125 ' + buttonsText[i++],
handler: () => {
this.crop();
}
},
{
text: '\uf247 ' + buttonsText[i++],
handler: () => {
this.group();
}
},
{
text: '\uf0de ' + buttonsText[i++],
handler: () => {
this.bringFoward();
}
},
{
text: '\uf0dd ' + buttonsText[i++],
handler: () => {
this.sendToBack();
}
},
{
text: '\uf1f8 ' + buttonsText[i++],
handler: () => {
this.deleteSelection();
}
}
]
});
yield actionSheet.present();
});
}
presentPictogramsActionSheet() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.disableDrawing();
const buttons = [];
const actionSheetStyles = [];
const images = this.pictograms;
for (let i = 0; i < images.length; i++) {
const style = document.createElement('style');
style.type = 'text/css';
style.innerHTML =
'.customCSSClass' +
i +
'{background: url(' +
"'" +
this.pictogramsPath +
images[i] +
"'" +
') no-repeat !important;padding-left:50px !important;height:80px; background-position: left center !important;}';
document.getElementsByTagName('head')[0].appendChild(style);
actionSheetStyles.push(style);
buttons.push({
role: 'destructive',
text: images[i],
cssClass: 'customCSSClass' + i,
handler: () => {
this.addImage(images[i]);
}
});
}
const titleText = this.translate.instant('addPictogram');
const actionSheet = yield this.actionSheetCtrl.create({
header: titleText,
buttons: buttons
});
actionSheet.onDidDismiss().then(() => {
for (let i = 0; i < actionSheetStyles.length; i++) {
if (actionSheetStyles[i].parentNode != null) {
actionSheetStyles[i].parentNode.removeChild(actionSheetStyles[i]);
}
}
});
yield actionSheet.present();
});
}
emitCanvas() {
this.canvas.emit(this.canvasManagerService.canvas);
}
};
tslib_1.__decorate([
ViewChild('pinchElement'),
tslib_1.__metadata("design:type", Object)
], MobileSketchToolComponent.prototype, "element", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], MobileSketchToolComponent.prototype, "imageData", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], MobileSketchToolComponent.prototype, "loadedJson", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], MobileSketchToolComponent.prototype, "pictogramsPath", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Array)
], MobileSketchToolComponent.prototype, "pictograms", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", Object)
], MobileSketchToolComponent.prototype, "canvas", void 0);
MobileSketchToolComponent = tslib_1.__decorate([
Component({
selector: 'lib-mobile-sketch-tool',
template: "<ion-content>\n <div class=\"div-canvas-container\" (touchstart)=\"mouseDown($event)\" (touchmove)=\"mouseMove($event)\" (touchend)=\"mouseUp()\"\n #pinchElement>\n <canvas id=\"canvas\"></canvas>\n\n <div class=\"color-picker\" *ngIf=\"isSelectingColor\">\n <ion-grid fixed>\n <ion-row>\n <ion-col style=\"background:#660000\" (tap)=\"setColor('#660000')\">\n </ion-col>\n <ion-col style=\"background:#663300\" (tap)=\"setColor('#663300')\">\n </ion-col>\n <ion-col style=\"background:#666600\" (tap)=\"setColor('#666600')\">\n </ion-col>\n <ion-col style=\"background:#006600\" (tap)=\"setColor('#006600')\">\n </ion-col>\n <ion-col style=\"background:#000066\" (tap)=\"setColor('#000066')\">\n </ion-col>\n <ion-col style=\"background:#660066\" (tap)=\"setColor('#660066')\">\n </ion-col>\n\n </ion-row>\n <ion-row>\n <ion-col style=\"background:#CC0000\" (tap)=\"setColor('#CC0000')\">\n </ion-col>\n <ion-col style=\"background:#CC6600\" (tap)=\"setColor('#CC6600')\">\n </ion-col>\n <ion-col style=\"background:#CCCC00\" (tap)=\"setColor('#CCCC00')\">\n </ion-col>\n <ion-col style=\"background:#00CC00\" (tap)=\"setColor('#00CC00')\">\n </ion-col>\n <ion-col style=\"background:#0000CC\" (tap)=\"setColor('#0000CC')\">\n </ion-col>\n <ion-col style=\"background:#CC00CC\" (tap)=\"setColor('#CC00CC')\">\n </ion-col>\n\n </ion-row>\n <ion-row>\n <ion-col style=\"background:#FF0000\" (tap)=\"setColor('#FF0000')\">\n </ion-col>\n <ion-col style=\"background:#FF8000\" (tap)=\"setColor('#FF8000')\">\n </ion-col>\n <ion-col style=\"background:#FFFF00\" (tap)=\"setColor('#FFFF00')\">\n </ion-col>\n <ion-col style=\"background:#00FF00\" (tap)=\"setColor('#00FF00')\">\n </ion-col>\n <ion-col style=\"background:#0000FF\" (tap)=\"setColor('#0000FF')\">\n </ion-col>\n <ion-col style=\"background:#FF00FF\" (tap)=\"setColor('#FF00FF')\">\n </ion-col>\n\n </ion-row>\n <ion-row>\n <ion-col style=\"background:#FF6666\" (tap)=\"setColor('#FF6666')\">\n </ion-col>\n <ion-col style=\"background:#FFB266\" (tap)=\"setColor('#FFB266')\">\n </ion-col>\n <ion-col style=\"background:#FFFF66\" (tap)=\"setColor('#FFFF66')\">\n </ion-col>\n <ion-col style=\"background:#66FF66\" (tap)=\"setColor('#66FF66')\">\n </ion-col>\n <ion-col style=\"background:#6666FF\" (tap)=\"setColor('#6666FF')\">\n </ion-col>\n <ion-col style=\"background:#FF66FF\" (tap)=\"setColor('#FF66FF')\">\n </ion-col>\n\n </ion-row>\n <ion-row>\n <ion-col style=\"background:#FF9999\" (tap)=\"setColor('#FF9999')\">\n </ion-col>\n <ion-col style=\"background:#FFCC99\" (tap)=\"setColor('#FFCC99')\">\n </ion-col>\n <ion-col style=\"background:#FFFF99\" (tap)=\"setColor('#FFFF99')\">\n </ion-col>\n <ion-col style=\"background:#99FF99\" (tap)=\"setColor('#99FF99')\">\n </ion-col>\n <ion-col style=\"background:#9999FF\" (tap)=\"setColor('#9999FF')\">\n </ion-col>\n <ion-col style=\"background:#FF99FF\" (tap)=\"setColor('#FF99FF')\">\n </ion-col>\n\n </ion-row>\n <ion-row>\n <ion-col style=\"background:#FFFFFF\" (tap)=\"setColor('#FFFFFF')\">\n </ion-col>\n <ion-col style=\"background:#C0C0C0\" (tap)=\"setColor('#C0C0C0')\">\n </ion-col>\n <ion-col style=\"background:#808080\" (tap)=\"setColor('#808080')\">\n </ion-col>\n <ion-col style=\"background:#606060\" (tap)=\"setColor('#606060')\">\n </ion-col>\n <ion-col style=\"background:#303030\" (tap)=\"setColor('#606060')\">\n </ion-col>\n <ion-col style=\"background:#000000\" (tap)=\"setColor('#000000')\">\n </ion-col>\n </ion-row>\n </ion-grid>\n </div>\n </div>\n</ion-content>\n\n<ion-footer>\n <ion-toolbar>\n <div class=\"div-edit-toolbar\">\n <ion-button class=\"button-edit-toolbar\" size=\"large\" fill=\"clear\" (click)=\"presentShapeActionSheet()\">\n <i class=\"fas fa-shapes\" id=\"icon\"></i>\n </ion-button>\n\n <ion-button class=\"button-edit-toolbar\" size=\"large\" fill=\"clear\" (click)=\"presentPictogramsActionSheet()\" *ngIf=\"hasPictograms\">\n <i class=\"fas fa-images\" id=\"icon\"></i>\n </ion-button>\n\n <ion-button class=\"button-edit-toolbar\" size=\"large\" fill=\"clear\" (click)=\"presentEditActionSheet()\">\n <i class=\"fas fa-edit\" id=\"icon\"></i>\n </ion-button>\n\n <ion-button class=\"button-edit-toolbar\" size=\"large\" [fill]=\"!isDrawing ? 'clear' : 'solid'\" (click)=\"draw()\">\n <i class=\"fas fa-pencil-alt\" id=\"icon\"></i>\n </ion-button>\n\n <ion-button class=\"button-edit-toolbar\" size=\"large\" fill=\"clear\" (click)=\"onColorClicked()\">\n <i class=\"fas fa-palette\" id=\"icon\"></i>\n </ion-button>\n\n <ion-button class=\"button-edit-toolbar\" size=\"large\" [fill]=\"!isPanning ? 'clear' : 'solid'\" (click)=\"onMoveClicked()\">\n <i class=\"fas fa-arrows-alt\" id=\"icon\"></i>\n </ion-button>\n\n <ion-button class=\"button-edit-toolbar\" size=\"large\" fill=\"clear\" (click)=\"undo()\" *ngIf=\"isUndoAvailable\">\n <i class=\"fas fa-undo\" id=\"icon\"></i>\n </ion-button>\n\n </div>\n </ion-toolbar>\n</ion-footer>\n",
providers: [CanvasManagerService],
styles: [".div-canvas-container{height:100%;width:100%;-o-object-fit:contain;object-fit:contain;text-align:center;margin:0 auto;padding:0 auto}.scroll-content{padding:0!important;overflow-y:hidden}.div-edit-toolbar{text-align:center}.button-edit-toolbar{padding:4%!important;margin:0!important}.action-sheet-button{font-family:FontAwesome,Arial}.color-picker{position:absolute;width:100%;height:auto;bottom:0;left:0}#icon{color:#b32017}.col{padding:10px}"]
}),
tslib_1.__metadata("design:paramtypes", [ActionSheetController,
CanvasManagerService,
TranslateService])
], MobileSketchToolComponent);
export { MobileSketchToolComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9iaWxlLXNrZXRjaC10b29sLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2xpYi1za2V0Y2gtdG9vbC8iLCJzb3VyY2VzIjpbImFwcC9saWItc2tldGNoLXRvb2wvbW9iaWxlLWNvbXBvbmVudC9tb2JpbGUtc2tldGNoLXRvb2wuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQW9DLFlBQVksRUFBRSxTQUFTLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDL0gsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDcEYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFNUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkQsbUdBQW1HO0FBRW5HLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQztBQUN4QixNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUM7QUFRbEMsSUFBYSx5QkFBeUIsR0FBdEMsTUFBYSx5QkFBeUI7SUF3QnBDLFlBQ1MsZUFBc0MsRUFDckMsb0JBQTBDLEVBQzFDLFNBQTJCO1FBRjVCLG9CQUFlLEdBQWYsZUFBZSxDQUF1QjtRQUNyQyx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBQzFDLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBVnBCLFdBQU0sR0FBRyxJQUFJLFlBQVksRUFBaUIsQ0FBQztRQVkxRCxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQztRQUM3QixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLENBQUMsUUFB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QUFFLHdCQUF3QjtRQUNsQywrcUxBQWtEO1FBRWxELFNBQVMsRUFBRSxDQUFDLG9CQUFvQixDQUFDOztLQUNsQyxDQUFDOzZDQTBCMEIscUJBQXFCO1FBQ2Ysb0JBQW9CO1FBQy9CLGdCQUFnQjtHQTNCMUIseUJBQXlCLENBMGJyQztTQTFiWSx5QkFBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBFdmVudEVtaXR0ZXIsIFZpZXdDaGlsZCwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZSB9IGZyb20gJy4vLi4vY29uc3RhbnRzL2F2YWlsYWJsZS1nZW9tZXRyaWMtc2hhcGVzJztcbmltcG9ydCB7IENhbnZhc01hbmFnZXJTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9jYW52YXMtbWFuYWdlci5zZXJ2aWNlJztcbmltcG9ydCB7IGZhYnJpYyB9IGZyb20gJ2ZhYnJpYyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBBY3Rpb25TaGVldENvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG4vL2ltcG9ydCB7IEdlc3R1cmVDb250cm9sbGVyIH0gZnJvbSDigJhAaW9uaWMvY29yZS9kaXN0L2NvbGxlY3Rpb24vdXRpbHMvZ2VzdHVyZS9nZXN0dXJlLWNvbnRyb2xsZXLigJk7XG5cbmNvbnN0IEJsYWNrID0gJyMwMDAwMDAnO1xuY29uc3QgVHJhbnNwYXJlbnQgPSAndHJhbnNwYXJlbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItbW9iaWxlLXNrZXRjaC10b29sJyxcbiAgdGVtcGxhdGVVcmw6ICcuL21vYmlsZS1za2V0Y2gtdG9vbC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL21vYmlsZS1za2V0Y2gtdG9vbC5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtDYW52YXNNYW5hZ2VyU2VydmljZV1cbn0pXG5leHBvcnQgY2xhc3MgTW9iaWxlU2tldGNoVG9vbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAvLyBwcml2YXRlIGdlc3R1cmU6IEdlc3R1cmVDb250cm9sbGVyO1xuICBAVmlld0NoaWxkKCdwaW5jaEVsZW1lbnQnKSBlbGVtZW50O1xuXG4gIHB1YmxpYyBmaWxsQ29sb3I6IHN0cmluZztcbiAgcHVibGljIHN0cm9rZUNvbG9yOiBzdHJpbmc7XG4gIHB1YmxpYyBpc0Nyb3BwaW5nOiBib29sZWFuO1xuICBwdWJsaWMgaXNVbmRvQXZhaWxhYmxlOiBib29sZWFuO1xuICBwdWJsaWMgaXNTZWxlY3RpbmdDb2xvcjogYm9vbGVhbjtcbiAgcHVibGljIGlzRHJhd2luZzogYm9vbGVhbjtcbiAgcHVibGljIGlzUGFubmluZzogYm9vbGVhbjtcblxuICBASW5wdXQoKSBwdWJsaWMgaW1hZ2VEYXRhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBsb2FkZWRKc29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBwaWN0b2dyYW1zUGF0aDogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgcGljdG9ncmFtczogW3N0cmluZ107XG5cbiAgQE91dHB1dCgpIHB1YmxpYyBjYW52YXMgPSBuZXcgRXZlbnRFbWl0dGVyPGZhYnJpYy5DYW52YXM+KCk7XG5cbiAgcHJpdmF0ZSBpc0xvYWRlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBwcmV2aW91c0ltYWdlRGF0YTogc3RyaW5nO1xuICBwcml2YXRlIGN1cnJlbnRKc29uOiBKU09OO1xuICBwcml2YXRlIHByZXZpb3VzSnNvbjogSlNPTjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYWN0aW9uU2hlZXRDdHJsOiBBY3Rpb25TaGVldENvbnRyb2xsZXIsXG4gICAgcHJpdmF0ZSBjYW52YXNNYW5hZ2VyU2VydmljZTogQ2FudmFzTWFuYWdlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5zdHJva2VDb2xvciA9IEJsYWNrO1xuICAgIHRoaXMuZmlsbENvbG9yID0gVHJhbnNwYXJlbnQ7XG4gICAgdGhpcy5pc0Nyb3BwaW5nID0gZmFsc2U7XG4gICAgdGhpcy5pc1Bhbm5pbmcgPSBmYWxzZTtcbiAgICB0aGlzLmlzTG9hZGVkID0gZmFsc2U7XG4gICAgdGhpcy5pc1VuZG9BdmFpbGFibGUgPSBmYWxzZTtcbiAgICB0aGlzLmlzU2VsZWN0aW5nQ29sb3IgPSBmYWxzZTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICh0aGlzLmltYWdlRGF0YSkge1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5lbXB0eUNhbnZhcygpO1xuICAgICAgaWYgKHRoaXMubG9hZGVkSnNvbiA9PSBudWxsIHx8IHRoaXMubG9hZGVkSnNvbi5sZW5ndGggPCAxMCkge1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldEJhY2tncm91bmRGcm9tVVJMKHRoaXMuaW1hZ2VEYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucHJldmlvdXNKc29uID0gSlNPTi5wYXJzZSh0aGlzLmxvYWRlZEpzb24pO1xuICAgICAgICB0aGlzLmN1cnJlbnRKc29uID0gdGhpcy5wcmV2aW91c0pzb247XG4gICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2VcbiAgICAgICAgICAubG9hZGZyb21Kc29uKEpTT04ucGFyc2UodGhpcy5sb2FkZWRKc29uKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMucHJldmlvdXNJbWFnZURhdGEgPSB0aGlzLmltYWdlRGF0YTtcbiAgICB9XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICBpZiAodGhpcy5pc0xvYWRlZCkge1xuICAgICAgaWYgKHRoaXMubG9hZGVkSnNvbiA9PT0gbnVsbCB8fCB0aGlzLmxvYWRlZEpzb24ubGVuZ3RoIDwgMTAgfHwgdGhpcy5pbWFnZURhdGEgIT09IHRoaXMucHJldmlvdXNJbWFnZURhdGEpIHtcbiAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5lbXB0eUNhbnZhcygpO1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldEJhY2tncm91bmRGcm9tVVJMKHRoaXMuaW1hZ2VEYXRhKTtcbiAgICAgICAgdGhpcy5wcmV2aW91c0ltYWdlRGF0YSA9IHRoaXMuaW1hZ2VEYXRhO1xuICAgICAgICB0aGlzLmN1cnJlbnRKc29uID0gbnVsbDtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5sb2FkZWRKc29uICE9PSBKU09OLnN0cmluZ2lmeSh0aGlzLmN1cnJlbnRKc29uKSkge1xuICAgICAgICAgIHRoaXMucHJldmlvdXNKc29uID0gSlNPTi5wYXJzZSh0aGlzLmxvYWRlZEpzb24pO1xuICAgICAgICAgIHRoaXMuY3VycmVudEpzb24gPSB0aGlzLnByZXZpb3VzSnNvbjtcbiAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlXG4gICAgICAgICAgICAubG9hZGZyb21Kc29uKEpTT04ucGFyc2UodGhpcy5sb2FkZWRKc29uKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIC8qdGhpcy5nZXN0dXJlID0gbmV3IEdlc3R1cmUodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xuICAgIHRoaXMuZ2VzdHVyZS5saXN0ZW4oKTtcbiAgICB0aGlzLmdlc3R1cmUub24oJ3BpbmNoJywgJGV2ZW50ID0+IHRoaXMucGluY2goJGV2ZW50KSk7Ki9cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIC8vdGhpcy5nZXN0dXJlLmRlc3Ryb3koKTtcbiAgfVxuXG4gIGdldCBoYXNQaWN0b2dyYW1zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhKCF0aGlzLnBpY3RvZ3JhbXMpO1xuICB9XG5cbiAgcHVibGljIGFkZFRleHQoKSB7XG4gICAgdGhpcy5kaXNhYmxlQWxsU3RhdGVzKCk7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hZGRUZXh0KHRoaXMuc3Ryb2tlQ29sb3IsICd0ZXh0ICcpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGFkZFNoYXBlKHNoYXBlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmRpc2FibGVBbGxTdGF0ZXMoKTtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZEdlb21ldHJpY1NoYXBlKFxuICAgICAgdGhpcy5zdHJva2VDb2xvcixcbiAgICAgIHRoaXMuZmlsbENvbG9yLFxuICAgICAgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGVbc2hhcGVdXG4gICAgKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRJbWFnZShzb3VyY2U6IHN0cmluZykge1xuICAgIHRoaXMuZGlzYWJsZUFsbFN0YXRlcygpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkSW1hZ2UodGhpcy5waWN0b2dyYW1zUGF0aCArIHNvdXJjZSk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgY2hhbmdlU3Ryb2tlQ29sb3IoKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5jaGFuZ2VTZWxlY3RlZE9iamVjdHNTdHJva2VDb2xvcihcbiAgICAgIHRoaXMuc3Ryb2tlQ29sb3JcbiAgICApO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc2V0RnJlZURyYXdpbmdCcnVzaENvbG9yKHRoaXMuc3Ryb2tlQ29sb3IpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGJyaW5nRm93YXJkKCkge1xuICAgIHRoaXMuZGlzYWJsZUFsbFN0YXRlcygpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYnJpbmdTZWxlY3RlZE9iamVjdHNUb0Zyb250KCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgc2VuZFRvQmFjaygpIHtcbiAgICB0aGlzLmRpc2FibGVBbGxTdGF0ZXMoKTtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNlbmRTZWxlY3RlZE9iamVjdHNUb0JhY2soKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBjcm9wKCkge1xuICAgIGlmICh0aGlzLmlzQ3JvcHBpbmcpIHtcbiAgICAgIHRoaXMuZGlzYWJsZUNyb3BwcGluZygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRpc2FibGVBbGxTdGF0ZXMoKTtcbiAgICAgIHRoaXMuaXNDcm9wcGluZyA9IHRydWU7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnJlc2V0Wm9vbSgpO1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5kaXNhYmxlU2VsZWN0aW9uKCk7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZFNlbGVjdGlvblJlY3RhbmdsZSgpO1xuICAgICAgdGhpcy5pc1VuZG9BdmFpbGFibGUgPSB0cnVlO1xuICAgICAgdGhpcy5wcmV2aW91c0pzb24gPSB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmpzb25Gcm9tQ2FudmFzKCk7XG4gICAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRpc2FibGVDcm9wcHBpbmcoKSB7XG4gICAgdGhpcy5pc0Nyb3BwaW5nID0gZmFsc2U7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5lbmFibGVTbGVjdGlvbigpO1xuICAgIHRoaXMuaXNVbmRvQXZhaWxhYmxlID0gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlU2VsZWN0aW9uKCkge1xuICAgIHRoaXMuZGlzYWJsZUFsbFN0YXRlcygpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZGVsZXRlU2VsZWN0ZWRPYmplY3RzKCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgbW91c2VVcCgpIHtcbiAgICBpZiAodGhpcy5pc0Nyb3BwaW5nKSB7XG4gICAgICB0aGlzLmlzQ3JvcHBpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuY3JvcEltYWdlKCk7XG4gICAgICB0aGlzLmlzVW5kb0F2YWlsYWJsZSA9IHRydWU7XG4gICAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuaXNDcm9wcGluZykge1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hanVzdENyb3BSZWN0YW5nbGUoZXZlbnQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc1Bhbm5pbmcpIHtcbiAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5wYW5DYW52YXMoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBtb3VzZURvd24oZXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc0Nyb3BwaW5nKSB7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnN0YXJ0U2VsZWN0aW5nQ3JvcFJlY3RhbmdsZShldmVudCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzUGFubmluZykge1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldExhc3RQYW5Qb3NpdGlvbihldmVudCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHBpbmNoKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmRpc2FibGVEcmF3aW5nKCk7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS56b29tKGV2ZW50KTtcbiAgfVxuXG4gIHB1YmxpYyBncm91cCgpIHtcbiAgICB0aGlzLmRpc2FibGVBbGxTdGF0ZXMoKTtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmdyb3VwU2VsZWN0ZWRPYmplY3RzKCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgdW5kbygpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmxvYWRmcm9tSnNvbih0aGlzLnByZXZpb3VzSnNvbik7XG4gICAgdGhpcy5pc1VuZG9BdmFpbGFibGUgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNvbG9yQ2xpY2tlZCgpIHtcbiAgICB0aGlzLmlzU2VsZWN0aW5nQ29sb3IgPSB0cnVlO1xuICAgIHRoaXMuc3RvcFBhbm5pbmcoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbk1vdmVDbGlja2VkKCkge1xuICAgIHRoaXMuaXNQYW5uaW5nID0gIXRoaXMuaXNQYW5uaW5nO1xuICAgIHRoaXMuZGlzYWJsZURyYXdpbmcoKTtcbiAgICBpZiAodGhpcy5pc1Bhbm5pbmcpIHtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZGlzYWJsZVNlbGVjdGlvbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmVuYWJsZVNsZWN0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkaXNhYmxlUGFubmluZygpIHtcbiAgICB0aGlzLmlzUGFubmluZyA9IGZhbHNlO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZW5hYmxlU2xlY3Rpb24oKTtcbiAgfVxuXG4gIHByaXZhdGUgZGlzYWJsZUFsbFN0YXRlcygpIHtcbiAgICB0aGlzLmRpc2FibGVEcmF3aW5nKCk7XG4gICAgdGhpcy5kaXNhYmxlUGFubmluZygpO1xuICB9XG5cbiAgcHVibGljIHN0b3BQYW5uaW5nKCkge1xuICAgIGlmICh0aGlzLmlzUGFubmluZykge1xuICAgICAgdGhpcy5pc1Bhbm5pbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZW5hYmxlU2xlY3Rpb24oKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0Q29sb3IoY29sb3I6IHN0cmluZykge1xuICAgIHRoaXMuc3Ryb2tlQ29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLmNoYW5nZVN0cm9rZUNvbG9yKCk7XG4gICAgdGhpcy5pc1NlbGVjdGluZ0NvbG9yID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgZHJhdygpIHtcbiAgICB0aGlzLmlzRHJhd2luZyA9ICF0aGlzLmlzRHJhd2luZztcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnRvZ2dsZUZyZWVEcmF3aW5nKCk7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5zZXRGcmVlRHJhd2luZ0JydXNoQ29sb3IodGhpcy5zdHJva2VDb2xvcik7XG5cbiAgICBpZiAodGhpcy5pc0RyYXdpbmcpIHtcbiAgICAgIHRoaXMuaXNQYW5uaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkaXNhYmxlRHJhd2luZygpIHtcbiAgICBpZiAodGhpcy5pc0RyYXdpbmcpIHtcbiAgICAgIHRoaXMuaXNEcmF3aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnRvZ2dsZUZyZWVEcmF3aW5nKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2xhdGVTaGFwZUJ1dHRvbnNUZXh0KCk6IEFycmF5PFN0cmluZz4ge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uQXJyYXkgPSBbXTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgncmVjdGFuZ2xlJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCd0cmlhbmdsZScpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnY2lyY2xlJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdsaW5lJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjcm9zcycpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgndGV4dCcpKTtcbiAgICByZXR1cm4gdHJhbnNsYXRpb25BcnJheTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwcmVzZW50U2hhcGVBY3Rpb25TaGVldCgpIHtcbiAgICB0aGlzLmRpc2FibGVEcmF3aW5nKCk7XG5cbiAgICBjb25zdCB0aXRsZVRleHQgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdhZGRHZW9tZXRyaWNTaGFwZScpO1xuICAgIGNvbnN0IGJ1dHRvbnNUZXh0ID0gdGhpcy50cmFuc2xhdGVTaGFwZUJ1dHRvbnNUZXh0KCk7XG4gICAgbGV0IGkgPSAwO1xuXG4gICAgY29uc3QgYWN0aW9uU2hlZXQgPSBhd2FpdCB0aGlzLmFjdGlvblNoZWV0Q3RybC5jcmVhdGUoe1xuICAgICAgaGVhZGVyOiB0aXRsZVRleHQsXG4gICAgICBidXR0b25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjBjOCAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkR2VvbWV0cmljU2hhcGUoXG4gICAgICAgICAgICAgIHRoaXMuc3Ryb2tlQ29sb3IsXG4gICAgICAgICAgICAgIHRoaXMuZmlsbENvbG9yLFxuICAgICAgICAgICAgICBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5SZWN0YW5nbGVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ1xcdWYwZDggICAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZEdlb21ldHJpY1NoYXBlKFxuICAgICAgICAgICAgICB0aGlzLnN0cm9rZUNvbG9yLFxuICAgICAgICAgICAgICB0aGlzLm