UNPKG

@alfresco/adf-content-services

Version:
155 lines 30.1 kB
/*! * @license * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Component, DestroyRef, EventEmitter, inject, Input, Output, ViewEncapsulation } from '@angular/core'; import { Node, Version } from '@alfresco/js-api'; import { ContentService } from '../common/services/content.service'; import { UploadService } from '../common/services/upload.service'; import { CommonModule } from '@angular/common'; import { MatRadioModule } from '@angular/material/radio'; import { FormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatButtonModule } from '@angular/material/button'; import { UploadVersionButtonComponent } from '../upload'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import * as i0 from "@angular/core"; import * as i1 from "../common/services/content.service"; import * as i2 from "../common/services/upload.service"; import * as i3 from "@angular/common"; import * as i4 from "@angular/material/radio"; import * as i5 from "@angular/forms"; 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 VersionUploadComponent { /** Current version for a target node */ set currentVersion(version) { if (version) { this.minorVersion = this.getNextMinorVersion(version.id); this.majorVersion = this.getNextMajorVersion(version.id); } } constructor(contentService, uploadService) { this.contentService = contentService; this.uploadService = uploadService; this.semanticVersion = 'minor'; this.uploadVersion = false; this.disabled = false; this.majorVersion = '2.0'; this.minorVersion = '1.1'; /** Toggles showing/hiding upload button. */ this.showUploadButton = true; /** Toggles showing/hiding of cancel button. */ this.showCancelButton = true; /** Emitted when the file is uploaded successfully. */ this.success = new EventEmitter(); /** Emitted when an error occurs. */ this.error = new EventEmitter(); /** Emitted when an cancelling during upload. */ this.cancel = new EventEmitter(); /** Emitted when the version is changed. */ this.versionChanged = new EventEmitter(); /** Emitted when the comment is changed. */ this.commentChanged = new EventEmitter(); /** Emitted when the upload starts */ this.uploadStarted = new EventEmitter(); this.destroyRef = inject(DestroyRef); } ngOnInit() { this.uploadService.fileUploadStarting.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => { this.disabled = true; this.uploadStarted.emit(event); }); } canUpload() { return this.contentService.hasAllowableOperations(this.node, 'update') && !this.disabled; } isMajorVersion() { return this.semanticVersion !== 'minor'; } cancelUpload() { this.disabled = false; this.cancel.emit(); } onVersionChange() { this.versionChanged.emit(this.isMajorVersion()); } onCommentChange() { this.commentChanged.emit(this.comment); } onSuccess(event) { this.success.emit(event); } onError(event) { this.disabled = false; this.error.emit(event); } getNextMinorVersion(version) { const { major, minor } = this.getParsedVersion(version); return `${major}.${minor + 1}`; } getNextMajorVersion(version) { const { major } = this.getParsedVersion(version); return `${major + 1}.0`; } getParsedVersion(version) { const minor = version.indexOf('.') !== -1 ? Number(version.substr(version.indexOf('.') + 1)) : 0; const major = parseInt(version, 10); return { minor, major }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: VersionUploadComponent, deps: [{ token: i1.ContentService }, { token: i2.UploadService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: VersionUploadComponent, isStandalone: true, selector: "adf-version-upload", inputs: { node: "node", newFileVersion: "newFileVersion", showUploadButton: "showUploadButton", showCancelButton: "showCancelButton", currentVersion: "currentVersion" }, outputs: { success: "success", error: "error", cancel: "cancel", versionChanged: "versionChanged", commentChanged: "commentChanged", uploadStarted: "uploadStarted" }, host: { classAttribute: "adf-version-upload" }, ngImport: i0, template: "<div class=\"adf-new-version-max-width\">\n <mat-radio-group class=\"adf-new-version-radio-group\" [(ngModel)]=\"semanticVersion\" (change)=\"onVersionChange()\">\n <mat-radio-button class=\"adf-new-version-radio-button\" id=\"adf-new-version-minor\" [value]=\"'minor'\">\n {{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.MINOR' | translate: { version: minorVersion } }}\n </mat-radio-button>\n <mat-radio-button class=\"adf-new-version-radio-button\" id=\"adf-new-version-major\" [value]=\"'major'\">\n {{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.MAJOR' | translate: { version: majorVersion } }}\n </mat-radio-button>\n </mat-radio-group>\n <mat-form-field class=\"adf-new-version-max-width\" subscriptSizing=\"dynamic\">\n <mat-label>{{'ADF_VERSION_LIST.ACTIONS.UPLOAD.COMMENT' | translate}}</mat-label>\n <textarea matInput\n [(ngModel)]=\"comment\"\n class=\"adf-new-version-text-area\" id=\"adf-new-version-text-area\"\n (change)=\"onCommentChange()\"></textarea>\n </mat-form-field>\n</div>\n<div class=\"adf-version-upload-buttons\">\n <adf-upload-version-button *ngIf=\"showUploadButton\"\n data-automation-id=\"adf-new-version-file-upload\"\n staticTitle=\"{{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.TITLE' | translate }}\"\n [node]=\"node\"\n [disabled]=\"!canUpload()\"\n [rootFolderId]=\"node.parentId\"\n tooltip=\"{{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.TOOLTIP' | translate }}\"\n [comment]=\"comment\"\n [versioning]=\"true\"\n [file]=\"newFileVersion\"\n [majorVersion]=\"isMajorVersion()\"\n (success)=\"onSuccess($event)\"\n (error)=\"onError($event)\" />\n <button mat-raised-button (click)=\"cancelUpload()\" id=\"adf-new-version-cancel\" *ngIf=\"showCancelButton\" >{{\n 'ADF_VERSION_LIST.ACTIONS.UPLOAD.CANCEL'| translate }}\n </button>\n</div>\n", styles: [".adf-new-version-radio-group{display:inline-flex;flex-direction:column}.adf-new-version-radio-button{margin:2px 5px 5px}.adf-version-upload-buttons{padding-top:18px;padding-bottom:5px;display:flex;float:right;justify-content:space-between;width:100%}.adf-version-upload .adf-new-version-max-width{padding-top:2px;width:100%;float:right}.adf-version-upload .adf-new-version-max-width .mdc-floating-label{padding-bottom:10px}.adf-version-upload .adf-new-version-max-width .mat-mdc-form-field-infix{padding-top:12px;padding-bottom:0}.adf-version-upload .adf-new-version-max-width .adf-new-version-text-area{resize:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i4.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i4.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { 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: "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: "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"] }, { kind: "component", type: UploadVersionButtonComponent, selector: "adf-upload-version-button", inputs: ["node"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: VersionUploadComponent, decorators: [{ type: Component, args: [{ selector: 'adf-version-upload', standalone: true, imports: [ CommonModule, MatRadioModule, FormsModule, TranslateModule, MatFormFieldModule, MatInputModule, MatButtonModule, UploadVersionButtonComponent ], encapsulation: ViewEncapsulation.None, host: { class: 'adf-version-upload' }, template: "<div class=\"adf-new-version-max-width\">\n <mat-radio-group class=\"adf-new-version-radio-group\" [(ngModel)]=\"semanticVersion\" (change)=\"onVersionChange()\">\n <mat-radio-button class=\"adf-new-version-radio-button\" id=\"adf-new-version-minor\" [value]=\"'minor'\">\n {{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.MINOR' | translate: { version: minorVersion } }}\n </mat-radio-button>\n <mat-radio-button class=\"adf-new-version-radio-button\" id=\"adf-new-version-major\" [value]=\"'major'\">\n {{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.MAJOR' | translate: { version: majorVersion } }}\n </mat-radio-button>\n </mat-radio-group>\n <mat-form-field class=\"adf-new-version-max-width\" subscriptSizing=\"dynamic\">\n <mat-label>{{'ADF_VERSION_LIST.ACTIONS.UPLOAD.COMMENT' | translate}}</mat-label>\n <textarea matInput\n [(ngModel)]=\"comment\"\n class=\"adf-new-version-text-area\" id=\"adf-new-version-text-area\"\n (change)=\"onCommentChange()\"></textarea>\n </mat-form-field>\n</div>\n<div class=\"adf-version-upload-buttons\">\n <adf-upload-version-button *ngIf=\"showUploadButton\"\n data-automation-id=\"adf-new-version-file-upload\"\n staticTitle=\"{{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.TITLE' | translate }}\"\n [node]=\"node\"\n [disabled]=\"!canUpload()\"\n [rootFolderId]=\"node.parentId\"\n tooltip=\"{{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.TOOLTIP' | translate }}\"\n [comment]=\"comment\"\n [versioning]=\"true\"\n [file]=\"newFileVersion\"\n [majorVersion]=\"isMajorVersion()\"\n (success)=\"onSuccess($event)\"\n (error)=\"onError($event)\" />\n <button mat-raised-button (click)=\"cancelUpload()\" id=\"adf-new-version-cancel\" *ngIf=\"showCancelButton\" >{{\n 'ADF_VERSION_LIST.ACTIONS.UPLOAD.CANCEL'| translate }}\n </button>\n</div>\n", styles: [".adf-new-version-radio-group{display:inline-flex;flex-direction:column}.adf-new-version-radio-button{margin:2px 5px 5px}.adf-version-upload-buttons{padding-top:18px;padding-bottom:5px;display:flex;float:right;justify-content:space-between;width:100%}.adf-version-upload .adf-new-version-max-width{padding-top:2px;width:100%;float:right}.adf-version-upload .adf-new-version-max-width .mdc-floating-label{padding-bottom:10px}.adf-version-upload .adf-new-version-max-width .mat-mdc-form-field-infix{padding-top:12px;padding-bottom:0}.adf-version-upload .adf-new-version-max-width .adf-new-version-text-area{resize:none}\n"] }] }], ctorParameters: () => [{ type: i1.ContentService }, { type: i2.UploadService }], propDecorators: { node: [{ type: Input, args: [{ required: true }] }], newFileVersion: [{ type: Input }], showUploadButton: [{ type: Input }], showCancelButton: [{ type: Input }], currentVersion: [{ type: Input }], success: [{ type: Output }], error: [{ type: Output }], cancel: [{ type: Output }], versionChanged: [{ type: Output }], commentChanged: [{ type: Output }], uploadStarted: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGliL2NvbnRlbnQtc2VydmljZXMvc3JjL2xpYi92ZXJzaW9uLW1hbmFnZXIvdmVyc2lvbi11cGxvYWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vbGliL2NvbnRlbnQtc2VydmljZXMvc3JjL2xpYi92ZXJzaW9uLW1hbmFnZXIvdmVyc2lvbi11cGxvYWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RILE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUVsRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxXQUFXLENBQUM7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d0JBQ2QsV0FBVzt3QkFDWCxlQUFlO3dCQUNmLGtCQUFrQjt3QkFDbEIsY0FBYzt3QkFDZCxlQUFlO3dCQUNmLDRCQUE0QjtxQkFDL0IsaUJBR2MsaUJBQWlCLENBQUMsSUFBSSxRQUMvQixFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRTsrR0FZckMsSUFBSTtzQkFESCxLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFLekIsY0FBYztzQkFEYixLQUFLO2dCQUtOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUtOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUtGLGNBQWM7c0JBRGpCLEtBQUs7Z0JBVU4sT0FBTztzQkFETixNQUFNO2dCQUtQLEtBQUs7c0JBREosTUFBTTtnQkFLUCxNQUFNO3NCQURMLE1BQU07Z0JBS1AsY0FBYztzQkFEYixNQUFNO2dCQUtQLGNBQWM7c0JBRGIsTUFBTTtnQkFLUCxhQUFhO3NCQURaLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgwqkgMjAwNS0yMDI1IEh5bGFuZCBTb2Z0d2FyZSwgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IENvbXBvbmVudCwgRGVzdHJveVJlZiwgRXZlbnRFbWl0dGVyLCBpbmplY3QsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5vZGUsIFZlcnNpb24gfSBmcm9tICdAYWxmcmVzY28vanMtYXBpJztcbmltcG9ydCB7IENvbnRlbnRTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3NlcnZpY2VzL2NvbnRlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBVcGxvYWRTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3NlcnZpY2VzL3VwbG9hZC5zZXJ2aWNlJztcbmltcG9ydCB7IEZpbGVVcGxvYWRFcnJvckV2ZW50LCBGaWxlVXBsb2FkRXZlbnQgfSBmcm9tICcuLi9jb21tb24vZXZlbnRzL2ZpbGUuZXZlbnQnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE1hdFJhZGlvTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcmFkaW8nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVNb2R1bGUgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgVXBsb2FkVmVyc2lvbkJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJy4uL3VwbG9hZCc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYWRmLXZlcnNpb24tdXBsb2FkJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQ29tbW9uTW9kdWxlLFxuICAgICAgICBNYXRSYWRpb01vZHVsZSxcbiAgICAgICAgRm9ybXNNb2R1bGUsXG4gICAgICAgIFRyYW5zbGF0ZU1vZHVsZSxcbiAgICAgICAgTWF0Rm9ybUZpZWxkTW9kdWxlLFxuICAgICAgICBNYXRJbnB1dE1vZHVsZSxcbiAgICAgICAgTWF0QnV0dG9uTW9kdWxlLFxuICAgICAgICBVcGxvYWRWZXJzaW9uQnV0dG9uQ29tcG9uZW50XG4gICAgXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdmVyc2lvbi11cGxvYWQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL3ZlcnNpb24tdXBsb2FkLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBob3N0OiB7IGNsYXNzOiAnYWRmLXZlcnNpb24tdXBsb2FkJyB9XG59KVxuZXhwb3J0IGNsYXNzIFZlcnNpb25VcGxvYWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAgIHNlbWFudGljVmVyc2lvbjogc3RyaW5nID0gJ21pbm9yJztcbiAgICBjb21tZW50OiBzdHJpbmc7XG4gICAgdXBsb2FkVmVyc2lvbjogYm9vbGVhbiA9IGZhbHNlO1xuICAgIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG4gICAgbWFqb3JWZXJzaW9uID0gJzIuMCc7XG4gICAgbWlub3JWZXJzaW9uID0gJzEuMSc7XG5cbiAgICAvKiogVGhlIHRhcmdldCBub2RlLiAqL1xuICAgIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pXG4gICAgbm9kZTogTm9kZTtcblxuICAgIC8qKiBOZXcgZmlsZSBmb3IgdXBkYXRpbmcgY3VycmVudCB2ZXJzaW9uLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgbmV3RmlsZVZlcnNpb246IEZpbGU7XG5cbiAgICAvKiogVG9nZ2xlcyBzaG93aW5nL2hpZGluZyB1cGxvYWQgYnV0dG9uLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgc2hvd1VwbG9hZEJ1dHRvbjogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogVG9nZ2xlcyBzaG93aW5nL2hpZGluZyBvZiBjYW5jZWwgYnV0dG9uLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgc2hvd0NhbmNlbEJ1dHRvbjogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogQ3VycmVudCB2ZXJzaW9uIGZvciBhIHRhcmdldCBub2RlICovXG4gICAgQElucHV0KClcbiAgICBzZXQgY3VycmVudFZlcnNpb24odmVyc2lvbjogVmVyc2lvbikge1xuICAgICAgICBpZiAodmVyc2lvbikge1xuICAgICAgICAgICAgdGhpcy5taW5vclZlcnNpb24gPSB0aGlzLmdldE5leHRNaW5vclZlcnNpb24odmVyc2lvbi5pZCk7XG4gICAgICAgICAgICB0aGlzLm1ham9yVmVyc2lvbiA9IHRoaXMuZ2V0TmV4dE1ham9yVmVyc2lvbih2ZXJzaW9uLmlkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBFbWl0dGVkIHdoZW4gdGhlIGZpbGUgaXMgdXBsb2FkZWQgc3VjY2Vzc2Z1bGx5LiAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHN1Y2Nlc3MgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKiogRW1pdHRlZCB3aGVuIGFuIGVycm9yIG9jY3Vycy4gKi9cbiAgICBAT3V0cHV0KClcbiAgICBlcnJvciA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZVVwbG9hZEVycm9yRXZlbnQ+KCk7XG5cbiAgICAvKiogRW1pdHRlZCB3aGVuIGFuIGNhbmNlbGxpbmcgZHVyaW5nIHVwbG9hZC4gKi9cbiAgICBAT3V0cHV0KClcbiAgICBjYW5jZWwgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKiogRW1pdHRlZCB3aGVuIHRoZSB2ZXJzaW9uIGlzIGNoYW5nZWQuICovXG4gICAgQE91dHB1dCgpXG4gICAgdmVyc2lvbkNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgICAvKiogRW1pdHRlZCB3aGVuIHRoZSBjb21tZW50IGlzIGNoYW5nZWQuICovXG4gICAgQE91dHB1dCgpXG4gICAgY29tbWVudENoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAgIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHVwbG9hZCBzdGFydHMgKi9cbiAgICBAT3V0cHV0KClcbiAgICB1cGxvYWRTdGFydGVkID0gbmV3IEV2ZW50RW1pdHRlcjxGaWxlVXBsb2FkRXZlbnQ+KCk7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbnRlbnRTZXJ2aWNlOiBDb250ZW50U2VydmljZSwgcHJpdmF0ZSB1cGxvYWRTZXJ2aWNlOiBVcGxvYWRTZXJ2aWNlKSB7fVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMudXBsb2FkU2VydmljZS5maWxlVXBsb2FkU3RhcnRpbmcucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKChldmVudDogRmlsZVVwbG9hZEV2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMudXBsb2FkU3RhcnRlZC5lbWl0KGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY2FuVXBsb2FkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50U2VydmljZS5oYXNBbGxvd2FibGVPcGVyYXRpb25zKHRoaXMubm9kZSwgJ3VwZGF0ZScpICYmICF0aGlzLmRpc2FibGVkO1xuICAgIH1cblxuICAgIGlzTWFqb3JWZXJzaW9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zZW1hbnRpY1ZlcnNpb24gIT09ICdtaW5vcic7XG4gICAgfVxuXG4gICAgY2FuY2VsVXBsb2FkKCkge1xuICAgICAgICB0aGlzLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2FuY2VsLmVtaXQoKTtcbiAgICB9XG5cbiAgICBvblZlcnNpb25DaGFuZ2UoKSB7XG4gICAgICAgIHRoaXMudmVyc2lvbkNoYW5nZWQuZW1pdCh0aGlzLmlzTWFqb3JWZXJzaW9uKCkpO1xuICAgIH1cblxuICAgIG9uQ29tbWVudENoYW5nZSgpIHtcbiAgICAgICAgdGhpcy5jb21tZW50Q2hhbmdlZC5lbWl0KHRoaXMuY29tbWVudCk7XG4gICAgfVxuXG4gICAgb25TdWNjZXNzKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgdGhpcy5zdWNjZXNzLmVtaXQoZXZlbnQpO1xuICAgIH1cblxuICAgIG9uRXJyb3IoZXZlbnQ6IEZpbGVVcGxvYWRFcnJvckV2ZW50KSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5lcnJvci5lbWl0KGV2ZW50KTtcbiAgICB9XG5cbiAgICBnZXROZXh0TWlub3JWZXJzaW9uKHZlcnNpb246IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHsgbWFqb3IsIG1pbm9yIH0gPSB0aGlzLmdldFBhcnNlZFZlcnNpb24odmVyc2lvbik7XG4gICAgICAgIHJldHVybiBgJHttYWpvcn0uJHttaW5vciArIDF9YDtcbiAgICB9XG5cbiAgICBnZXROZXh0TWFqb3JWZXJzaW9uKHZlcnNpb246IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHsgbWFqb3IgfSA9IHRoaXMuZ2V0UGFyc2VkVmVyc2lvbih2ZXJzaW9uKTtcbiAgICAgICAgcmV0dXJuIGAke21ham9yICsgMX0uMGA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRQYXJzZWRWZXJzaW9uKHZlcnNpb246IHN0cmluZykge1xuICAgICAgICBjb25zdCBtaW5vciA9IHZlcnNpb24uaW5kZXhPZignLicpICE9PSAtMSA/IE51bWJlcih2ZXJzaW9uLnN1YnN0cih2ZXJzaW9uLmluZGV4T2YoJy4nKSArIDEpKSA6IDA7XG4gICAgICAgIGNvbnN0IG1ham9yID0gcGFyc2VJbnQodmVyc2lvbiwgMTApO1xuICAgICAgICByZXR1cm4geyBtaW5vciwgbWFqb3IgfTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiYWRmLW5ldy12ZXJzaW9uLW1heC13aWR0aFwiPlxuICAgIDxtYXQtcmFkaW8tZ3JvdXAgY2xhc3M9XCJhZGYtbmV3LXZlcnNpb24tcmFkaW8tZ3JvdXBcIiBbKG5nTW9kZWwpXT1cInNlbWFudGljVmVyc2lvblwiIChjaGFuZ2UpPVwib25WZXJzaW9uQ2hhbmdlKClcIj5cbiAgICAgICAgPG1hdC1yYWRpby1idXR0b24gY2xhc3M9XCJhZGYtbmV3LXZlcnNpb24tcmFkaW8tYnV0dG9uXCIgaWQ9XCJhZGYtbmV3LXZlcnNpb24tbWlub3JcIiBbdmFsdWVdPVwiJ21pbm9yJ1wiPlxuICAgICAgICAgICAge3sgJ0FERl9WRVJTSU9OX0xJU1QuQUNUSU9OUy5VUExPQUQuTUlOT1InIHwgdHJhbnNsYXRlOiB7IHZlcnNpb246IG1pbm9yVmVyc2lvbiB9IH19XG4gICAgICAgIDwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICAgICAgPG1hdC1yYWRpby1idXR0b24gY2xhc3M9XCJhZGYtbmV3LXZlcnNpb24tcmFkaW8tYnV0dG9uXCIgaWQ9XCJhZGYtbmV3LXZlcnNpb24tbWFqb3JcIiBbdmFsdWVdPVwiJ21ham9yJ1wiPlxuICAgICAgICAgICAge3sgJ0FERl9WRVJTSU9OX0xJU1QuQUNUSU9OUy5VUExPQUQuTUFKT1InIHwgdHJhbnNsYXRlOiB7IHZlcnNpb246IG1ham9yVmVyc2lvbiB9IH19XG4gICAgICAgIDwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICA8L21hdC1yYWRpby1ncm91cD5cbiAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJhZGYtbmV3LXZlcnNpb24tbWF4LXdpZHRoXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiPlxuICAgICAgICA8bWF0LWxhYmVsPnt7J0FERl9WRVJTSU9OX0xJU1QuQUNUSU9OUy5VUExPQUQuQ09NTUVOVCcgfCB0cmFuc2xhdGV9fTwvbWF0LWxhYmVsPlxuICAgICAgICA8dGV4dGFyZWEgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29tbWVudFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImFkZi1uZXctdmVyc2lvbi10ZXh0LWFyZWFcIiBpZD1cImFkZi1uZXctdmVyc2lvbi10ZXh0LWFyZWFcIlxuICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkNvbW1lbnRDaGFuZ2UoKVwiPjwvdGV4dGFyZWE+XG4gICAgPC9tYXQtZm9ybS1maWVsZD5cbjwvZGl2PlxuPGRpdiBjbGFzcz1cImFkZi12ZXJzaW9uLXVwbG9hZC1idXR0b25zXCI+XG4gICAgPGFkZi11cGxvYWQtdmVyc2lvbi1idXR0b24gKm5nSWY9XCJzaG93VXBsb2FkQnV0dG9uXCJcbiAgICAgICAgZGF0YS1hdXRvbWF0aW9uLWlkPVwiYWRmLW5ldy12ZXJzaW9uLWZpbGUtdXBsb2FkXCJcbiAgICAgICAgc3RhdGljVGl0bGU9XCJ7eyAnQURGX1ZFUlNJT05fTElTVC5BQ1RJT05TLlVQTE9BRC5USVRMRScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICBbbm9kZV09XCJub2RlXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cIiFjYW5VcGxvYWQoKVwiXG4gICAgICAgIFtyb290Rm9sZGVySWRdPVwibm9kZS5wYXJlbnRJZFwiXG4gICAgICAgIHRvb2x0aXA9XCJ7eyAnQURGX1ZFUlNJT05fTElTVC5BQ1RJT05TLlVQTE9BRC5UT09MVElQJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgIFtjb21tZW50XT1cImNvbW1lbnRcIlxuICAgICAgICBbdmVyc2lvbmluZ109XCJ0cnVlXCJcbiAgICAgICAgW2ZpbGVdPVwibmV3RmlsZVZlcnNpb25cIlxuICAgICAgICBbbWFqb3JWZXJzaW9uXT1cImlzTWFqb3JWZXJzaW9uKClcIlxuICAgICAgICAoc3VjY2Vzcyk9XCJvblN1Y2Nlc3MoJGV2ZW50KVwiXG4gICAgICAgIChlcnJvcik9XCJvbkVycm9yKCRldmVudClcIiAvPlxuICAgIDxidXR0b24gbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cImNhbmNlbFVwbG9hZCgpXCIgaWQ9XCJhZGYtbmV3LXZlcnNpb24tY2FuY2VsXCIgICpuZ0lmPVwic2hvd0NhbmNlbEJ1dHRvblwiID57e1xuICAgICAgICAnQURGX1ZFUlNJT05fTElTVC5BQ1RJT05TLlVQTE9BRC5DQU5DRUwnfCB0cmFuc2xhdGUgfX1cbiAgICA8L2J1dHRvbj5cbjwvZGl2PlxuIl19