@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
139 lines • 33.7 kB
JavaScript
import { Component, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { GainsightService, PluginsService, ViewContext, WizardComponent, gettext } from '@c8y/ngx-components';
import { ApplicationPropertiesFormComponent, EcosystemService, PRODUCT_EXPERIENCE_ECOSYSTEM } from '@c8y/ngx-components/ecosystem/shared';
import { TranslateService } from '@ngx-translate/core';
import { pick } from 'lodash-es';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components/ecosystem/shared";
import * as i2 from "@c8y/ngx-components";
import * as i3 from "@ngx-translate/core";
import * as i4 from "@angular/router";
import * as i5 from "@angular/common";
import * as i6 from "@angular/forms";
export class DeployApplicationComponent {
constructor(ecosystemService, wizardComponent, translate, pluginService, gainsightService, router) {
this.ecosystemService = ecosystemService;
this.wizardComponent = wizardComponent;
this.translate = translate;
this.pluginService = pluginService;
this.gainsightService = gainsightService;
this.router = router;
this.CURRENT_LOCATION = location.href;
this.inProgress = true;
this.isDeployed = false;
this.deployedWithSuccess = false;
this.model = {
selected: undefined,
binary: {
id: undefined
}
};
this.canDeploy = false;
this.descriptionTemplate = gettext('Deploy application using "{{ packageName }}" package');
this.successMessageTemplate = gettext('Application "{{ packageName }}" created');
this.doneLabel = gettext('Done');
this.cancelLabel = gettext('Cancel');
this.package = this.wizardComponent.package;
}
async ngOnInit() {
const apps = await this.ecosystemService.getHostedAndPackageApplications();
this.newAppConfig = this.ecosystemService.getUniqueAppConfig(this.package, apps);
this.headerText = this.getHeaderText();
this.inProgress = false;
}
async deployApp() {
this.inProgress = true;
const formGroupValue = this.applicationPropertiesForm.formGroup.getRawValue();
// Verify if selected package version is compatible with current platform versions.
this.package.manifest.version = this.model.selected.version;
const verifyVersionCompatibility = await this.ecosystemService.verifyBlueprintVersionsCompatibility(this.package.manifest);
if (!verifyVersionCompatibility) {
this.cancel();
return;
}
const { contextPath, license, name, manifest } = this.package;
const type = this.pluginService.getPackageType(this.package);
const licensedApp = {
contextPath,
license: license || manifest.license,
name,
type,
version: this.model.selected.version
};
const isArchived = await this.ecosystemService.verifyArchived([licensedApp]);
if (!isArchived) {
this.cancel();
return;
}
const licensesVerifiedByUser = await this.ecosystemService.verifyLicenses([licensedApp]);
if (!licensesVerifiedByUser) {
this.cancel();
return;
}
try {
this.deployedApp = await this.ecosystemService.deployApp(this.package, formGroupValue, this.model);
const applicationCustomEventInfo = pick(this.package, [
'id',
'name',
'contextPath',
'label',
'key'
]);
this.deployedWithSuccess = true;
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.DEPLOY_APPLICATION, {
component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.DEPLOY_APPLICATION,
action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION,
result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.DEPLOYED,
url: this.CURRENT_LOCATION,
...applicationCustomEventInfo,
package: this.deployedApp?.manifest?.package ?? null
});
}
catch (error) {
this.ecosystemService.alertError(error);
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.DEPLOY_APPLICATION, {
component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.DEPLOY_APPLICATION,
action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION,
result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SERVER_FAILURE,
url: this.CURRENT_LOCATION,
error
});
}
finally {
this.markAsDeployed();
}
}
cancel() {
this.wizardComponent.close();
}
onAppVersionSelect(appVersion) {
Object.assign(this.model, {
selected: appVersion
});
this.canDeploy = true;
}
open() {
this.router.navigateByUrl(ViewContext.Application.replace(':id', `${this.deployedApp.id}`));
this.cancel();
}
markAsDeployed() {
this.isDeployed = true;
this.inProgress = false;
}
getHeaderText() {
return this.translate.instant(this.descriptionTemplate, {
packageName: this.package.name
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DeployApplicationComponent, deps: [{ token: i1.EcosystemService }, { token: i2.WizardComponent }, { token: i3.TranslateService }, { token: i2.PluginsService }, { token: i2.GainsightService }, { token: i4.Router }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DeployApplicationComponent, selector: "c8y-deploy-application", viewQueries: [{ propertyName: "applicationPropertiesForm", first: true, predicate: ApplicationPropertiesFormComponent, descendants: true }], ngImport: i0, template: "<c8y-wizard-header>\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"output\"></i>\n <h4 id=\"modal-title\">{{ 'Deploy application' | translate }}</h4>\n </div>\n</c8y-wizard-header>\n\n<c8y-wizard-body id=\"modal-body\">\n <ng-container *ngIf=\"!isDeployed\">\n <div class=\"fadeIn animated d-flex a-i-center j-c-center d-col\" style=\"min-height: 309px\">\n <p\n class=\"bg-level-0 fit-w p-16 text-center text-medium sticky-top bg-level-0 separator-bottom\"\n *ngIf=\"!inProgress\"\n >\n {{ headerText | translate }}\n </p>\n <c8y-application-properties-form\n *ngIf=\"!inProgress\"\n [application]=\"newAppConfig\"\n class=\"d-block fit-w bg-level-1\"\n ></c8y-application-properties-form>\n\n <ng-container *ngIf=\"!inProgress\">\n <div [ngStyle]=\"{ padding: '0 16px' }\" class=\"d-block fit-w bg-gray-white\">\n <c8y-package-version-select\n [ngModel]=\"model.selected\"\n (ngModelChange)=\"onAppVersionSelect($event)\"\n [packageId]=\"package?.id\"\n [label]=\"'Use extension package version' | translate\"\n ></c8y-package-version-select>\n </div>\n </ng-container>\n\n <c8y-loading\n *ngIf=\"inProgress\"\n [message]=\"'Deploying\u2026' | translate\"\n class=\"text-center\"\n layout=\"application\"\n ></c8y-loading>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"isDeployed\">\n <div\n *ngIf=\"deployedWithSuccess; else failedDeploy\"\n class=\"modal-body fadeIn animated\"\n style=\"min-height: 309px\"\n >\n <div class=\"d-flex a-i-center j-c-center d-col\">\n <c8y-operation-result\n type=\"success\"\n [size]=\"84\"\n [vertical]=\"true\"\n [text]=\"successMessageTemplate | translate: { packageName: package.name }\"\n class=\"lead d-block m-b-16\"\n ></c8y-operation-result>\n </div>\n </div>\n <ng-template #failedDeploy>\n <div class=\"modal-body fadeIn animated text-center\" style=\"min-height: 257px\">\n <c8y-operation-result\n type=\"error\"\n [size]=\"84\"\n [vertical]=\"true\"\n text=\"{{ 'Application creation failed' | translate }}\"\n class=\"lead\"\n ></c8y-operation-result>\n </div>\n </ng-template>\n </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n <button\n (click)=\"cancel()\"\n type=\"button\"\n class=\"btn btn-default\"\n data-cy=\"c8y-deploy-application--cancel-blueprint-button\"\n title=\"{{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\"\n >\n {{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\n </button>\n\n <button\n (click)=\"deployApp()\"\n *ngIf=\"!isDeployed\"\n [disabled]=\"inProgress || !canDeploy\"\n [ngClass]=\"{ 'btn-pending': inProgress }\"\n class=\"btn btn-primary\"\n type=\"button\"\n data-cy=\"c8y-deploy-application--deploy-blueprint-button\"\n title=\"{{ 'Deploy' | translate }}\"\n >\n {{ 'Deploy' | translate }}\n </button>\n\n <button\n (click)=\"open()\"\n type=\"button\"\n class=\"btn btn-primary\"\n *ngIf=\"isDeployed && deployedWithSuccess\"\n title=\"{{ 'Open the application details' | translate }}\"\n translate\n >\n Open\n </button>\n</c8y-wizard-footer>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i2.OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.WizardHeaderComponent, selector: "c8y-wizard-header" }, { kind: "component", type: i2.WizardBodyComponent, selector: "c8y-wizard-body" }, { kind: "component", type: i2.WizardFooterComponent, selector: "c8y-wizard-footer" }, { kind: "component", type: i1.ApplicationPropertiesFormComponent, selector: "c8y-application-properties-form", inputs: ["application", "disabled"] }, { kind: "component", type: i1.PackageVersionSelectComponent, selector: "c8y-package-version-select", inputs: ["label", "packageContextPath", "packageId"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DeployApplicationComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-deploy-application', template: "<c8y-wizard-header>\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"output\"></i>\n <h4 id=\"modal-title\">{{ 'Deploy application' | translate }}</h4>\n </div>\n</c8y-wizard-header>\n\n<c8y-wizard-body id=\"modal-body\">\n <ng-container *ngIf=\"!isDeployed\">\n <div class=\"fadeIn animated d-flex a-i-center j-c-center d-col\" style=\"min-height: 309px\">\n <p\n class=\"bg-level-0 fit-w p-16 text-center text-medium sticky-top bg-level-0 separator-bottom\"\n *ngIf=\"!inProgress\"\n >\n {{ headerText | translate }}\n </p>\n <c8y-application-properties-form\n *ngIf=\"!inProgress\"\n [application]=\"newAppConfig\"\n class=\"d-block fit-w bg-level-1\"\n ></c8y-application-properties-form>\n\n <ng-container *ngIf=\"!inProgress\">\n <div [ngStyle]=\"{ padding: '0 16px' }\" class=\"d-block fit-w bg-gray-white\">\n <c8y-package-version-select\n [ngModel]=\"model.selected\"\n (ngModelChange)=\"onAppVersionSelect($event)\"\n [packageId]=\"package?.id\"\n [label]=\"'Use extension package version' | translate\"\n ></c8y-package-version-select>\n </div>\n </ng-container>\n\n <c8y-loading\n *ngIf=\"inProgress\"\n [message]=\"'Deploying\u2026' | translate\"\n class=\"text-center\"\n layout=\"application\"\n ></c8y-loading>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"isDeployed\">\n <div\n *ngIf=\"deployedWithSuccess; else failedDeploy\"\n class=\"modal-body fadeIn animated\"\n style=\"min-height: 309px\"\n >\n <div class=\"d-flex a-i-center j-c-center d-col\">\n <c8y-operation-result\n type=\"success\"\n [size]=\"84\"\n [vertical]=\"true\"\n [text]=\"successMessageTemplate | translate: { packageName: package.name }\"\n class=\"lead d-block m-b-16\"\n ></c8y-operation-result>\n </div>\n </div>\n <ng-template #failedDeploy>\n <div class=\"modal-body fadeIn animated text-center\" style=\"min-height: 257px\">\n <c8y-operation-result\n type=\"error\"\n [size]=\"84\"\n [vertical]=\"true\"\n text=\"{{ 'Application creation failed' | translate }}\"\n class=\"lead\"\n ></c8y-operation-result>\n </div>\n </ng-template>\n </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n <button\n (click)=\"cancel()\"\n type=\"button\"\n class=\"btn btn-default\"\n data-cy=\"c8y-deploy-application--cancel-blueprint-button\"\n title=\"{{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\"\n >\n {{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\n </button>\n\n <button\n (click)=\"deployApp()\"\n *ngIf=\"!isDeployed\"\n [disabled]=\"inProgress || !canDeploy\"\n [ngClass]=\"{ 'btn-pending': inProgress }\"\n class=\"btn btn-primary\"\n type=\"button\"\n data-cy=\"c8y-deploy-application--deploy-blueprint-button\"\n title=\"{{ 'Deploy' | translate }}\"\n >\n {{ 'Deploy' | translate }}\n </button>\n\n <button\n (click)=\"open()\"\n type=\"button\"\n class=\"btn btn-primary\"\n *ngIf=\"isDeployed && deployedWithSuccess\"\n title=\"{{ 'Open the application details' | translate }}\"\n translate\n >\n Open\n </button>\n</c8y-wizard-footer>\n" }]
}], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.WizardComponent }, { type: i3.TranslateService }, { type: i2.PluginsService }, { type: i2.GainsightService }, { type: i4.Router }], propDecorators: { applicationPropertiesForm: [{
type: ViewChild,
args: [ApplicationPropertiesFormComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95LWFwcGxpY2F0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2Vjb3N5c3RlbS9wYWNrYWdlcy9kZXBsb3ktYXBwbGljYXRpb24vZGVwbG95LWFwcGxpY2F0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2Vjb3N5c3RlbS9wYWNrYWdlcy9kZXBsb3ktYXBwbGljYXRpb24vZGVwbG95LWFwcGxpY2F0aW9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV6QyxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCxXQUFXLEVBQ1gsZUFBZSxFQUNmLE9BQU8sRUFDUixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxrQ0FBa0MsRUFDbEMsZ0JBQWdCLEVBRWhCLDRCQUE0QixFQUM3QixNQUFNLHNDQUFzQyxDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7Ozs7Ozs7O0FBTWpDLE1BQU0sT0FBTywwQkFBMEI7SUE4QnJDLFlBQ1UsZ0JBQWtDLEVBQ2xDLGVBQWdDLEVBQ2hDLFNBQTJCLEVBQzNCLGFBQTZCLEVBQzdCLGdCQUFrQyxFQUNsQyxNQUFjO1FBTGQscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUFDM0Isa0JBQWEsR0FBYixhQUFhLENBQWdCO1FBQzdCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtR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Q0FBa0MsZ0RDMUMvQyx5NUdBMkdBOzs0RkRwRmEsMEJBQTBCO2tCQUp0QyxTQUFTOytCQUNFLHdCQUF3QjttT0F1QmxDLHlCQUF5QjtzQkFEeEIsU0FBUzt1QkFBQyxrQ0FBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgSUFwcGxpY2F0aW9uLCBJQXBwbGljYXRpb25WZXJzaW9uIH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHtcbiAgR2FpbnNpZ2h0U2VydmljZSxcbiAgUGx1Z2luc1NlcnZpY2UsXG4gIFZpZXdDb250ZXh0LFxuICBXaXphcmRDb21wb25lbnQsXG4gIGdldHRleHRcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvblByb3BlcnRpZXNGb3JtQ29tcG9uZW50LFxuICBFY29zeXN0ZW1TZXJ2aWNlLFxuICBMaWNlbnNlZEFwcGxpY2F0aW9uUGx1Z2luLFxuICBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvZWNvc3lzdGVtL3NoYXJlZCc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBwaWNrIH0gZnJvbSAnbG9kYXNoLWVzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWRlcGxveS1hcHBsaWNhdGlvbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9kZXBsb3ktYXBwbGljYXRpb24uY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIERlcGxveUFwcGxpY2F0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQ1VSUkVOVF9MT0NBVElPTiA9IGxvY2F0aW9uLmhyZWY7XG5cbiAgaW5Qcm9ncmVzcyA9IHRydWU7XG4gIHBhY2thZ2U6IElBcHBsaWNhdGlvbjtcbiAgaXNEZXBsb3llZCA9IGZhbHNlO1xuICBkZXBsb3llZFdpdGhTdWNjZXNzID0gZmFsc2U7XG4gIG5ld0FwcENvbmZpZzogSUFwcGxpY2F0aW9uO1xuICBkZXBsb3llZEFwcDogSUFwcGxpY2F0aW9uO1xuICBhcHBsaWNhdGlvbkhyZWY6IHN0cmluZztcblxuICBtb2RlbCA9IHtcbiAgICBzZWxlY3RlZDogdW5kZWZpbmVkLFxuICAgIGJpbmFyeToge1xuICAgICAgaWQ6IHVuZGVmaW5lZFxuICAgIH1cbiAgfTtcbiAgY2FuRGVwbG95ID0gZmFsc2U7XG5cbiAgQFZpZXdDaGlsZChBcHBsaWNhdGlvblByb3BlcnRpZXNGb3JtQ29tcG9uZW50KVxuICBhcHBsaWNhdGlvblByb3BlcnRpZXNGb3JtOiBBcHBsaWNhdGlvblByb3BlcnRpZXNGb3JtQ29tcG9uZW50O1xuXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uVGVtcGxhdGU6IHN0cmluZyA9IGdldHRleHQoXG4gICAgJ0RlcGxveSBhcHBsaWNhdGlvbiB1c2luZyBcInt7IHBhY2thZ2VOYW1lIH19XCIgcGFja2FnZSdcbiAgKTtcbiAgcmVhZG9ubHkgc3VjY2Vzc01lc3NhZ2VUZW1wbGF0ZSA9IGdldHRleHQoJ0FwcGxpY2F0aW9uIFwie3sgcGFja2FnZU5hbWUgfX1cIiBjcmVhdGVkJyk7XG4gIHJlYWRvbmx5IGRvbmVMYWJlbCA9IGdldHRleHQoJ0RvbmUnKTtcbiAgcmVhZG9ubHkgY2FuY2VsTGFiZWwgPSBnZXR0ZXh0KCdDYW5jZWwnKTtcbiAgaGVhZGVyVGV4dDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWNvc3lzdGVtU2VydmljZTogRWNvc3lzdGVtU2VydmljZSxcbiAgICBwcml2YXRlIHdpemFyZENvbXBvbmVudDogV2l6YXJkQ29tcG9uZW50LFxuICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGx1Z2luU2VydmljZTogUGx1Z2luc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBnYWluc2lnaHRTZXJ2aWNlOiBHYWluc2lnaHRTZXJ2aWNlLFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXJcbiAgKSB7XG4gICAgdGhpcy5wYWNrYWdlID0gKHRoaXMud2l6YXJkQ29tcG9uZW50IGFzIGFueSkucGFja2FnZTtcbiAgfVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIGNvbnN0IGFwcHMgPSBhd2FpdCB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuZ2V0SG9zdGVkQW5kUGFja2FnZUFwcGxpY2F0aW9ucygpO1xuICAgIHRoaXMubmV3QXBwQ29uZmlnID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmdldFVuaXF1ZUFwcENvbmZpZyh0aGlzLnBhY2thZ2UsIGFwcHMpO1xuICAgIHRoaXMuaGVhZGVyVGV4dCA9IHRoaXMuZ2V0SGVhZGVyVGV4dCgpO1xuICAgIHRoaXMuaW5Qcm9ncmVzcyA9IGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgZGVwbG95QXBwKCkge1xuICAgIHRoaXMuaW5Qcm9ncmVzcyA9IHRydWU7XG4gICAgY29uc3QgZm9ybUdyb3VwVmFsdWUgPSB0aGlzLmFwcGxpY2F0aW9uUHJvcGVydGllc0Zvcm0uZm9ybUdyb3VwLmdldFJhd1ZhbHVlKCk7XG4gICAgLy8gVmVyaWZ5IGlmIHNlbGVjdGVkIHBhY2thZ2UgdmVyc2lvbiBpcyBjb21wYXRpYmxlIHdpdGggY3VycmVudCBwbGF0Zm9ybSB2ZXJzaW9ucy5cbiAgICB0aGlzLnBhY2thZ2UubWFuaWZlc3QudmVyc2lvbiA9IHRoaXMubW9kZWwuc2VsZWN0ZWQudmVyc2lvbjtcbiAgICBjb25zdCB2ZXJpZnlWZXJzaW9uQ29tcGF0aWJpbGl0eSA9XG4gICAgICBhd2FpdCB0aGlzLmVjb3N5c3RlbVNlcnZpY2UudmVyaWZ5Qmx1ZXByaW50VmVyc2lvbnNDb21wYXRpYmlsaXR5KHRoaXMucGFja2FnZS5tYW5pZmVzdCk7XG5cbiAgICBpZiAoIXZlcmlmeVZlcnNpb25Db21wYXRpYmlsaXR5KSB7XG4gICAgICB0aGlzLmNhbmNlbCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29udGV4dFBhdGgsIGxpY2Vuc2UsIG5hbWUsIG1hbmlmZXN0IH0gPSB0aGlzLnBhY2thZ2U7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMucGx1Z2luU2VydmljZS5nZXRQYWNrYWdlVHlwZSh0aGlzLnBhY2thZ2UpO1xuICAgIGNvbnN0IGxpY2Vuc2VkQXBwOiBMaWNlbnNlZEFwcGxpY2F0aW9uUGx1Z2luID0ge1xuICAgICAgY29udGV4dFBhdGgsXG4gICAgICBsaWNlbnNlOiBsaWNlbnNlIHx8IG1hbmlmZXN0LmxpY2Vuc2UsXG4gICAgICBuYW1lLFxuICAgICAgdHlwZSxcbiAgICAgIHZlcnNpb246IHRoaXMubW9kZWwuc2VsZWN0ZWQudmVyc2lvblxuICAgIH07XG5cbiAgICBjb25zdCBpc0FyY2hpdmVkID0gYXdhaXQgdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLnZlcmlmeUFyY2hpdmVkKFtsaWNlbnNlZEFwcF0pO1xuICAgIGlmICghaXNBcmNoaXZlZCkge1xuICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsaWNlbnNlc1ZlcmlmaWVkQnlVc2VyID0gYXdhaXQgdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLnZlcmlmeUxpY2Vuc2VzKFtsaWNlbnNlZEFwcF0pO1xuICAgIGlmICghbGljZW5zZXNWZXJpZmllZEJ5VXNlcikge1xuICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5kZXBsb3llZEFwcCA9IGF3YWl0IHRoaXMuZWNvc3lzdGVtU2VydmljZS5kZXBsb3lBcHAoXG4gICAgICAgIHRoaXMucGFja2FnZSxcbiAgICAgICAgZm9ybUdyb3VwVmFsdWUsXG4gICAgICAgIHRoaXMubW9kZWxcbiAgICAgICk7XG4gICAgICBjb25zdCBhcHBsaWNhdGlvbkN1c3RvbUV2ZW50SW5mbyA9IHBpY2sodGhpcy5wYWNrYWdlLCBbXG4gICAgICAgICdpZCcsXG4gICAgICAgICduYW1lJyxcbiAgICAgICAgJ2NvbnRleHRQYXRoJyxcbiAgICAgICAgJ2xhYmVsJyxcbiAgICAgICAgJ2tleSdcbiAgICAgIF0gc2F0aXNmaWVzIChrZXlvZiBJQXBwbGljYXRpb24pW10pO1xuXG4gICAgICB0aGlzLmRlcGxveWVkV2l0aFN1Y2Nlc3MgPSB0cnVlO1xuICAgICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyaWdnZXJFdmVudChcbiAgICAgICAgUFJPRFVDVF9FWFBFUklFTkNFX0VDT1NZU1RFTS5BUFBMSUNBVElPTlMuRVZFTlRTLkRFUExPWV9BUFBMSUNBVElPTixcbiAgICAgICAge1xuICAgICAgICAgIGNvbXBvbmVudDogUFJPRFVDVF9FWFBFUklFTkNFX0VDT1NZU1RFTS5BUFBMSUNBVElPTlMuQ09NUE9ORU5UUy5ERVBMT1lfQVBQTElDQVRJT04sXG4gICAgICAgICAgYWN0aW9uOiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5BQ1RJT05TLkRFUExPWV9BUFBMSUNBVElPTixcbiAgICAgICAgICByZXN1bHQ6IFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLlJFU1VMVFMuREVQTE9ZRUQsXG4gICAgICAgICAgdXJsOiB0aGlzLkNVUlJFTlRfTE9DQVRJT04sXG4gICAgICAgICAgLi4uYXBwbGljYXRpb25DdXN0b21FdmVudEluZm8sXG4gICAgICAgICAgcGFja2FnZTogdGhpcy5kZXBsb3llZEFwcD8ubWFuaWZlc3Q/LnBhY2thZ2UgPz8gbnVsbFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuYWxlcnRFcnJvcihlcnJvcik7XG4gICAgICB0aGlzLmdhaW5zaWdodFNlcnZpY2UudHJpZ2dlckV2ZW50KFxuICAgICAgICBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5FVkVOVFMuREVQTE9ZX0FQUExJQ0FUSU9OLFxuICAgICAgICB7XG4gICAgICAgICAgY29tcG9uZW50OiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5DT01QT05FTlRTLkRFUExPWV9BUFBMSUNBVElPTixcbiAgICAgICAgICBhY3Rpb246IFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU0uQVBQTElDQVRJT05TLkFDVElPTlMuREVQTE9ZX0FQUExJQ0FUSU9OLFxuICAgICAgICAgIHJlc3VsdDogUFJPRFVDVF9FWFBFUklFTkNFX0VDT1NZU1RFTS5BUFBMSUNBVElPTlMuUkVTVUxUUy5TRVJWRVJfRkFJTFVSRSxcbiAgICAgICAgICB1cmw6IHRoaXMuQ1VSUkVOVF9MT0NBVElPTixcbiAgICAgICAgICBlcnJvclxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLm1hcmtBc0RlcGxveWVkKCk7XG4gICAgfVxuICB9XG5cbiAgY2FuY2VsKCkge1xuICAgIHRoaXMud2l6YXJkQ29tcG9uZW50LmNsb3NlKCk7XG4gIH1cblxuICBvbkFwcFZlcnNpb25TZWxlY3QoYXBwVmVyc2lvbjogSUFwcGxpY2F0aW9uVmVyc2lvbikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5tb2RlbCwge1xuICAgICAgc2VsZWN0ZWQ6IGFwcFZlcnNpb25cbiAgICB9KTtcbiAgICB0aGlzLmNhbkRlcGxveSA9IHRydWU7XG4gIH1cblxuICBvcGVuKCkge1xuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwoVmlld0NvbnRleHQuQXBwbGljYXRpb24ucmVwbGFjZSgnOmlkJywgYCR7dGhpcy5kZXBsb3llZEFwcC5pZH1gKSk7XG4gICAgdGhpcy5jYW5jZWwoKTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya0FzRGVwbG95ZWQoKSB7XG4gICAgdGhpcy5pc0RlcGxveWVkID0gdHJ1ZTtcbiAgICB0aGlzLmluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SGVhZGVyVGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2xhdGUuaW5zdGFudCh0aGlzLmRlc2NyaXB0aW9uVGVtcGxhdGUsIHtcbiAgICAgIHBhY2thZ2VOYW1lOiB0aGlzLnBhY2thZ2UubmFtZVxuICAgIH0pO1xuICB9XG59XG4iLCI8Yzh5LXdpemFyZC1oZWFkZXI+XG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXIgZGlhbG9nLWhlYWRlclwiPlxuICAgIDxpIGM4eUljb249XCJvdXRwdXRcIj48L2k+XG4gICAgPGg0IGlkPVwibW9kYWwtdGl0bGVcIj57eyAnRGVwbG95IGFwcGxpY2F0aW9uJyB8IHRyYW5zbGF0ZSB9fTwvaDQ+XG4gIDwvZGl2PlxuPC9jOHktd2l6YXJkLWhlYWRlcj5cblxuPGM4eS13aXphcmQtYm9keSBpZD1cIm1vZGFsLWJvZHlcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0RlcGxveWVkXCI+XG4gICAgPGRpdiBjbGFzcz1cImZhZGVJbiBhbmltYXRlZCBkLWZsZXggYS1pLWNlbnRlciBqLWMtY2VudGVyIGQtY29sXCIgc3R5bGU9XCJtaW4taGVpZ2h0OiAzMDlweFwiPlxuICAgICAgPHBcbiAgICAgICAgY2xhc3M9XCJiZy1sZXZlbC0wIGZpdC13IHAtMTYgdGV4dC1jZW50ZXIgdGV4dC1tZWRpdW0gc3RpY2t5LXRvcCBiZy1sZXZlbC0wIHNlcGFyYXRvci1ib3R0b21cIlxuICAgICAgICAqbmdJZj1cIiFpblByb2dyZXNzXCJcbiAgICAgID5cbiAgICAgICAge3sgaGVhZGVyVGV4dCB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9wPlxuICAgICAgPGM4eS1hcHBsaWNhdGlvbi1wcm9wZXJ0aWVzLWZvcm1cbiAgICAgICAgKm5nSWY9XCIhaW5Qcm9ncmVzc1wiXG4gICAgICAgIFthcHBsaWNhdGlvbl09XCJuZXdBcHBDb25maWdcIlxuICAgICAgICBjbGFzcz1cImQtYmxvY2sgZml0LXcgYmctbGV2ZWwtMVwiXG4gICAgICA+PC9jOHktYXBwbGljYXRpb24tcHJvcGVydGllcy1mb3JtPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWluUHJvZ3Jlc3NcIj5cbiAgICAgICAgPGRpdiBbbmdTdHlsZV09XCJ7IHBhZGRpbmc6ICcwIDE2cHgnIH1cIiBjbGFzcz1cImQtYmxvY2sgZml0LXcgYmctZ3JheS13aGl0ZVwiPlxuICAgICAgICAgIDxjOHktcGFja2FnZS12ZXJzaW9uLXNlbGVjdFxuICAgICAgICAgICAgW25nTW9kZWxdPVwibW9kZWwuc2VsZWN0ZWRcIlxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25BcHBWZXJzaW9uU2VsZWN0KCRldmVudClcIlxuICAgICAgICAgICAgW3BhY2thZ2VJZF09XCJwYWNrYWdlPy5pZFwiXG4gICAgICAgICAgICBbbGFiZWxdPVwiJ1VzZSBleHRlbnNpb24gcGFja2FnZSB2ZXJzaW9uJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgPjwvYzh5LXBhY2thZ2UtdmVyc2lvbi1zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxjOHktbG9hZGluZ1xuICAgICAgICAqbmdJZj1cImluUHJvZ3Jlc3NcIlxuICAgICAgICBbbWVzc2FnZV09XCInRGVwbG95aW5n4oCmJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIGNsYXNzPVwidGV4dC1jZW50ZXJcIlxuICAgICAgICBsYXlvdXQ9XCJhcHBsaWNhdGlvblwiXG4gICAgICA+PC9jOHktbG9hZGluZz5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzRGVwbG95ZWRcIj5cbiAgICA8ZGl2XG4gICAgICAqbmdJZj1cImRlcGxveWVkV2l0aFN1Y2Nlc3M7IGVsc2UgZmFpbGVkRGVwbG95XCJcbiAgICAgIGNsYXNzPVwibW9kYWwtYm9keSBmYWRlSW4gYW5pbWF0ZWRcIlxuICAgICAgc3R5bGU9XCJtaW4taGVpZ2h0OiAzMDlweFwiXG4gICAgPlxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyIGotYy1jZW50ZXIgZC1jb2xcIj5cbiAgICAgICAgPGM4eS1vcGVyYXRpb24tcmVzdWx0XG4gICAgICAgICAgdHlwZT1cInN1Y2Nlc3NcIlxuICAgICAgICAgIFtzaXplXT1cIjg0XCJcbiAgICAgICAgICBbdmVydGljYWxdPVwidHJ1ZVwiXG4gICAgICAgICAgW3RleHRdPVwic3VjY2Vzc01lc3NhZ2VUZW1wbGF0ZSB8IHRyYW5zbGF0ZTogeyBwYWNrYWdlTmFtZTogcGFja2FnZS5uYW1lIH1cIlxuICAgICAgICAgIGNsYXNzPVwibGVhZCBkLWJsb2NrIG0tYi0xNlwiXG4gICAgICAgID48L2M4eS1vcGVyYXRpb24tcmVzdWx0PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPG5nLXRlbXBsYXRlICNmYWlsZWREZXBsb3k+XG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keSBmYWRlSW4gYW5pbWF0ZWQgdGV4dC1jZW50ZXJcIiBzdHlsZT1cIm1pbi1oZWlnaHQ6IDI1N3B4XCI+XG4gICAgICAgIDxjOHktb3BlcmF0aW9uLXJlc3VsdFxuICAgICAgICAgIHR5cGU9XCJlcnJvclwiXG4gICAgICAgICAgW3NpemVdPVwiODRcIlxuICAgICAgICAgIFt2ZXJ0aWNhbF09XCJ0cnVlXCJcbiAgICAgICAgICB0ZXh0PVwie3sgJ0FwcGxpY2F0aW9uIGNyZWF0aW9uIGZhaWxlZCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgIGNsYXNzPVwibGVhZFwiXG4gICAgICAgID48L2M4eS1vcGVyYXRpb24tcmVzdWx0PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9uZy1jb250YWluZXI+XG48L2M4eS13aXphcmQtYm9keT5cblxuPGM4eS13aXphcmQtZm9vdGVyPlxuICA8YnV0dG9uXG4gICAgKGNsaWNrKT1cImNhbmNlbCgpXCJcbiAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICBjbGFzcz1cImJ0biBidG4tZGVmYXVsdFwiXG4gICAgZGF0YS1jeT1cImM4eS1kZXBsb3ktYXBwbGljYXRpb24tLWNhbmNlbC1ibHVlcHJpbnQtYnV0dG9uXCJcbiAgICB0aXRsZT1cInt7IChpc0RlcGxveWVkICYmIGRlcGxveWVkV2l0aFN1Y2Nlc3MgPyBkb25lTGFiZWwgOiBjYW5jZWxMYWJlbCkgfCB0cmFuc2xhdGUgfX1cIlxuICA+XG4gICAge3sgKGlzRGVwbG95ZWQgJiYgZGVwbG95ZWRXaXRoU3VjY2VzcyA/IGRvbmVMYWJlbCA6IGNhbmNlbExhYmVsKSB8IHRyYW5zbGF0ZSB9fVxuICA8L2J1dHRvbj5cblxuICA8YnV0dG9uXG4gICAgKGNsaWNrKT1cImRlcGxveUFwcCgpXCJcbiAgICAqbmdJZj1cIiFpc0RlcGxveWVkXCJcbiAgICBbZGlzYWJsZWRdPVwiaW5Qcm9ncmVzcyB8fCAhY2FuRGVwbG95XCJcbiAgICBbbmdDbGFzc109XCJ7ICdidG4tcGVuZGluZyc6IGluUHJvZ3Jlc3MgfVwiXG4gICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIlxuICAgIHR5cGU9XCJidXR0b25cIlxuICAgIGRhdGEtY3k9XCJjOHktZGVwbG95LWFwcGxpY2F0aW9uLS1kZXBsb3ktYmx1ZXByaW50LWJ1dHRvblwiXG4gICAgdGl0bGU9XCJ7eyAnRGVwbG95JyB8IHRyYW5zbGF0ZSB9fVwiXG4gID5cbiAgICB7eyAnRGVwbG95JyB8IHRyYW5zbGF0ZSB9fVxuICA8L2J1dHRvbj5cblxuICA8YnV0dG9uXG4gICAgKGNsaWNrKT1cIm9wZW4oKVwiXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIlxuICAgICpuZ0lmPVwiaXNEZXBsb3llZCAmJiBkZXBsb3llZFdpdGhTdWNjZXNzXCJcbiAgICB0aXRsZT1cInt7ICdPcGVuIHRoZSBhcHBsaWNhdGlvbiBkZXRhaWxzJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgdHJhbnNsYXRlXG4gID5cbiAgICBPcGVuXG4gIDwvYnV0dG9uPlxuPC9jOHktd2l6YXJkLWZvb3Rlcj5cbiJdfQ==