cps-ui-kit 0.154.0 → 0.156.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/esm2020/lib/components/cps-file-upload/cps-file-upload.component.mjs +138 -0
- package/esm2020/lib/components/cps-table/cps-table.component.mjs +73 -36
- package/esm2020/lib/components/cps-table/directives/internal/table-unsort.directive.mjs +148 -23
- package/esm2020/lib/components/cps-tree-table/cps-tree-table.component.mjs +39 -82
- package/esm2020/lib/components/cps-tree-table/directives/internal/tree-table-unsort.directive.mjs +188 -11
- package/esm2020/lib/services/cps-notification/internal/components/cps-toast/cps-toast.component.mjs +3 -3
- package/esm2020/public-api.mjs +2 -1
- package/fesm2015/cps-ui-kit.mjs +581 -153
- package/fesm2015/cps-ui-kit.mjs.map +1 -1
- package/fesm2020/cps-ui-kit.mjs +577 -152
- package/fesm2020/cps-ui-kit.mjs.map +1 -1
- package/lib/components/cps-file-upload/cps-file-upload.component.d.ts +58 -0
- package/lib/components/cps-table/cps-table.component.d.ts +37 -16
- package/lib/components/cps-table/directives/internal/table-unsort.directive.d.ts +6 -2
- package/lib/components/cps-tree-table/cps-tree-table.component.d.ts +13 -12
- package/lib/components/cps-tree-table/directives/internal/tree-table-unsort.directive.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
package/README.md
CHANGED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { convertSize } from '../../utils/internal/size-utils';
|
|
4
|
+
import { CpsIconComponent } from '../cps-icon/cps-icon.component';
|
|
5
|
+
import { CpsProgressLinearComponent } from '../cps-progress-linear/cps-progress-linear.component';
|
|
6
|
+
import { catchError, of, take } from 'rxjs';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/common";
|
|
9
|
+
/**
|
|
10
|
+
* CpsFileUploadComponent is an advanced uploader with dragdrop support.
|
|
11
|
+
* @group Components
|
|
12
|
+
*/
|
|
13
|
+
export class CpsFileUploadComponent {
|
|
14
|
+
constructor() {
|
|
15
|
+
/**
|
|
16
|
+
* Expected extensions of a file to be uploaded. E.g. 'doc or .doc'.
|
|
17
|
+
* @group Props
|
|
18
|
+
*/
|
|
19
|
+
this.extensions = [];
|
|
20
|
+
/**
|
|
21
|
+
* Expected file description. E.g. 'Word document'.
|
|
22
|
+
* @group Props
|
|
23
|
+
*/
|
|
24
|
+
this.fileDesc = 'Any file';
|
|
25
|
+
/**
|
|
26
|
+
* Width of the component, a number denoting pixels or a string.
|
|
27
|
+
* @group Props
|
|
28
|
+
*/
|
|
29
|
+
this.width = '100%';
|
|
30
|
+
/**
|
|
31
|
+
* Callback for uploaded file processing.
|
|
32
|
+
* @group Props
|
|
33
|
+
*/
|
|
34
|
+
this.fileProcessingCallback = undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Callback to invoke when file is uploaded.
|
|
37
|
+
* @param {File} File
|
|
38
|
+
* @group Emits
|
|
39
|
+
*/
|
|
40
|
+
this.fileUploaded = new EventEmitter();
|
|
41
|
+
/**
|
|
42
|
+
* Callback to invoke when file upload fails.
|
|
43
|
+
* @param {string} - file name
|
|
44
|
+
* @group Emits
|
|
45
|
+
*/
|
|
46
|
+
this.fileUploadFailed = new EventEmitter();
|
|
47
|
+
/**
|
|
48
|
+
* Callback to invoke when uploaded file is removed.
|
|
49
|
+
* @param {string} - file name
|
|
50
|
+
* @group Emits
|
|
51
|
+
*/
|
|
52
|
+
this.uploadedFileRemoved = new EventEmitter();
|
|
53
|
+
this.isDragoverFile = false;
|
|
54
|
+
this.extensionsString = '';
|
|
55
|
+
this.extensionsStringAsterisks = '';
|
|
56
|
+
this.isProcessingFile = false;
|
|
57
|
+
}
|
|
58
|
+
ngOnInit() {
|
|
59
|
+
this.width = convertSize(this.width);
|
|
60
|
+
this.extensions = this.extensions.map((ext) => ext.startsWith('.') ? ext : '.' + ext);
|
|
61
|
+
this.extensionsString = this.extensions.join(', ');
|
|
62
|
+
this.extensionsStringAsterisks = this.extensions
|
|
63
|
+
.map((ext) => '*' + ext)
|
|
64
|
+
.join(', ');
|
|
65
|
+
}
|
|
66
|
+
tryUploadFile(event) {
|
|
67
|
+
event.preventDefault();
|
|
68
|
+
event.stopPropagation();
|
|
69
|
+
this.isDragoverFile = false;
|
|
70
|
+
let file;
|
|
71
|
+
if (event.type === 'drop') {
|
|
72
|
+
file = event.dataTransfer?.files.item(0) ?? undefined;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const files = event.target.files;
|
|
76
|
+
if (!files || files.length < 1)
|
|
77
|
+
return;
|
|
78
|
+
file = files.item(0) ?? undefined;
|
|
79
|
+
}
|
|
80
|
+
if (!this._isFileExtensionValid(file)) {
|
|
81
|
+
this.fileUploadFailed.emit(file?.name ?? '');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.uploadedFile = file;
|
|
85
|
+
if (this.uploadedFile) {
|
|
86
|
+
this.fileUploaded.emit(this.uploadedFile);
|
|
87
|
+
if (this.fileProcessingCallback) {
|
|
88
|
+
this.isProcessingFile = true;
|
|
89
|
+
this.fileProcessingCallback(this.uploadedFile)
|
|
90
|
+
.pipe(take(1), catchError(() => {
|
|
91
|
+
return of(false);
|
|
92
|
+
}))
|
|
93
|
+
.subscribe((res) => {
|
|
94
|
+
if (!res)
|
|
95
|
+
this.removeUploadedFile();
|
|
96
|
+
this.isProcessingFile = false;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
removeUploadedFile() {
|
|
102
|
+
const name = this.uploadedFile?.name ?? '';
|
|
103
|
+
this.uploadedFile = undefined;
|
|
104
|
+
this.uploadedFileRemoved.emit(name);
|
|
105
|
+
}
|
|
106
|
+
_isFileExtensionValid(file) {
|
|
107
|
+
if (!file)
|
|
108
|
+
return false;
|
|
109
|
+
if (this.extensions.length < 1)
|
|
110
|
+
return true;
|
|
111
|
+
for (const ext of this.extensions) {
|
|
112
|
+
if (file.name.endsWith(ext))
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
CpsFileUploadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CpsFileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
119
|
+
CpsFileUploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: CpsFileUploadComponent, isStandalone: true, selector: "cps-file-upload", inputs: { extensions: "extensions", fileDesc: "fileDesc", width: "width", fileProcessingCallback: "fileProcessingCallback" }, outputs: { fileUploaded: "fileUploaded", fileUploadFailed: "fileUploadFailed", uploadedFileRemoved: "uploadedFileRemoved" }, ngImport: i0, template: "<div class=\"cps-file-upload\" [ngStyle]=\"{ width: width }\">\n <div\n class=\"cps-file-upload-dropzone\"\n [ngClass]=\"{\n 'dragged-over': isDragoverFile,\n 'with-uploads': uploadedFile?.name\n }\"\n (dragend)=\"isDragoverFile = false\"\n (dragenter)=\"isDragoverFile = true\"\n (dragleave)=\"isDragoverFile = false\"\n (dragover)=\"isDragoverFile = true\"\n (mouseleave)=\"isDragoverFile = false\"\n (drop)=\"tryUploadFile($event)\">\n <input\n (change)=\"tryUploadFile($event)\"\n type=\"file\"\n [accept]=\"extensionsString\"\n title=\"\" />\n <cps-icon icon=\"export\" size=\"large\" color=\"text-darkest\"></cps-icon>\n <div class=\"cps-file-upload-dropzone-title\">\n Drag&Drop or choose a file to upload\n </div>\n <span\n class=\"cps-file-upload-dropzone-file-desc\"\n *ngIf=\"fileDesc || extensionsStringAsterisks\"\n >{{ fileDesc }}\n {{\n extensionsStringAsterisks ? '(' + extensionsStringAsterisks + ')' : ''\n }}</span\n >\n <cps-progress-linear\n *ngIf=\"isProcessingFile && uploadedFile\"\n height=\"3\"\n radius=\"4\"\n opacity=\"0.3\"\n class=\"cps-file-upload-progress-bar\"\n bgColor=\"transparent\">\n </cps-progress-linear>\n </div>\n <div *ngIf=\"uploadedFile\" class=\"cps-file-upload-uploaded-files\">\n <div class=\"cps-file-upload-uploaded-file\">\n <div class=\"cps-file-upload-uploaded-file-title\">\n <cps-icon\n class=\"cps-file-upload-uploaded-file-status-icon\"\n [icon]=\"isProcessingFile ? 'pending' : 'toast-success'\"\n [color]=\"isProcessingFile ? 'warn' : 'success'\">\n </cps-icon>\n <div class=\"cps-file-upload-uploaded-file-name\">\n {{ uploadedFile.name }}\n </div>\n </div>\n <cps-icon\n *ngIf=\"!isProcessingFile\"\n class=\"cps-file-upload-uploaded-file-remove-icon\"\n icon=\"remove\"\n color=\"error\"\n (click)=\"removeUploadedFile()\">\n </cps-icon>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex}:host .cps-file-upload .cps-file-upload-dropzone{font-family:Source Sans Pro,sans-serif;min-height:20px;padding:2rem;text-align:center;border:2px dashed var(--cps-color-calm);position:relative;border-radius:1rem}:host .cps-file-upload .cps-file-upload-dropzone:hover{background-color:var(--cps-color-highlight-hover)}:host .cps-file-upload .cps-file-upload-dropzone:active{background-color:var(--cps-color-highlight-selected)}:host .cps-file-upload .cps-file-upload-dropzone.dragged-over{background-color:var(--cps-color-highlight-selected)}:host .cps-file-upload .cps-file-upload-dropzone.with-uploads{border-bottom-right-radius:0;border-bottom-left-radius:0;border-bottom:1px dashed var(--cps-color-calm)}:host .cps-file-upload .cps-file-upload-dropzone input{cursor:pointer;opacity:0;position:absolute;width:100%;height:100%;top:0;left:0}:host .cps-file-upload .cps-file-upload-dropzone .cps-file-upload-dropzone-title{font-size:16px;margin:8px 0;color:var(--cps-color-calm);font-weight:600}:host .cps-file-upload .cps-file-upload-dropzone .cps-file-upload-dropzone-file-desc{font-size:18px;color:var(--cps-color-text-dark)}:host .cps-file-upload .cps-file-upload-dropzone .cps-file-upload-progress-bar{position:absolute;bottom:-2px;left:0}:host .cps-file-upload .cps-file-upload-uploaded-files{border-bottom:2px dashed var(--cps-color-calm);border-left:2px dashed var(--cps-color-calm);border-right:2px dashed var(--cps-color-calm);border-bottom-right-radius:16px;border-bottom-left-radius:16px;background-color:var(--cps-color-highlight-hover)}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file{cursor:default;display:flex;align-items:center;justify-content:space-between;padding:8px 12px}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-title{display:flex;align-items:center}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-title .cps-file-upload-uploaded-file-name{color:var(--cps-color-text-darkest);font-size:20px;margin:0 8px}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-remove-icon{cursor:pointer}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-remove-icon:hover ::ng-deep .cps-icon{color:var(--cps-color-error-darken1)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: CpsIconComponent, selector: "cps-icon", inputs: ["icon", "size", "color"] }, { kind: "component", type: CpsProgressLinearComponent, selector: "cps-progress-linear", inputs: ["width", "height", "color", "bgColor", "opacity", "radius"] }] });
|
|
120
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CpsFileUploadComponent, decorators: [{
|
|
121
|
+
type: Component,
|
|
122
|
+
args: [{ selector: 'cps-file-upload', standalone: true, imports: [CommonModule, CpsIconComponent, CpsProgressLinearComponent], template: "<div class=\"cps-file-upload\" [ngStyle]=\"{ width: width }\">\n <div\n class=\"cps-file-upload-dropzone\"\n [ngClass]=\"{\n 'dragged-over': isDragoverFile,\n 'with-uploads': uploadedFile?.name\n }\"\n (dragend)=\"isDragoverFile = false\"\n (dragenter)=\"isDragoverFile = true\"\n (dragleave)=\"isDragoverFile = false\"\n (dragover)=\"isDragoverFile = true\"\n (mouseleave)=\"isDragoverFile = false\"\n (drop)=\"tryUploadFile($event)\">\n <input\n (change)=\"tryUploadFile($event)\"\n type=\"file\"\n [accept]=\"extensionsString\"\n title=\"\" />\n <cps-icon icon=\"export\" size=\"large\" color=\"text-darkest\"></cps-icon>\n <div class=\"cps-file-upload-dropzone-title\">\n Drag&Drop or choose a file to upload\n </div>\n <span\n class=\"cps-file-upload-dropzone-file-desc\"\n *ngIf=\"fileDesc || extensionsStringAsterisks\"\n >{{ fileDesc }}\n {{\n extensionsStringAsterisks ? '(' + extensionsStringAsterisks + ')' : ''\n }}</span\n >\n <cps-progress-linear\n *ngIf=\"isProcessingFile && uploadedFile\"\n height=\"3\"\n radius=\"4\"\n opacity=\"0.3\"\n class=\"cps-file-upload-progress-bar\"\n bgColor=\"transparent\">\n </cps-progress-linear>\n </div>\n <div *ngIf=\"uploadedFile\" class=\"cps-file-upload-uploaded-files\">\n <div class=\"cps-file-upload-uploaded-file\">\n <div class=\"cps-file-upload-uploaded-file-title\">\n <cps-icon\n class=\"cps-file-upload-uploaded-file-status-icon\"\n [icon]=\"isProcessingFile ? 'pending' : 'toast-success'\"\n [color]=\"isProcessingFile ? 'warn' : 'success'\">\n </cps-icon>\n <div class=\"cps-file-upload-uploaded-file-name\">\n {{ uploadedFile.name }}\n </div>\n </div>\n <cps-icon\n *ngIf=\"!isProcessingFile\"\n class=\"cps-file-upload-uploaded-file-remove-icon\"\n icon=\"remove\"\n color=\"error\"\n (click)=\"removeUploadedFile()\">\n </cps-icon>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex}:host .cps-file-upload .cps-file-upload-dropzone{font-family:Source Sans Pro,sans-serif;min-height:20px;padding:2rem;text-align:center;border:2px dashed var(--cps-color-calm);position:relative;border-radius:1rem}:host .cps-file-upload .cps-file-upload-dropzone:hover{background-color:var(--cps-color-highlight-hover)}:host .cps-file-upload .cps-file-upload-dropzone:active{background-color:var(--cps-color-highlight-selected)}:host .cps-file-upload .cps-file-upload-dropzone.dragged-over{background-color:var(--cps-color-highlight-selected)}:host .cps-file-upload .cps-file-upload-dropzone.with-uploads{border-bottom-right-radius:0;border-bottom-left-radius:0;border-bottom:1px dashed var(--cps-color-calm)}:host .cps-file-upload .cps-file-upload-dropzone input{cursor:pointer;opacity:0;position:absolute;width:100%;height:100%;top:0;left:0}:host .cps-file-upload .cps-file-upload-dropzone .cps-file-upload-dropzone-title{font-size:16px;margin:8px 0;color:var(--cps-color-calm);font-weight:600}:host .cps-file-upload .cps-file-upload-dropzone .cps-file-upload-dropzone-file-desc{font-size:18px;color:var(--cps-color-text-dark)}:host .cps-file-upload .cps-file-upload-dropzone .cps-file-upload-progress-bar{position:absolute;bottom:-2px;left:0}:host .cps-file-upload .cps-file-upload-uploaded-files{border-bottom:2px dashed var(--cps-color-calm);border-left:2px dashed var(--cps-color-calm);border-right:2px dashed var(--cps-color-calm);border-bottom-right-radius:16px;border-bottom-left-radius:16px;background-color:var(--cps-color-highlight-hover)}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file{cursor:default;display:flex;align-items:center;justify-content:space-between;padding:8px 12px}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-title{display:flex;align-items:center}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-title .cps-file-upload-uploaded-file-name{color:var(--cps-color-text-darkest);font-size:20px;margin:0 8px}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-remove-icon{cursor:pointer}:host .cps-file-upload .cps-file-upload-uploaded-files .cps-file-upload-uploaded-file .cps-file-upload-uploaded-file-remove-icon:hover ::ng-deep .cps-icon{color:var(--cps-color-error-darken1)!important}\n"] }]
|
|
123
|
+
}], propDecorators: { extensions: [{
|
|
124
|
+
type: Input
|
|
125
|
+
}], fileDesc: [{
|
|
126
|
+
type: Input
|
|
127
|
+
}], width: [{
|
|
128
|
+
type: Input
|
|
129
|
+
}], fileProcessingCallback: [{
|
|
130
|
+
type: Input
|
|
131
|
+
}], fileUploaded: [{
|
|
132
|
+
type: Output
|
|
133
|
+
}], fileUploadFailed: [{
|
|
134
|
+
type: Output
|
|
135
|
+
}], uploadedFileRemoved: [{
|
|
136
|
+
type: Output
|
|
137
|
+
}] } });
|
|
138
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3BzLWZpbGUtdXBsb2FkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nwcy11aS1raXQvc3JjL2xpYi9jb21wb25lbnRzL2Nwcy1maWxlLXVwbG9hZC9jcHMtZmlsZS11cGxvYWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY3BzLXVpLWtpdC9zcmMvbGliL2NvbXBvbmVudHMvY3BzLWZpbGUtdXBsb2FkL2Nwcy1maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbEUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFDbEcsT0FBTyxFQUFjLFVBQVUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7QUFFeEQ7OztHQUdHO0FBUUgsTUFBTSxPQUFPLHNCQUFzQjtJQVBuQztRQVFFOzs7V0FHRztRQUNNLGVBQVUsR0FBYSxFQUFFLENBQUM7UUFFbkM7OztXQUdHO1FBQ00sYUFBUSxHQUFHLFVBQVUsQ0FBQztRQUUvQjs7O1dBR0c7UUFDTSxVQUFLLEdBQW9CLE1BQU0sQ0FBQztRQUV6Qzs7O1dBR0c7UUFDTSwyQkFBc0IsR0FDN0IsU0FBUyxDQUFDO1FBRVo7Ozs7V0FJRztRQUNPLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUVsRDs7OztXQUlHO1FBQ08scUJBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUV4RDs7OztXQUlHO1FBQ08sd0JBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUUzRCxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUV2QixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdEIsOEJBQXlCLEdBQUcsRUFBRSxDQUFDO1FBRS9CLHFCQUFnQixHQUFHLEtBQUssQ0FBQztLQXNFMUI7SUFwRUMsUUFBUTtRQUNOLElBQUksQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDNUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUN0QyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMsVUFBVTthQUM3QyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7YUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hCLENBQUM7SUFFRCxhQUFhLENBQUMsS0FBWTtRQUN4QixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXhCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBQzVCLElBQUksSUFBc0IsQ0FBQztRQUUzQixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFO1lBQ3pCLElBQUksR0FBSSxLQUFtQixDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQztTQUN0RTthQUFNO1lBQ0wsTUFBTSxLQUFLLEdBQUksS0FBSyxDQUFDLE1BQTJCLENBQUMsS0FBSyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDO2dCQUFFLE9BQU87WUFDdkMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDO1NBQ25DO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNyQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7WUFDN0MsT0FBTztTQUNSO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMxQyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtnQkFDL0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztnQkFDN0IsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7cUJBQzNDLElBQUksQ0FDSCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsVUFBVSxDQUFDLEdBQUcsRUFBRTtvQkFDZCxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDbkIsQ0FBQyxDQUFDLENBQ0g7cUJBQ0EsU0FBUyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ2pCLElBQUksQ0FBQyxHQUFHO3dCQUFFLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO29CQUNwQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO2dCQUNoQyxDQUFDLENBQUMsQ0FBQzthQUNOO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUMzQyxJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztRQUM5QixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTyxxQkFBcUIsQ0FBQyxJQUFXO1FBQ3ZDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFFeEIsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFNUMsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2pDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1NBQzFDO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDOzttSEF6SFUsc0JBQXNCO3VHQUF0QixzQkFBc0Isc1VDbEJuQyw0akVBNkRBLG0rRUQvQ1ksWUFBWSxzVEFBRSxnQkFBZ0Isd0ZBQUUsMEJBQTBCOzJGQUl6RCxzQkFBc0I7a0JBUGxDLFNBQVM7K0JBQ0UsaUJBQWlCLGNBQ2YsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLGdCQUFnQixFQUFFLDBCQUEwQixDQUFDOzhCQVM1RCxVQUFVO3NCQUFsQixLQUFLO2dCQU1HLFFBQVE7c0JBQWhCLEtBQUs7Z0JBTUcsS0FBSztzQkFBYixLQUFLO2dCQU1HLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFRSSxZQUFZO3NCQUFyQixNQUFNO2dCQU9HLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFPRyxtQkFBbUI7c0JBQTVCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgY29udmVydFNpemUgfSBmcm9tICcuLi8uLi91dGlscy9pbnRlcm5hbC9zaXplLXV0aWxzJztcbmltcG9ydCB7IENwc0ljb25Db21wb25lbnQgfSBmcm9tICcuLi9jcHMtaWNvbi9jcHMtaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ3BzUHJvZ3Jlc3NMaW5lYXJDb21wb25lbnQgfSBmcm9tICcuLi9jcHMtcHJvZ3Jlc3MtbGluZWFyL2Nwcy1wcm9ncmVzcy1saW5lYXIuY29tcG9uZW50JztcbmltcG9ydCB7IE9ic2VydmFibGUsIGNhdGNoRXJyb3IsIG9mLCB0YWtlIH0gZnJvbSAncnhqcyc7XG5cbi8qKlxuICogQ3BzRmlsZVVwbG9hZENvbXBvbmVudCBpcyBhbiBhZHZhbmNlZCB1cGxvYWRlciB3aXRoIGRyYWdkcm9wIHN1cHBvcnQuXG4gKiBAZ3JvdXAgQ29tcG9uZW50c1xuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjcHMtZmlsZS11cGxvYWQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBDcHNJY29uQ29tcG9uZW50LCBDcHNQcm9ncmVzc0xpbmVhckNvbXBvbmVudF0sXG4gIHRlbXBsYXRlVXJsOiAnLi9jcHMtZmlsZS11cGxvYWQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jcHMtZmlsZS11cGxvYWQuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBDcHNGaWxlVXBsb2FkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgLyoqXG4gICAqIEV4cGVjdGVkIGV4dGVuc2lvbnMgb2YgYSBmaWxlIHRvIGJlIHVwbG9hZGVkLiBFLmcuICdkb2Mgb3IgLmRvYycuXG4gICAqIEBncm91cCBQcm9wc1xuICAgKi9cbiAgQElucHV0KCkgZXh0ZW5zaW9uczogc3RyaW5nW10gPSBbXTtcblxuICAvKipcbiAgICogRXhwZWN0ZWQgZmlsZSBkZXNjcmlwdGlvbi4gRS5nLiAnV29yZCBkb2N1bWVudCcuXG4gICAqIEBncm91cCBQcm9wc1xuICAgKi9cbiAgQElucHV0KCkgZmlsZURlc2MgPSAnQW55IGZpbGUnO1xuXG4gIC8qKlxuICAgKiBXaWR0aCBvZiB0aGUgY29tcG9uZW50LCBhIG51bWJlciBkZW5vdGluZyBwaXhlbHMgb3IgYSBzdHJpbmcuXG4gICAqIEBncm91cCBQcm9wc1xuICAgKi9cbiAgQElucHV0KCkgd2lkdGg6IG51bWJlciB8IHN0cmluZyA9ICcxMDAlJztcblxuICAvKipcbiAgICogQ2FsbGJhY2sgZm9yIHVwbG9hZGVkIGZpbGUgcHJvY2Vzc2luZy5cbiAgICogQGdyb3VwIFByb3BzXG4gICAqL1xuICBASW5wdXQoKSBmaWxlUHJvY2Vzc2luZ0NhbGxiYWNrPzogKGZpbGU6IEZpbGUpID0+IE9ic2VydmFibGU8Ym9vbGVhbj4gPVxuICAgIHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gZmlsZSBpcyB1cGxvYWRlZC5cbiAgICogQHBhcmFtIHtGaWxlfSBGaWxlXG4gICAqIEBncm91cCBFbWl0c1xuICAgKi9cbiAgQE91dHB1dCgpIGZpbGVVcGxvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZT4oKTtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gZmlsZSB1cGxvYWQgZmFpbHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSAtIGZpbGUgbmFtZVxuICAgKiBAZ3JvdXAgRW1pdHNcbiAgICovXG4gIEBPdXRwdXQoKSBmaWxlVXBsb2FkRmFpbGVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIHRvIGludm9rZSB3aGVuIHVwbG9hZGVkIGZpbGUgaXMgcmVtb3ZlZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IC0gZmlsZSBuYW1lXG4gICAqIEBncm91cCBFbWl0c1xuICAgKi9cbiAgQE91dHB1dCgpIHVwbG9hZGVkRmlsZVJlbW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICBpc0RyYWdvdmVyRmlsZSA9IGZhbHNlO1xuICB1cGxvYWRlZEZpbGU/OiBGaWxlO1xuICBleHRlbnNpb25zU3RyaW5nID0gJyc7XG4gIGV4dGVuc2lvbnNTdHJpbmdBc3Rlcmlza3MgPSAnJztcblxuICBpc1Byb2Nlc3NpbmdGaWxlID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy53aWR0aCA9IGNvbnZlcnRTaXplKHRoaXMud2lkdGgpO1xuICAgIHRoaXMuZXh0ZW5zaW9ucyA9IHRoaXMuZXh0ZW5zaW9ucy5tYXAoKGV4dCkgPT5cbiAgICAgIGV4dC5zdGFydHNXaXRoKCcuJykgPyBleHQgOiAnLicgKyBleHRcbiAgICApO1xuICAgIHRoaXMuZXh0ZW5zaW9uc1N0cmluZyA9IHRoaXMuZXh0ZW5zaW9ucy5qb2luKCcsICcpO1xuICAgIHRoaXMuZXh0ZW5zaW9uc1N0cmluZ0FzdGVyaXNrcyA9IHRoaXMuZXh0ZW5zaW9uc1xuICAgICAgLm1hcCgoZXh0KSA9PiAnKicgKyBleHQpXG4gICAgICAuam9pbignLCAnKTtcbiAgfVxuXG4gIHRyeVVwbG9hZEZpbGUoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIHRoaXMuaXNEcmFnb3ZlckZpbGUgPSBmYWxzZTtcbiAgICBsZXQgZmlsZTogRmlsZSB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChldmVudC50eXBlID09PSAnZHJvcCcpIHtcbiAgICAgIGZpbGUgPSAoZXZlbnQgYXMgRHJhZ0V2ZW50KS5kYXRhVHJhbnNmZXI/LmZpbGVzLml0ZW0oMCkgPz8gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmaWxlcyA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkuZmlsZXM7XG4gICAgICBpZiAoIWZpbGVzIHx8IGZpbGVzLmxlbmd0aCA8IDEpIHJldHVybjtcbiAgICAgIGZpbGUgPSBmaWxlcy5pdGVtKDApID8/IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX2lzRmlsZUV4dGVuc2lvblZhbGlkKGZpbGUpKSB7XG4gICAgICB0aGlzLmZpbGVVcGxvYWRGYWlsZWQuZW1pdChmaWxlPy5uYW1lID8/ICcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnVwbG9hZGVkRmlsZSA9IGZpbGU7XG4gICAgaWYgKHRoaXMudXBsb2FkZWRGaWxlKSB7XG4gICAgICB0aGlzLmZpbGVVcGxvYWRlZC5lbWl0KHRoaXMudXBsb2FkZWRGaWxlKTtcbiAgICAgIGlmICh0aGlzLmZpbGVQcm9jZXNzaW5nQ2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmdGaWxlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5maWxlUHJvY2Vzc2luZ0NhbGxiYWNrKHRoaXMudXBsb2FkZWRGaWxlKVxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gb2YoZmFsc2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICAgICAgLnN1YnNjcmliZSgocmVzKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXJlcykgdGhpcy5yZW1vdmVVcGxvYWRlZEZpbGUoKTtcbiAgICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nRmlsZSA9IGZhbHNlO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZVVwbG9hZGVkRmlsZSgpIHtcbiAgICBjb25zdCBuYW1lID0gdGhpcy51cGxvYWRlZEZpbGU/Lm5hbWUgPz8gJyc7XG4gICAgdGhpcy51cGxvYWRlZEZpbGUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy51cGxvYWRlZEZpbGVSZW1vdmVkLmVtaXQobmFtZSk7XG4gIH1cblxuICBwcml2YXRlIF9pc0ZpbGVFeHRlbnNpb25WYWxpZChmaWxlPzogRmlsZSkge1xuICAgIGlmICghZmlsZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHRoaXMuZXh0ZW5zaW9ucy5sZW5ndGggPCAxKSByZXR1cm4gdHJ1ZTtcblxuICAgIGZvciAoY29uc3QgZXh0IG9mIHRoaXMuZXh0ZW5zaW9ucykge1xuICAgICAgaWYgKGZpbGUubmFtZS5lbmRzV2l0aChleHQpKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjcHMtZmlsZS11cGxvYWRcIiBbbmdTdHlsZV09XCJ7IHdpZHRoOiB3aWR0aCB9XCI+XG4gIDxkaXZcbiAgICBjbGFzcz1cImNwcy1maWxlLXVwbG9hZC1kcm9wem9uZVwiXG4gICAgW25nQ2xhc3NdPVwie1xuICAgICAgJ2RyYWdnZWQtb3Zlcic6IGlzRHJhZ292ZXJGaWxlLFxuICAgICAgJ3dpdGgtdXBsb2Fkcyc6IHVwbG9hZGVkRmlsZT8ubmFtZVxuICAgIH1cIlxuICAgIChkcmFnZW5kKT1cImlzRHJhZ292ZXJGaWxlID0gZmFsc2VcIlxuICAgIChkcmFnZW50ZXIpPVwiaXNEcmFnb3ZlckZpbGUgPSB0cnVlXCJcbiAgICAoZHJhZ2xlYXZlKT1cImlzRHJhZ292ZXJGaWxlID0gZmFsc2VcIlxuICAgIChkcmFnb3Zlcik9XCJpc0RyYWdvdmVyRmlsZSA9IHRydWVcIlxuICAgIChtb3VzZWxlYXZlKT1cImlzRHJhZ292ZXJGaWxlID0gZmFsc2VcIlxuICAgIChkcm9wKT1cInRyeVVwbG9hZEZpbGUoJGV2ZW50KVwiPlxuICAgIDxpbnB1dFxuICAgICAgKGNoYW5nZSk9XCJ0cnlVcGxvYWRGaWxlKCRldmVudClcIlxuICAgICAgdHlwZT1cImZpbGVcIlxuICAgICAgW2FjY2VwdF09XCJleHRlbnNpb25zU3RyaW5nXCJcbiAgICAgIHRpdGxlPVwiXCIgLz5cbiAgICA8Y3BzLWljb24gaWNvbj1cImV4cG9ydFwiIHNpemU9XCJsYXJnZVwiIGNvbG9yPVwidGV4dC1kYXJrZXN0XCI+PC9jcHMtaWNvbj5cbiAgICA8ZGl2IGNsYXNzPVwiY3BzLWZpbGUtdXBsb2FkLWRyb3B6b25lLXRpdGxlXCI+XG4gICAgICBEcmFnJkRyb3Agb3IgY2hvb3NlIGEgZmlsZSB0byB1cGxvYWRcbiAgICA8L2Rpdj5cbiAgICA8c3BhblxuICAgICAgY2xhc3M9XCJjcHMtZmlsZS11cGxvYWQtZHJvcHpvbmUtZmlsZS1kZXNjXCJcbiAgICAgICpuZ0lmPVwiZmlsZURlc2MgfHwgZXh0ZW5zaW9uc1N0cmluZ0FzdGVyaXNrc1wiXG4gICAgICA+e3sgZmlsZURlc2MgfX1cbiAgICAgIHt7XG4gICAgICAgIGV4dGVuc2lvbnNTdHJpbmdBc3Rlcmlza3MgPyAnKCcgKyBleHRlbnNpb25zU3RyaW5nQXN0ZXJpc2tzICsgJyknIDogJydcbiAgICAgIH19PC9zcGFuXG4gICAgPlxuICAgIDxjcHMtcHJvZ3Jlc3MtbGluZWFyXG4gICAgICAqbmdJZj1cImlzUHJvY2Vzc2luZ0ZpbGUgJiYgdXBsb2FkZWRGaWxlXCJcbiAgICAgIGhlaWdodD1cIjNcIlxuICAgICAgcmFkaXVzPVwiNFwiXG4gICAgICBvcGFjaXR5PVwiMC4zXCJcbiAgICAgIGNsYXNzPVwiY3BzLWZpbGUtdXBsb2FkLXByb2dyZXNzLWJhclwiXG4gICAgICBiZ0NvbG9yPVwidHJhbnNwYXJlbnRcIj5cbiAgICA8L2Nwcy1wcm9ncmVzcy1saW5lYXI+XG4gIDwvZGl2PlxuICA8ZGl2ICpuZ0lmPVwidXBsb2FkZWRGaWxlXCIgY2xhc3M9XCJjcHMtZmlsZS11cGxvYWQtdXBsb2FkZWQtZmlsZXNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY3BzLWZpbGUtdXBsb2FkLXVwbG9hZGVkLWZpbGVcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcHMtZmlsZS11cGxvYWQtdXBsb2FkZWQtZmlsZS10aXRsZVwiPlxuICAgICAgICA8Y3BzLWljb25cbiAgICAgICAgICBjbGFzcz1cImNwcy1maWxlLXVwbG9hZC11cGxvYWRlZC1maWxlLXN0YXR1cy1pY29uXCJcbiAgICAgICAgICBbaWNvbl09XCJpc1Byb2Nlc3NpbmdGaWxlID8gJ3BlbmRpbmcnIDogJ3RvYXN0LXN1Y2Nlc3MnXCJcbiAgICAgICAgICBbY29sb3JdPVwiaXNQcm9jZXNzaW5nRmlsZSA/ICd3YXJuJyA6ICdzdWNjZXNzJ1wiPlxuICAgICAgICA8L2Nwcy1pY29uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3BzLWZpbGUtdXBsb2FkLXVwbG9hZGVkLWZpbGUtbmFtZVwiPlxuICAgICAgICAgIHt7IHVwbG9hZGVkRmlsZS5uYW1lIH19XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8Y3BzLWljb25cbiAgICAgICAgKm5nSWY9XCIhaXNQcm9jZXNzaW5nRmlsZVwiXG4gICAgICAgIGNsYXNzPVwiY3BzLWZpbGUtdXBsb2FkLXVwbG9hZGVkLWZpbGUtcmVtb3ZlLWljb25cIlxuICAgICAgICBpY29uPVwicmVtb3ZlXCJcbiAgICAgICAgY29sb3I9XCJlcnJvclwiXG4gICAgICAgIChjbGljayk9XCJyZW1vdmVVcGxvYWRlZEZpbGUoKVwiPlxuICAgICAgPC9jcHMtaWNvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
|