@netgrif/components
Version:
Netgrif Application Engine frontend Angular components
157 lines • 34.1 kB
JavaScript
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { ProgressType } from '@netgrif/components-core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import * as i0 from "@angular/core";
import * as i1 from "@angular/material/dialog";
import * as i2 from "@netgrif/components-core";
import * as i3 from "@ngx-translate/core";
import * as i4 from "@angular/common";
import * as i5 from "@ngbracket/ngx-layout";
import * as i6 from "@angular/material/core";
import * as i7 from "@angular/material/button";
import * as i8 from "@angular/material/icon";
import * as i9 from "@angular/material/form-field";
import * as i10 from "@angular/material/progress-bar";
import * as i11 from "@angular/material/progress-spinner";
import * as i12 from "@angular/material/select";
import * as i13 from "@angular/forms";
export class ImportNetDialogComponent {
_dialogRef;
_petriNetResource;
_log;
_snackbar;
_translate;
files = {};
releaseTypes = ['Major', 'Minor', 'Patch'];
releaseTypeControl = new FormControl(this.releaseTypes[0]);
_response = undefined;
_fileInput;
constructor(_dialogRef, _petriNetResource, _log, _snackbar, _translate) {
this._dialogRef = _dialogRef;
this._petriNetResource = _petriNetResource;
this._log = _log;
this._snackbar = _snackbar;
this._translate = _translate;
this._dialogRef.backdropClick().subscribe(event => {
this.close();
});
}
ngAfterViewInit() {
this._fileInput = document.getElementById('sidemenu-fileUpload');
this._fileInput.onchange = () => {
for (const fileIndex of Array.from(Array(this._fileInput.files.length).keys())) {
const file = this._fileInput.files[fileIndex];
if (this.files[file.name]) {
const knownFile = this.files[file.name].data;
if (knownFile.type !== file.type || knownFile.lastModified !== file.lastModified) {
this.files[file.name] = this.setupFile(file);
}
}
else {
this.files[file.name] = this.setupFile(file);
}
}
this.uploadFiles();
};
}
get fileList() {
return Object.values(this.files);
}
get isAllFinished() {
return Object.values(this.files).every(file => !file.inProgress && file.progress === 100);
}
onProcessFileChosen() {
if (this._fileInput) {
this._fileInput.click();
}
}
cancelFile(file) {
file.sub.unsubscribe();
this.removeFile(file);
}
retryFile(file) {
this.uploadFile(file);
}
close() {
this._dialogRef.close({
opened: false,
message: 'All process files were processed',
data: this._response ? { net: this._response.net } : undefined
});
}
setupFile(file) {
return {
data: file,
stringId: '',
downloading: false,
inProgress: false,
progress: 0,
completed: false,
uploaded: false
};
}
uploadFiles() {
this._fileInput.value = '';
this.fileList.filter(fileModel => !fileModel.completed && fileModel.progress === 0).forEach(file => {
this.uploadFile(file);
});
}
removeFile(file) {
if (this.files[file.data.name]) {
delete this.files[file.data.name];
}
}
uploadFile(file) {
const fileFormData = new FormData();
fileFormData.append('file', file.data);
fileFormData.append('meta', this.releaseTypeControl.value.toString().toUpperCase());
file.inProgress = true;
file.completed = false;
file.error = false;
file.sub = this._petriNetResource.importPetriNet(fileFormData).subscribe((response) => {
if (response.type && response.type === ProgressType.UPLOAD) {
file.progress = response.progress;
if (file.progress === 100) {
file.uploaded = true;
}
}
else {
this._log.info(response.success);
this._response = response.outcome;
file.inProgress = false;
file.completed = true;
this._snackbar.openSuccessSnackBar(response.outcome.message === undefined
? this._translate.instant('workflow.snackBar.uploadSuccess')
: response.outcome.message);
}
}, error => {
file.inProgress = false;
file.completed = false;
file.error = true;
this._log.error('Importing process file has failed!', error);
this._snackbar.openErrorSnackBar(`${this._translate.instant('workflow.snackBar.uploadFailed')} ${error?.error?.message ?? ''}`);
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImportNetDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: i2.PetriNetResourceService }, { token: i2.LoggerService }, { token: i2.SnackBarService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ImportNetDialogComponent, selector: "nc-import-net-dialog", ngImport: i0, template: "<div class=\"mat-dialog-title\" fxLayout=\"column\" fxLayoutAlign=\"center none\">\n {{ 'side-menu.import-net.upload' | translate}}\n</div>\n\n<div mat-dialog-content fxLayout=\"column\" class=\"netgrif-input\">\n\n <ul class=\"file-list\">\n <li *ngFor=\"let file of fileList\" [@fadeInOut]=\"'in'\">\n <mat-progress-bar color=\"accent\" [value]=\"file.progress\"></mat-progress-bar>\n <span class=\"file-list-label\">\n <mat-progress-spinner *ngIf=\"file.inProgress && file.uploaded\" class=\"margin-right-default\"\n color=\"accent\" mode=\"indeterminate\" diameter=\"20\"></mat-progress-spinner>\n <mat-icon *ngIf=\"!file.inProgress && file.uploaded && file.completed\"\n class=\"done-icon margin-right-default\">\n done\n </mat-icon>\n <mat-icon *ngIf=\"!file.inProgress && !file.completed && file.error\"\n class=\"done-icon margin-right-default\">\n error\n </mat-icon>\n {{file.data.name}}\n <a title=\"Retry\" (click)=\"retryFile(file)\" *ngIf=\"!file.inProgress && file.error\">\n <mat-icon>refresh</mat-icon>\n </a>\n <a title=\"Cancel\" (click)=\"cancelFile(file)\" *ngIf=\"file.inProgress\">\n <mat-icon>cancel</mat-icon>\n </a>\n </span>\n </li>\n </ul>\n\n <input type=\"file\" id=\"sidemenu-fileUpload\" name=\"fileUpload\" multiple=\"multiple\"\n accept=\"text/xml\" class=\"display-none\"/>\n\n <mat-form-field class=\"cell-padding-fix\" color=\"primary\" appearance=\"outline\">\n <mat-label>Release</mat-label>\n <mat-select [formControl]=\"releaseTypeControl\">\n <mat-option *ngFor=\"let type of releaseTypes\" [value]=\"type\">\n {{type}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <button mat-raised-button color=\"primary\" class=\"margin-top\" (click)=\"onProcessFileChosen()\">\n <mat-icon>file_upload</mat-icon>\n {{ 'side-menu.import-net.choose' | translate}}\n </button>\n\n <button *ngIf=\"isAllFinished\" mat-stroked-button class=\"margin-top\" (click)=\"close()\">\n {{ 'side-menu.import-net.done' | translate}}\n </button>\n\n</div>\n\n", styles: [".file-list,.file-list li{margin:0;padding:0;list-style:none}.file-list-label{display:inline-flex;vertical-align:middle;font-size:12px;line-height:18px}.file-list-label mat-icon{font-size:18px;text-align:center}.file-list-label a{cursor:pointer}.container{padding:10%}.margin-right-default{margin-right:8px}.margin-right-half{margin-right:4px}.display-none{display:none!important}.margin-top{margin-top:8px}.cell-padding-fix{padding:4px 0 0}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i5.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "component", type: i10.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i11.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i13.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], animations: [
trigger('fadeInOut', [
state('in', style({ opacity: 100 })),
transition('* => void', [
animate(300, style({ opacity: 0 }))
])
])
] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImportNetDialogComponent, decorators: [{
type: Component,
args: [{ selector: 'nc-import-net-dialog', animations: [
trigger('fadeInOut', [
state('in', style({ opacity: 100 })),
transition('* => void', [
animate(300, style({ opacity: 0 }))
])
])
], template: "<div class=\"mat-dialog-title\" fxLayout=\"column\" fxLayoutAlign=\"center none\">\n {{ 'side-menu.import-net.upload' | translate}}\n</div>\n\n<div mat-dialog-content fxLayout=\"column\" class=\"netgrif-input\">\n\n <ul class=\"file-list\">\n <li *ngFor=\"let file of fileList\" [@fadeInOut]=\"'in'\">\n <mat-progress-bar color=\"accent\" [value]=\"file.progress\"></mat-progress-bar>\n <span class=\"file-list-label\">\n <mat-progress-spinner *ngIf=\"file.inProgress && file.uploaded\" class=\"margin-right-default\"\n color=\"accent\" mode=\"indeterminate\" diameter=\"20\"></mat-progress-spinner>\n <mat-icon *ngIf=\"!file.inProgress && file.uploaded && file.completed\"\n class=\"done-icon margin-right-default\">\n done\n </mat-icon>\n <mat-icon *ngIf=\"!file.inProgress && !file.completed && file.error\"\n class=\"done-icon margin-right-default\">\n error\n </mat-icon>\n {{file.data.name}}\n <a title=\"Retry\" (click)=\"retryFile(file)\" *ngIf=\"!file.inProgress && file.error\">\n <mat-icon>refresh</mat-icon>\n </a>\n <a title=\"Cancel\" (click)=\"cancelFile(file)\" *ngIf=\"file.inProgress\">\n <mat-icon>cancel</mat-icon>\n </a>\n </span>\n </li>\n </ul>\n\n <input type=\"file\" id=\"sidemenu-fileUpload\" name=\"fileUpload\" multiple=\"multiple\"\n accept=\"text/xml\" class=\"display-none\"/>\n\n <mat-form-field class=\"cell-padding-fix\" color=\"primary\" appearance=\"outline\">\n <mat-label>Release</mat-label>\n <mat-select [formControl]=\"releaseTypeControl\">\n <mat-option *ngFor=\"let type of releaseTypes\" [value]=\"type\">\n {{type}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <button mat-raised-button color=\"primary\" class=\"margin-top\" (click)=\"onProcessFileChosen()\">\n <mat-icon>file_upload</mat-icon>\n {{ 'side-menu.import-net.choose' | translate}}\n </button>\n\n <button *ngIf=\"isAllFinished\" mat-stroked-button class=\"margin-top\" (click)=\"close()\">\n {{ 'side-menu.import-net.done' | translate}}\n </button>\n\n</div>\n\n", styles: [".file-list,.file-list li{margin:0;padding:0;list-style:none}.file-list-label{display:inline-flex;vertical-align:middle;font-size:12px;line-height:18px}.file-list-label mat-icon{font-size:18px;text-align:center}.file-list-label a{cursor:pointer}.container{padding:10%}.margin-right-default{margin-right:8px}.margin-right-half{margin-right:4px}.display-none{display:none!important}.margin-top{margin-top:8px}.cell-padding-fix{padding:4px 0 0}\n"] }]
}], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: i2.PetriNetResourceService }, { type: i2.LoggerService }, { type: i2.SnackBarService }, { type: i3.TranslateService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LW5ldC1kaWFsb2cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmV0Z3JpZi1jb21wb25lbnRzL3NyYy9saWIvZGlhbG9nL2ltcG9ydC1uZXQtZGlhbG9nL2ltcG9ydC1uZXQtZGlhbG9nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy9zcmMvbGliL2RpYWxvZy9pbXBvcnQtbmV0LWRpYWxvZy9pbXBvcnQtbmV0LWRpYWxvZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWdCLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN2RCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUlzQixZQUFZLEVBRXhDLE1BQU0sMEJBQTBCLENBQUM7QUFHbEMsT0FBTyxFQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7O0FBbUIvRSxNQUFNLE9BQU8sd0JBQXdCO0lBU1g7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQVhmLEtBQUssR0FBYSxFQUFFLENBQUM7SUFDckIsWUFBWSxHQUFrQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUQsa0JBQWtCLEdBQUcsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXhELFNBQVMsR0FBeUIsU0FBUyxDQUFDO0lBQzVDLFVBQVUsQ0FBbUI7SUFFdkMsWUFBc0IsVUFBa0QsRUFDbEQsaUJBQTBDLEVBQzFDLElBQW1CLEVBQ25CLFNBQTBCLEVBQzFCLFVBQTRCO1FBSjVCLGVBQVUsR0FBVixVQUFVLENBQXdDO1FB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LElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQzVCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsZ0NBQWdDLENBQUMsSUFBSSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZHLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQzt3R0E3SFEsd0JBQXdCOzRGQUF4Qix3QkFBd0IsNERDOUJyQyxpNkVBc0RBLG8rSERqQ2dCO1lBQ1IsT0FBTyxDQUFDLFdBQVcsRUFBRTtnQkFDakIsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFDLENBQUMsQ0FBQztnQkFDbEMsVUFBVSxDQUFDLFdBQVcsRUFBRTtvQkFDcEIsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQztpQkFDcEMsQ0FBQzthQUNMLENBQUM7U0FDTDs7NEZBRVEsd0JBQXdCO2tCQWJwQyxTQUFTOytCQUNJLHNCQUFzQixjQUdwQjt3QkFDUixPQUFPLENBQUMsV0FBVyxFQUFFOzRCQUNqQixLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFDOzRCQUNsQyxVQUFVLENBQUMsV0FBVyxFQUFFO2dDQUNwQixPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUMsQ0FBQyxDQUFDOzZCQUNwQyxDQUFDO3lCQUNMLENBQUM7cUJBQ0wiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FmdGVyVmlld0luaXQsIENvbXBvbmVudH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0Zvcm1Db250cm9sfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICAgIEV2ZW50T3V0Y29tZU1lc3NhZ2VSZXNvdXJjZSxcbiAgICBGaWxlVXBsb2FkTW9kZWwsIExvZ2dlclNlcnZpY2UsXG4gICAgUGV0cmlOZXRFdmVudE91dGNvbWUsXG4gICAgUGV0cmlOZXRSZXNvdXJjZVNlcnZpY2UsIFByb2dyZXNzVHlwZSwgUHJvdmlkZXJQcm9ncmVzcyxcbiAgICBTbmFja0JhclNlcnZpY2Vcbn0gZnJvbSAnQG5ldGdyaWYvY29tcG9uZW50cy1jb3JlJztcbmltcG9ydCB7VHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge01hdERpYWxvZ1JlZn0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7YW5pbWF0ZSwgc3RhdGUsIHN0eWxlLCB0cmFuc2l0aW9uLCB0cmlnZ2VyfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcblxuaW50ZXJmYWNlIEZpbGVMaXN0IHtcbiAgICBba2V5OiBzdHJpbmddOiBGaWxlVXBsb2FkTW9kZWw7XG59XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmMtaW1wb3J0LW5ldC1kaWFsb2cnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9pbXBvcnQtbmV0LWRpYWxvZy5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vaW1wb3J0LW5ldC1kaWFsb2cuY29tcG9uZW50LnNjc3MnXSxcbiAgICBhbmltYXRpb25zOiBbXG4gICAgICAgIHRyaWdnZXIoJ2ZhZGVJbk91dCcsIFtcbiAgICAgICAgICAgIHN0YXRlKCdpbicsIHN0eWxlKHtvcGFjaXR5OiAxMDB9KSksXG4gICAgICAgICAgICB0cmFuc2l0aW9uKCcqID0+IHZvaWQnLCBbXG4gICAgICAgICAgICAgICAgYW5pbWF0ZSgzMDAsIHN0eWxlKHtvcGFjaXR5OiAwfSkpXG4gICAgICAgICAgICBdKVxuICAgICAgICBdKVxuICAgIF1cbn0pXG5leHBvcnQgY2xhc3MgSW1wb3J0TmV0RGlhbG9nQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG5cbiAgICBwdWJsaWMgZmlsZXM6IEZpbGVMaXN0ID0ge307XG4gICAgcHVibGljIHJlbGVhc2VUeXBlczogQXJyYXk8c3RyaW5nPiA9IFsnTWFqb3InLCAnTWlub3InLCAnUGF0Y2gnXTtcbiAgICBwdWJsaWMgcmVsZWFzZVR5cGVDb250cm9sID0gbmV3IEZvcm1Db250cm9sKHRoaXMucmVsZWFzZVR5cGVzWzBdKTtcblxuICAgIHByb3RlY3RlZCBfcmVzcG9uc2U6IFBldHJpTmV0RXZlbnRPdXRjb21lID0gdW5kZWZpbmVkO1xuICAgIHByb3RlY3RlZCBfZmlsZUlucHV0OiBIVE1MSW5wdXRFbGVtZW50O1xuXG4gICAgY29uc3RydWN0b3IocHJvdGVjdGVkIF9kaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxJbXBvcnROZXREaWFsb2dDb21wb25lbnQ+LFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfcGV0cmlOZXRSZXNvdXJjZTogUGV0cmlOZXRSZXNvdXJjZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9sb2c6IExvZ2dlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9zbmFja2JhcjogU25hY2tCYXJTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5iYWNrZHJvcENsaWNrKCkuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9maWxlSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZW1lbnUtZmlsZVVwbG9hZCcpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX2ZpbGVJbnB1dC5vbmNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZmlsZUluZGV4IG9mIEFycmF5LmZyb20oQXJyYXkodGhpcy5fZmlsZUlucHV0LmZpbGVzLmxlbmd0aCkua2V5cygpKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLl9maWxlSW5wdXQuZmlsZXNbZmlsZUluZGV4XTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5maWxlc1tmaWxlLm5hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGtub3duRmlsZSA9IHRoaXMuZmlsZXNbZmlsZS5uYW1lXS5kYXRhIGFzIEZpbGU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrbm93bkZpbGUudHlwZSAhPT0gZmlsZS50eXBlIHx8IGtub3duRmlsZS5sYXN0TW9kaWZpZWQgIT09IGZpbGUubGFzdE1vZGlmaWVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbGVzW2ZpbGUubmFtZV0gPSB0aGlzLnNldHVwRmlsZShmaWxlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsZXNbZmlsZS5uYW1lXSA9IHRoaXMuc2V0dXBGaWxlKGZpbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudXBsb2FkRmlsZXMoKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZXQgZmlsZUxpc3QoKTogQXJyYXk8RmlsZVVwbG9hZE1vZGVsPiB7XG4gICAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuZmlsZXMpO1xuICAgIH1cblxuICAgIGdldCBpc0FsbEZpbmlzaGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0aGlzLmZpbGVzKS5ldmVyeShmaWxlID0+ICFmaWxlLmluUHJvZ3Jlc3MgJiYgZmlsZS5wcm9ncmVzcyA9PT0gMTAwKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Qcm9jZXNzRmlsZUNob3NlbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2ZpbGVJbnB1dCkge1xuICAgICAgICAgICAgdGhpcy5fZmlsZUlucHV0LmNsaWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2FuY2VsRmlsZShmaWxlOiBGaWxlVXBsb2FkTW9kZWwpIHtcbiAgICAgICAgZmlsZS5zdWIudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5yZW1vdmVGaWxlKGZpbGUpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZXRyeUZpbGUoZmlsZTogRmlsZVVwbG9hZE1vZGVsKSB7XG4gICAgICAgIHRoaXMudXBsb2FkRmlsZShmaWxlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY2xvc2UoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5jbG9zZSh7XG4gICAgICAgICAgICBvcGVuZWQ6IGZhbHNlLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0FsbCBwcm9jZXNzIGZpbGVzIHdlcmUgcHJvY2Vzc2VkJyxcbiAgICAgICAgICAgIGRhdGE6IHRoaXMuX3Jlc3BvbnNlID8ge25ldDogdGhpcy5fcmVzcG9uc2UubmV0fSA6IHVuZGVmaW5lZFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc2V0dXBGaWxlKGZpbGU6IEZpbGUpOiBGaWxlVXBsb2FkTW9kZWwge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YTogZmlsZSxcbiAgICAgICAgICAgIHN0cmluZ0lkOiAnJyxcbiAgICAgICAgICAgIGRvd25sb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgIGluUHJvZ3Jlc3M6IGZhbHNlLFxuICAgICAgICAgICAgcHJvZ3Jlc3M6IDAsXG4gICAgICAgICAgICBjb21wbGV0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgdXBsb2FkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHVwbG9hZEZpbGVzKCkge1xuICAgICAgICB0aGlzLl9maWxlSW5wdXQudmFsdWUgPSAnJztcblxuICAgICAgICB0aGlzLmZpbGVMaXN0LmZpbHRlcihmaWxlTW9kZWwgPT4gIWZpbGVNb2RlbC5jb21wbGV0ZWQgJiYgZmlsZU1vZGVsLnByb2dyZXNzID09PSAwKS5mb3JFYWNoKGZpbGUgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGxvYWRGaWxlKGZpbGUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVtb3ZlRmlsZShmaWxlOiBGaWxlVXBsb2FkTW9kZWwpIHtcbiAgICAgICAgaWYgKHRoaXMuZmlsZXNbZmlsZS5kYXRhLm5hbWVdKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5maWxlc1tmaWxlLmRhdGEubmFtZV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgdXBsb2FkRmlsZShmaWxlOiBGaWxlVXBsb2FkTW9kZWwpIHtcbiAgICAgICAgY29uc3QgZmlsZUZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZpbGVGb3JtRGF0YS5hcHBlbmQoJ2ZpbGUnLCBmaWxlLmRhdGEgYXMgRmlsZSk7XG4gICAgICAgIGZpbGVGb3JtRGF0YS5hcHBlbmQoJ21ldGEnLCB0aGlzLnJlbGVhc2VUeXBlQ29udHJvbC52YWx1ZS50b1N0cmluZygpLnRvVXBwZXJDYXNlKCkpO1xuXG4gICAgICAgIGZpbGUuaW5Qcm9ncmVzcyA9IHRydWU7XG4gICAgICAgIGZpbGUuY29tcGxldGVkID0gZmFsc2U7XG4gICAgICAgIGZpbGUuZXJyb3IgPSBmYWxzZTtcbiAgICAgICAgZmlsZS5zdWIgPSB0aGlzLl9wZXRyaU5ldFJlc291cmNlLmltcG9ydFBldHJpTmV0KGZpbGVGb3JtRGF0YSkuc3Vic2NyaWJlKChyZXNwb25zZTogRXZlbnRPdXRjb21lTWVzc2FnZVJlc291cmNlKSA9PiB7XG4gICAgICAgICAgICBpZiAoKHJlc3BvbnNlIGFzIFByb3ZpZGVyUHJvZ3Jlc3MpLnR5cGUgJiYgKHJlc3BvbnNlIGFzIFByb3ZpZGVyUHJvZ3Jlc3MpLnR5cGUgPT09IFByb2dyZXNzVHlwZS5VUExPQUQpIHtcbiAgICAgICAgICAgICAgICBmaWxlLnByb2dyZXNzID0gKHJlc3BvbnNlIGFzIFByb3ZpZGVyUHJvZ3Jlc3MpLnByb2dyZXNzO1xuICAgICAgICAgICAgICAgIGlmIChmaWxlLnByb2dyZXNzID09PSAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZS51cGxvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2cuaW5mbyhyZXNwb25zZS5zdWNjZXNzKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZXNwb25zZSA9IHJlc3BvbnNlLm91dGNvbWUgYXMgUGV0cmlOZXRFdmVudE91dGNvbWU7XG4gICAgICAgICAgICAgICAgZmlsZS5pblByb2dyZXNzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZmlsZS5jb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NuYWNrYmFyLm9wZW5TdWNjZXNzU25hY2tCYXIocmVzcG9uc2Uub3V0Y29tZS5tZXNzYWdlID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLl90cmFuc2xhdGUuaW5zdGFudCgnd29ya2Zsb3cuc25hY2tCYXIudXBsb2FkU3VjY2VzcycpXG4gICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2Uub3V0Y29tZS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgZXJyb3IgPT4ge1xuICAgICAgICAgICAgZmlsZS5pblByb2dyZXNzID0gZmFsc2U7XG4gICAgICAgICAgICBmaWxlLmNvbXBsZXRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgZmlsZS5lcnJvciA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9sb2cuZXJyb3IoJ0ltcG9ydGluZyBwcm9jZXNzIGZpbGUgaGFzIGZhaWxlZCEnLCBlcnJvcik7XG4gICAgICAgICAgICB0aGlzLl9zbmFja2Jhci5vcGVuRXJyb3JTbmFja0JhcihcbiAgICAgICAgICAgICAgICBgJHt0aGlzLl90cmFuc2xhdGUuaW5zdGFudCgnd29ya2Zsb3cuc25hY2tCYXIudXBsb2FkRmFpbGVkJyl9ICR7ZXJyb3I/LmVycm9yPy5tZXNzYWdlID8/ICcnfWApO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiIGZ4TGF5b3V0PVwiY29sdW1uXCIgZnhMYXlvdXRBbGlnbj1cImNlbnRlciBub25lXCI+XG4gICAge3sgJ3NpZGUtbWVudS5pbXBvcnQtbmV0LnVwbG9hZCcgfCB0cmFuc2xhdGV9fVxuPC9kaXY+XG5cbjxkaXYgbWF0LWRpYWxvZy1jb250ZW50IGZ4TGF5b3V0PVwiY29sdW1uXCIgY2xhc3M9XCJuZXRncmlmLWlucHV0XCI+XG5cbiAgICA8dWwgY2xhc3M9XCJmaWxlLWxpc3RcIj5cbiAgICAgICAgPGxpICpuZ0Zvcj1cImxldCBmaWxlIG9mIGZpbGVMaXN0XCIgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiPlxuICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgY29sb3I9XCJhY2NlbnRcIiBbdmFsdWVdPVwiZmlsZS5wcm9ncmVzc1wiPjwvbWF0LXByb2dyZXNzLWJhcj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmlsZS1saXN0LWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1zcGlubmVyICpuZ0lmPVwiZmlsZS5pblByb2dyZXNzICYmIGZpbGUudXBsb2FkZWRcIiBjbGFzcz1cIm1hcmdpbi1yaWdodC1kZWZhdWx0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJhY2NlbnRcIiBtb2RlPVwiaW5kZXRlcm1pbmF0ZVwiIGRpYW1ldGVyPVwiMjBcIj48L21hdC1wcm9ncmVzcy1zcGlubmVyPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFmaWxlLmluUHJvZ3Jlc3MgJiYgZmlsZS51cGxvYWRlZCAmJiBmaWxlLmNvbXBsZXRlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZG9uZS1pY29uIG1hcmdpbi1yaWdodC1kZWZhdWx0XCI+XG4gICAgICAgICAgICAgICAgICAgIGRvbmVcbiAgICAgICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFmaWxlLmluUHJvZ3Jlc3MgJiYgIWZpbGUuY29tcGxldGVkICYmICBmaWxlLmVycm9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkb25lLWljb24gbWFyZ2luLXJpZ2h0LWRlZmF1bHRcIj5cbiAgICAgICAgICAgICAgICAgICAgZXJyb3JcbiAgICAgICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIHt7ZmlsZS5kYXRhLm5hbWV9fVxuICAgICAgICAgICAgICAgIDxhIHRpdGxlPVwiUmV0cnlcIiAoY2xpY2spPVwicmV0cnlGaWxlKGZpbGUpXCIgKm5nSWY9XCIhZmlsZS5pblByb2dyZXNzICYmIGZpbGUuZXJyb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnJlZnJlc2g8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8YSB0aXRsZT1cIkNhbmNlbFwiIChjbGljayk9XCJjYW5jZWxGaWxlKGZpbGUpXCIgKm5nSWY9XCJmaWxlLmluUHJvZ3Jlc3NcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNhbmNlbDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xpPlxuICAgIDwvdWw+XG5cbiAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiBpZD1cInNpZGVtZW51LWZpbGVVcGxvYWRcIiBuYW1lPVwiZmlsZVVwbG9hZFwiIG11bHRpcGxlPVwibXVsdGlwbGVcIlxuICAgICAgICAgICBhY2NlcHQ9XCJ0ZXh0L3htbFwiIGNsYXNzPVwiZGlzcGxheS1ub25lXCIvPlxuXG4gICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiY2VsbC1wYWRkaW5nLWZpeFwiIGNvbG9yPVwicHJpbWFyeVwiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCI+XG4gICAgICAgIDxtYXQtbGFiZWw+UmVsZWFzZTwvbWF0LWxhYmVsPlxuICAgICAgICA8bWF0LXNlbGVjdCBbZm9ybUNvbnRyb2xdPVwicmVsZWFzZVR5cGVDb250cm9sXCI+XG4gICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgdHlwZSBvZiByZWxlYXNlVHlwZXNcIiBbdmFsdWVdPVwidHlwZVwiPlxuICAgICAgICAgICAgICAgIHt7dHlwZX19XG4gICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgPGJ1dHRvbiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiBjbGFzcz1cIm1hcmdpbi10b3BcIiAoY2xpY2spPVwib25Qcm9jZXNzRmlsZUNob3NlbigpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5maWxlX3VwbG9hZDwvbWF0LWljb24+XG4gICAgICAgIHt7ICdzaWRlLW1lbnUuaW1wb3J0LW5ldC5jaG9vc2UnIHwgdHJhbnNsYXRlfX1cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b24gKm5nSWY9XCJpc0FsbEZpbmlzaGVkXCIgbWF0LXN0cm9rZWQtYnV0dG9uIGNsYXNzPVwibWFyZ2luLXRvcFwiIChjbGljayk9XCJjbG9zZSgpXCI+XG4gICAgICAgIHt7ICdzaWRlLW1lbnUuaW1wb3J0LW5ldC5kb25lJyB8IHRyYW5zbGF0ZX19XG4gICAgPC9idXR0b24+XG5cbjwvZGl2PlxuXG4iXX0=