@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
177 lines • 62.4 kB
JavaScript
import { Component, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { AlertService, gettext, ModalService, Status } from '@c8y/ngx-components';
import { TranslateService } from '@ngx-translate/core';
import { cloneDeep, escapeRegExp, find, head, orderBy } from 'lodash-es';
import { BsModalService } from 'ngx-bootstrap/modal';
import { ConnectionInfoWithDownloadCsvComponent } from './connection-info-with-download-csv.component';
import { ConnectionType } from './multiple-lns-connector.model';
import { MultipleLnsConnectorService } from './multiple-lns-connector.service';
import * as i0 from "@angular/core";
import * as i1 from "./multiple-lns-connector.service";
import * as i2 from "@c8y/ngx-components";
import * as i3 from "@ngx-translate/core";
import * as i4 from "ngx-bootstrap/modal";
import * as i5 from "@angular/common";
import * as i6 from "@angular/forms";
import * as i7 from "./no-connections-found.component";
export class SigfoxMultipleLnsConnectorComponent {
constructor(connectorService, alertService, translateService, modalService, modal) {
this.connectorService = connectorService;
this.alertService = alertService;
this.translateService = translateService;
this.modalService = modalService;
this.modal = modal;
this.state = 'loadingConnection';
this.cloneDeep = cloneDeep;
this.connections = Array();
this.showPassword = false;
this.cardHeader = gettext('Sigfox connections');
this.allowedSpecialCharacters = '~!@$^(){}[]|:,<+=,.`_ -';
this.namePattern = `^[a-zA-Z0-9 ${escapeRegExp(this.allowedSpecialCharacters)}]*$`;
this.namePatternError = this.translateService.instant(gettext('Connection name can only contain letters, numbers, spaces, and the following symbols: {{ symbols }}'), {
symbols: this.allowedSpecialCharacters
});
}
async ngOnInit() {
await this.loadConnections();
}
async loadConnections() {
const res = await this.connectorService.list(ConnectionType.SIGFOX);
if (res && res.status !== 200) {
const data = res.json ? await res.json() : undefined;
this.alertService.addServerFailure({ data, res });
this.state = 'loadingError';
}
else {
const list = await res.json();
this.connections = orderBy(list, ['name'], ['asc']);
await this.setModel();
}
}
async setModel(connectionObj = null) {
const resetConnection = await this.resetEditedUnsavedConnection();
this.connection = connectionObj
? connectionObj
: this.state === 'savedSuccessfully'
? this.connection
: resetConnection ?? cloneDeep(head(this.connections));
this.state = 'updateConnection';
this.showPassword = false;
this.originalConnection = this.connection ? cloneDeep(this.connection) : undefined;
}
async resetEditedUnsavedConnection() {
if (this.state !== 'updateConnection' || !this.originalConnection) {
return;
}
const { name } = this.originalConnection;
const originalData = find(this.connections, { name });
if (originalData) {
return cloneDeep(originalData);
}
}
async addConnection() {
await this.resetEditedUnsavedConnection();
this.connection = {};
this.originalConnection = {};
this.state = 'addConnections';
this.showPassword = true;
}
async save() {
const checkForConnectionName = this.originalConnection && this.originalConnection.name && this.originalConnection.name !== ''
? this.originalConnection.name
: this.connection.name;
const isConnectionExist = await this.connectorService.exists(ConnectionType.SIGFOX, checkForConnectionName);
if (this.state === 'addConnections' && isConnectionExist) {
const mesg = this.translateService.instant(gettext(`Connection with name "{{ name }}" already exists.`), { name: this.connection.name });
this.alertService.danger(mesg);
}
else {
return this.saveConnection();
}
}
async deleteConnection(originalConnection) {
const { name } = originalConnection;
const mesg = this.translateService.instant(gettext(`You are about to delete the connection "{{ name }}". Do you want to proceed?`), { name });
try {
await this.modal.confirm(gettext('Delete connection'), mesg, Status.DANGER, {
ok: gettext('Delete'),
cancel: gettext('Cancel')
});
await this.delete(originalConnection);
}
catch (error) {
// empty catch block
}
}
changePassword() {
this.showPassword = !this.showPassword;
if (this.connectorsForm.controls.password) {
this.connectorsForm.controls.password.setValue(null);
}
}
async saveConnection() {
const res = await this.connectorService.save(this.connection, this.originalConnection?.name);
if (res && (res.status === 201 || res.status === 200)) {
this.state = 'savedSuccessfully';
this.alertService.success(gettext('Connection saved.'));
await this.loadConnections();
}
else if (res && res.status === 500) {
const data = res.json ? await res.json() : undefined;
const app = this.connectorService.getApplication('sigfox-agent');
const initialState = {
messageData: data,
appData: app,
modalTitle: gettext('Failed to update the connection'),
ariaDescribedby: 'modal-body',
ariaLabelledBy: 'modal-title',
connectionName: this.connection.name
};
this.modalService.show(ConnectionInfoWithDownloadCsvComponent, { initialState });
}
else {
const data = res.json ? await res.json() : undefined;
this.alertService.addServerFailure({ data, res });
}
}
async delete(originalConnection) {
try {
const response = await this.connectorService.delete(originalConnection);
if (response.ok && response.status === 204) {
this.alertService.success(gettext('Connection deleted.'));
await this.loadConnections();
}
else if (response && response.status === 500) {
const data = response.json ? await response.json() : undefined;
const app = this.connectorService.getApplication('sigfox-agent');
const initialState = {
messageData: data,
appData: app,
ariaDescribedby: 'modal-body',
ariaLabelledBy: 'modal-title',
modalTitle: gettext('Failed to delete the connection'),
connectionName: originalConnection.name
};
this.modalService.show(ConnectionInfoWithDownloadCsvComponent, { initialState });
}
else {
const data = response.json ? await response.json() : undefined;
this.alertService.addServerFailure({ data, response });
}
}
catch (error) {
// empty catch block
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SigfoxMultipleLnsConnectorComponent, deps: [{ token: i1.MultipleLnsConnectorService }, { token: i2.AlertService }, { token: i3.TranslateService }, { token: i4.BsModalService }, { token: i2.ModalService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SigfoxMultipleLnsConnectorComponent, selector: "sigfox-multiple-lns-connector", viewQueries: [{ propertyName: "connectorsForm", first: true, predicate: ["connectorsForm"], descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"state === 'loadingConnection'; else renderListAndForm\">\n <c8y-loading></c8y-loading>\n</ng-container>\n<c8y-title>{{ 'Connectivity' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'cog'\"\n [label]=\"'Settings' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'cog'\"\n [label]=\"'Connectivity' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'cog'\"\n [label]=\"'Sigfox' | translate\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<ng-template #renderListAndForm>\n <no-connections-found\n (onAction)=\"addConnection()\"\n *ngIf=\"connections.length === 0 && state !== 'addConnections'\"\n [header]=\"cardHeader | translate\"\n ></no-connections-found>\n <div>\n <div\n class=\"card content-fullpage split-view--5-7\"\n *ngIf=\"connections.length !== 0 || state === 'addConnections'\"\n >\n <div class=\"card-header separator grid__col--fullspan\">\n <div class=\"card-title\">{{ cardHeader | translate }}</div>\n </div>\n <div class=\"inner-scroll split-view__list\">\n <div class=\"bg-level-1 flex-grow\">\n <c8y-list-group class=\"nav c8y-nav-stacked\">\n <c8y-li\n class=\"c8y-stacked-item p-0\"\n [class.active]=\"connection.name === connectionBeingEdited\"\n *ngFor=\"let connection of connections; let index = index\"\n (click)=\"setModel(cloneDeep(connection))\"\n >\n <c8y-li-icon [icon]=\"'plug'\"></c8y-li-icon>\n <span title=\"{{ connection.name }}\">\n {{ connection.name }}\n </span>\n </c8y-li>\n\n <c8y-li\n class=\"c8y-nav-stacked active\"\n *ngIf=\"state === 'addConnections'\"\n (click)=\"addConnection()\"\n >\n <c8y-li-icon [icon]=\"'plug'\"></c8y-li-icon>\n {{ 'New connection' | translate }}\n </c8y-li>\n </c8y-list-group>\n </div>\n <div class=\"card-footer separator-top\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Add connection' | translate }}\"\n [disabled]=\"state === 'addConnections'\"\n (click)=\"addConnection()\"\n >\n <i [c8yIcon]=\"'plus-circle'\"></i>\n {{ 'Add connection' | translate }}\n </button>\n </div>\n </div>\n\n <!-- 'split-view__detail--selected' condition needs to be fixed. this is needed so that both columns are visible in tablet format -->\n\n <div\n class=\"inner-scroll split-view__detail\"\n ng-class=\"{ 'split-view__detail--selected': vm.selected && vm.jsonSchemaObjects }\"\n >\n <div class=\"card-header separator visible-sm visible-xs fit-w sticky-top\">\n <button\n class=\"btn btn-clean text-primary\"\n title=\"{{ 'Back' | translate }}\"\n ng-click=\"vm.deselect()\"\n >\n <i [c8yIcon]=\"'chevron-left'\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n </div>\n <form\n class=\"d-contents\"\n #connectorsForm=\"ngForm\"\n >\n <div class=\"flex-grow\">\n <div class=\"card-block large-padding\">\n <c8y-form-group>\n <label for=\"name\">\n {{ 'Name' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"name\"\n name=\"name\"\n type=\"text\"\n required\n [placeholder]=\"'e.g. Sigfox connection' | translate\"\n [(ngModel)]=\"connection.name\"\n [pattern]=\"namePattern\"\n />\n <c8y-messages>\n <c8y-message\n name=\"pattern\"\n [text]=\"namePatternError\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group>\n <label for=\"description\">\n {{ 'Description' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"description\"\n name=\"description\"\n type=\"text\"\n [placeholder]=\"\n 'e.g. This connection has a built-in functionality to\u2026' | translate\n \"\n [(ngModel)]=\"connection.description\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label for=\"baseUrl\">\n {{ 'URL' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"baseUrl\"\n name=\"baseUrl\"\n type=\"text\"\n required\n [placeholder]=\"\n 'e.g. {{ example }}' | translate : { example: 'https://backend.sigfox.com/api' }\n \"\n [(ngModel)]=\"connection.baseUrl\"\n />\n </c8y-form-group>\n <c8y-form-group>\n <label for=\"parentGroupId\">\n {{ 'Parent group ID' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"parentGroupId\"\n name=\"parentGroupId\"\n type=\"text\"\n required\n [placeholder]=\"\n 'e.g. {{ example }}' | translate : { example: '58c1793b9e93a15370f71caa' }\n \"\n [(ngModel)]=\"connection.parentGroupId\"\n pattern=\"[a-z\\d]+\"\n />\n <c8y-messages>\n <c8y-message\n name=\"pattern\"\n text=\"{{ 'Must be a valid Parent group ID' | translate }}\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group>\n <label for=\"username\">\n {{ 'Username' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"username\"\n placeholder=\"{{ 'e.g. joe`LOCALIZE`' | translate }}\"\n name=\"username\"\n type=\"text\"\n required\n [(ngModel)]=\"connection.username\"\n />\n </c8y-form-group>\n <c8y-form-group *ngIf=\"showPassword\">\n <label for=\"password\">\n {{ 'Password' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"password\"\n placeholder=\"{{ 'e.g. my_password' | translate }}\"\n name=\"password\"\n type=\"password\"\n required\n [(ngModel)]=\"connection.password\"\n />\n </c8y-form-group>\n\n <button\n class=\"btn btn-default\"\n name=\"changePassword\"\n type=\"button\"\n *ngIf=\"state === 'updateConnection'\"\n (click)=\"changePassword()\"\n >\n <span\n title=\"{{ 'Change password' | translate }}\"\n *ngIf=\"!showPassword\"\n >\n {{ 'Change password' | translate }}\n </span>\n <span\n title=\"{{ 'Cancel password change' | translate }}\"\n *ngIf=\"showPassword\"\n >\n {{ 'Cancel password change' | translate }}\n </span>\n </button>\n </div>\n </div>\n\n <div class=\"card-footer separator-top\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"setModel()\"\n translate\n >\n Cancel\n </button>\n <button\n class=\"btn btn-danger\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n data-cy=\"sigfox-multiple-lns-connector.component--delete-connectivity\"\n *ngIf=\"state === 'updateConnection'\"\n (click)=\"deleteConnection(originalConnection)\"\n translate\n >\n Delete\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n data-cy=\"sigfox-multiple-lns-connector.component--save-connectivity\"\n type=\"submit\"\n [disabled]=\"!this.connectorsForm.form.valid || this.connectorsForm.form.pristine\"\n (click)=\"save()\"\n translate\n >\n Save\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: i2.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i2.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i2.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i2.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i7.NoConnectionsFoundComponent, selector: "no-connections-found", inputs: ["header"], outputs: ["onAction"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SigfoxMultipleLnsConnectorComponent, decorators: [{
type: Component,
args: [{ selector: 'sigfox-multiple-lns-connector', template: "<ng-container *ngIf=\"state === 'loadingConnection'; else renderListAndForm\">\n <c8y-loading></c8y-loading>\n</ng-container>\n<c8y-title>{{ 'Connectivity' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'cog'\"\n [label]=\"'Settings' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'cog'\"\n [label]=\"'Connectivity' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'cog'\"\n [label]=\"'Sigfox' | translate\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<ng-template #renderListAndForm>\n <no-connections-found\n (onAction)=\"addConnection()\"\n *ngIf=\"connections.length === 0 && state !== 'addConnections'\"\n [header]=\"cardHeader | translate\"\n ></no-connections-found>\n <div>\n <div\n class=\"card content-fullpage split-view--5-7\"\n *ngIf=\"connections.length !== 0 || state === 'addConnections'\"\n >\n <div class=\"card-header separator grid__col--fullspan\">\n <div class=\"card-title\">{{ cardHeader | translate }}</div>\n </div>\n <div class=\"inner-scroll split-view__list\">\n <div class=\"bg-level-1 flex-grow\">\n <c8y-list-group class=\"nav c8y-nav-stacked\">\n <c8y-li\n class=\"c8y-stacked-item p-0\"\n [class.active]=\"connection.name === connectionBeingEdited\"\n *ngFor=\"let connection of connections; let index = index\"\n (click)=\"setModel(cloneDeep(connection))\"\n >\n <c8y-li-icon [icon]=\"'plug'\"></c8y-li-icon>\n <span title=\"{{ connection.name }}\">\n {{ connection.name }}\n </span>\n </c8y-li>\n\n <c8y-li\n class=\"c8y-nav-stacked active\"\n *ngIf=\"state === 'addConnections'\"\n (click)=\"addConnection()\"\n >\n <c8y-li-icon [icon]=\"'plug'\"></c8y-li-icon>\n {{ 'New connection' | translate }}\n </c8y-li>\n </c8y-list-group>\n </div>\n <div class=\"card-footer separator-top\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Add connection' | translate }}\"\n [disabled]=\"state === 'addConnections'\"\n (click)=\"addConnection()\"\n >\n <i [c8yIcon]=\"'plus-circle'\"></i>\n {{ 'Add connection' | translate }}\n </button>\n </div>\n </div>\n\n <!-- 'split-view__detail--selected' condition needs to be fixed. this is needed so that both columns are visible in tablet format -->\n\n <div\n class=\"inner-scroll split-view__detail\"\n ng-class=\"{ 'split-view__detail--selected': vm.selected && vm.jsonSchemaObjects }\"\n >\n <div class=\"card-header separator visible-sm visible-xs fit-w sticky-top\">\n <button\n class=\"btn btn-clean text-primary\"\n title=\"{{ 'Back' | translate }}\"\n ng-click=\"vm.deselect()\"\n >\n <i [c8yIcon]=\"'chevron-left'\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n </div>\n <form\n class=\"d-contents\"\n #connectorsForm=\"ngForm\"\n >\n <div class=\"flex-grow\">\n <div class=\"card-block large-padding\">\n <c8y-form-group>\n <label for=\"name\">\n {{ 'Name' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"name\"\n name=\"name\"\n type=\"text\"\n required\n [placeholder]=\"'e.g. Sigfox connection' | translate\"\n [(ngModel)]=\"connection.name\"\n [pattern]=\"namePattern\"\n />\n <c8y-messages>\n <c8y-message\n name=\"pattern\"\n [text]=\"namePatternError\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group>\n <label for=\"description\">\n {{ 'Description' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"description\"\n name=\"description\"\n type=\"text\"\n [placeholder]=\"\n 'e.g. This connection has a built-in functionality to\u2026' | translate\n \"\n [(ngModel)]=\"connection.description\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label for=\"baseUrl\">\n {{ 'URL' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"baseUrl\"\n name=\"baseUrl\"\n type=\"text\"\n required\n [placeholder]=\"\n 'e.g. {{ example }}' | translate : { example: 'https://backend.sigfox.com/api' }\n \"\n [(ngModel)]=\"connection.baseUrl\"\n />\n </c8y-form-group>\n <c8y-form-group>\n <label for=\"parentGroupId\">\n {{ 'Parent group ID' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"parentGroupId\"\n name=\"parentGroupId\"\n type=\"text\"\n required\n [placeholder]=\"\n 'e.g. {{ example }}' | translate : { example: '58c1793b9e93a15370f71caa' }\n \"\n [(ngModel)]=\"connection.parentGroupId\"\n pattern=\"[a-z\\d]+\"\n />\n <c8y-messages>\n <c8y-message\n name=\"pattern\"\n text=\"{{ 'Must be a valid Parent group ID' | translate }}\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group>\n <label for=\"username\">\n {{ 'Username' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"username\"\n placeholder=\"{{ 'e.g. joe`LOCALIZE`' | translate }}\"\n name=\"username\"\n type=\"text\"\n required\n [(ngModel)]=\"connection.username\"\n />\n </c8y-form-group>\n <c8y-form-group *ngIf=\"showPassword\">\n <label for=\"password\">\n {{ 'Password' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"password\"\n placeholder=\"{{ 'e.g. my_password' | translate }}\"\n name=\"password\"\n type=\"password\"\n required\n [(ngModel)]=\"connection.password\"\n />\n </c8y-form-group>\n\n <button\n class=\"btn btn-default\"\n name=\"changePassword\"\n type=\"button\"\n *ngIf=\"state === 'updateConnection'\"\n (click)=\"changePassword()\"\n >\n <span\n title=\"{{ 'Change password' | translate }}\"\n *ngIf=\"!showPassword\"\n >\n {{ 'Change password' | translate }}\n </span>\n <span\n title=\"{{ 'Cancel password change' | translate }}\"\n *ngIf=\"showPassword\"\n >\n {{ 'Cancel password change' | translate }}\n </span>\n </button>\n </div>\n </div>\n\n <div class=\"card-footer separator-top\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"setModel()\"\n translate\n >\n Cancel\n </button>\n <button\n class=\"btn btn-danger\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n data-cy=\"sigfox-multiple-lns-connector.component--delete-connectivity\"\n *ngIf=\"state === 'updateConnection'\"\n (click)=\"deleteConnection(originalConnection)\"\n translate\n >\n Delete\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n data-cy=\"sigfox-multiple-lns-connector.component--save-connectivity\"\n type=\"submit\"\n [disabled]=\"!this.connectorsForm.form.valid || this.connectorsForm.form.pristine\"\n (click)=\"save()\"\n translate\n >\n Save\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1.MultipleLnsConnectorService }, { type: i2.AlertService }, { type: i3.TranslateService }, { type: i4.BsModalService }, { type: i2.ModalService }], propDecorators: { connectorsForm: [{
type: ViewChild,
args: ['connectorsForm', { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnZm94LW11bHRpcGxlLWxucy1jb25uZWN0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvdG9jb2wtbHB3YW4vbXVsdGlwbGUtbG5zLWNvbm5lY3RvcnMvc2lnZm94LW11bHRpcGxlLWxucy1jb25uZWN0b3IuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vcHJvdG9jb2wtbHB3YW4vbXVsdGlwbGUtbG5zLWNvbm5lY3RvcnMvc2lnZm94LW11bHRpcGxlLWxucy1jb25uZWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0QsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN6RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDdkcsT0FBTyxFQUFFLGNBQWMsRUFBZ0MsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQzs7Ozs7Ozs7O0FBTS9FLE1BQU0sT0FBTyxtQ0FBbUM7SUFtQjlDLFlBQ1UsZ0JBQTZDLEVBQzdDLFlBQTBCLEVBQzFCLGdCQUFrQyxFQUNsQyxZQUE0QixFQUM1QixLQUFtQjtRQUpuQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQTZCO1FBQzdDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWdCO1FBQzVCLFVBQUssR0FBTCxLQUFLLENBQWM7UUF2QjdCLFVBQUssR0FBZSxtQkFBbUIsQ0FBQztRQUN4QyxjQUFTLEdBQUcsU0FBUyxDQUFDO1FBRXRCLGdCQUFXLEdBQUcsS0FBSyxFQUFvQixDQUFDO1FBQ3hDLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRXJCLGVBQVUsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUMzQyw2QkFBd0IsR0FBRyx5QkFBeUIsQ0FBQztRQUNyRCxnQkFBVyxHQUFHLGVBQWUsWUFBWSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUM7UUFDOUUscUJBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FDOUMsT0FBTyxDQUNMLHFHQUFxRyxDQUN0RyxFQUNEO1lBQ0UsT0FBTyxFQUFFLElBQUksQ0FBQyx3QkFBd0I7U0FDdkMsQ0FDRixDQUFDO0lBUUMsQ0FBQztJQUVKLEtBQUssQ0FBQyxRQUFRO1FBQ1osTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlO1FBQ25CLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEUsSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3JELElBQUksQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQztRQUM5QixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNwRCxNQUFNLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBYSxHQUFHLElBQUk7UUFDakMsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztRQUNsRSxJQUFJLENBQUMsVUFBVSxHQUFHLGFBQWE7WUFDN0IsQ0FBQyxDQUFDLGFBQWE7WUFDZixDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxtQkFBbUI7Z0JBQ2xDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVTtnQkFDakIsQ0FBQyxDQUFDLGVBQWUsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxLQUFLLEdBQUcsa0JBQWtCLENBQUM7UUFDaEMsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDMUIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNyRixDQUFDO0lBRUQsS0FBSyxDQUFDLDRCQUE0QjtRQUNoQyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssa0JBQWtCLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNsRSxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDekMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELElBQUksWUFBWSxFQUFFLENBQUM7WUFDakIsT0FBTyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYTtRQUNqQixNQUFNLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBc0IsQ0FBQztRQUN6QyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsRUFBc0IsQ0FBQztRQUNqRCxJQUFJLENBQUMsS0FBSyxHQUFHLGdCQUFnQixDQUFDO1FBQzlCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0lBQzNCLENBQUM7SUFFRCxLQUFLLENBQUMsSUFBSTtRQUNSLE1BQU0sc0JBQXNCLEdBQzFCLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEtBQUssRUFBRTtZQUM1RixDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUk7WUFDOUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1FBQzNCLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUMxRCxjQUFjLENBQUMsTUFBTSxFQUNyQixzQkFBc0IsQ0FDdkIsQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxnQkFBZ0IsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQ3hDLE9BQU8sQ0FBQyxtREFBbUQsQ0FBQyxFQUM1RCxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUMvQixDQUFDO1lBQ0YsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0I7UUFDdkMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLGtCQUFrQixDQUFDO1FBQ3BDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQ3hDLE9BQU8sQ0FBQyw4RUFBOEUsQ0FBQyxFQUN2RixFQUFFLElBQUksRUFBRSxDQUNULENBQUM7UUFFRixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFO2dCQUMxRSxFQUFFLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQztnQkFDckIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUM7YUFDMUIsQ0FBQyxDQUFDO1lBRUgsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBb0I7UUFDdEIsQ0FBQztJQUNILENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDdkMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZELENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLGNBQWM7UUFDMUIsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzdGLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RELElBQUksQ0FBQyxLQUFLLEdBQUcsbUJBQW1CLENBQUM7WUFDakMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztZQUN4RCxNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUMvQixDQUFDO2FBQU0sSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3JELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDakUsTUFBTSxZQUFZLEdBQUc7Z0JBQ25CLFdBQVcsRUFBRSxJQUFJO2dCQUNqQixPQUFPLEVBQUUsR0FBRztnQkFDWixVQUFVLEVBQUUsT0FBTyxDQUFDLGlDQUFpQyxDQUFDO2dCQUN0RCxlQUFlLEVBQUUsWUFBWTtnQkFDN0IsY0FBYyxFQUFFLGFBQWE7Z0JBQzdCLGNBQWMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUk7YUFDckMsQ0FBQztZQUNGLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxFQUFFLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUNuRixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDckQsSUFBSSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0I7UUFDckMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFFeEUsSUFBSSxRQUFRLENBQUMsRUFBRSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUM7Z0JBQzFELE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQy9CLENBQUM7aUJBQU0sSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDL0MsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDL0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDakUsTUFBTSxZQUFZLEdBQUc7b0JBQ25CLFdBQVcsRUFBRSxJQUFJO29CQUNqQixPQUFPLEVBQUUsR0FBRztvQkFDWixlQUFlLEVBQUUsWUFBWTtvQkFDN0IsY0FBYyxFQUFFLGFBQWE7b0JBQzdCLFVBQVUsRUFBRSxPQUFPLENBQUMsaUNBQWlDLENBQUM7b0JBQ3RELGNBQWMsRUFBRSxrQkFBa0IsQ0FBQyxJQUFJO2lCQUN4QyxDQUFDO2dCQUNGLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxFQUFFLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUNuRixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDL0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFvQjtRQUN0QixDQUFDO0lBQ0gsQ0FBQzsrR0E1S1UsbUNBQW1DO21HQUFuQyxtQ0FBbUMsdUxDZGhELG95U0FzUUE7OzRGRHhQYSxtQ0FBbUM7a0JBSi9DLFNBQVM7K0JBQ0UsK0JBQStCO2tOQVNPLGNBQWM7c0JBQTdELFNBQVM7dUJBQUMsZ0JBQWdCLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmdGb3JtIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWxlcnRTZXJ2aWNlLCBnZXR0ZXh0LCBNb2RhbFNlcnZpY2UsIFN0YXR1cyB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgY2xvbmVEZWVwLCBlc2NhcGVSZWdFeHAsIGZpbmQsIGhlYWQsIG9yZGVyQnkgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgQnNNb2RhbFNlcnZpY2UgfSBmcm9tICduZ3gtYm9vdHN0cmFwL21vZGFsJztcbmltcG9ydCB7IENvbm5lY3Rpb25JbmZvV2l0aERvd25sb2FkQ3N2Q29tcG9uZW50IH0gZnJvbSAnLi9jb25uZWN0aW9uLWluZm8td2l0aC1kb3dubG9hZC1jc3YuY29tcG9uZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb25UeXBlLCBMcHdhblN0YXRlLCBTaWdmb3hDb25uZWN0aW9uIH0gZnJvbSAnLi9tdWx0aXBsZS1sbnMtY29ubmVjdG9yLm1vZGVsJztcbmltcG9ydCB7IE11bHRpcGxlTG5zQ29ubmVjdG9yU2VydmljZSB9IGZyb20gJy4vbXVsdGlwbGUtbG5zLWNvbm5lY3Rvci5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2lnZm94LW11bHRpcGxlLWxucy1jb25uZWN0b3InLFxuICB0ZW1wbGF0ZVVybDogJy4vc2lnZm94LW11bHRpcGxlLWxucy1jb25uZWN0b3IuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIFNpZ2ZveE11bHRpcGxlTG5zQ29ubmVjdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgc3RhdGU6IExwd2FuU3RhdGUgPSAnbG9hZGluZ0Nvbm5lY3Rpb24nO1xuICBjbG9uZURlZXAgPSBjbG9uZURlZXA7XG4gIGNvbm5lY3Rpb246IFNpZ2ZveENvbm5lY3Rpb247XG4gIGNvbm5lY3Rpb25zID0gQXJyYXk8U2lnZm94Q29ubmVjdGlvbj4oKTtcbiAgc2hvd1Bhc3N3b3JkID0gZmFsc2U7XG4gIEBWaWV3Q2hpbGQoJ2Nvbm5lY3RvcnNGb3JtJywgeyBzdGF0aWM6IGZhbHNlIH0pIGNvbm5lY3RvcnNGb3JtOiBOZ0Zvcm07XG4gIGNhcmRIZWFkZXIgPSBnZXR0ZXh0KCdTaWdmb3ggY29ubmVjdGlvbnMnKTtcbiAgYWxsb3dlZFNwZWNpYWxDaGFyYWN0ZXJzID0gJ34hQCReKCl7fVtdfDosPCs9LC5gXyAtJztcbiAgbmFtZVBhdHRlcm4gPSBgXlthLXpBLVowLTkgJHtlc2NhcGVSZWdFeHAodGhpcy5hbGxvd2VkU3BlY2lhbENoYXJhY3RlcnMpfV0qJGA7XG4gIG5hbWVQYXR0ZXJuRXJyb3IgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICBnZXR0ZXh0KFxuICAgICAgJ0Nvbm5lY3Rpb24gbmFtZSBjYW4gb25seSBjb250YWluIGxldHRlcnMsIG51bWJlcnMsIHNwYWNlcywgYW5kIHRoZSBmb2xsb3dpbmcgc3ltYm9sczoge3sgc3ltYm9scyB9fSdcbiAgICApLFxuICAgIHtcbiAgICAgIHN5bWJvbHM6IHRoaXMuYWxsb3dlZFNwZWNpYWxDaGFyYWN0ZXJzXG4gICAgfVxuICApO1xuICBvcmlnaW5hbENvbm5lY3Rpb246IFNpZ2ZveENvbm5lY3Rpb247XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY29ubmVjdG9yU2VydmljZTogTXVsdGlwbGVMbnNDb25uZWN0b3JTZXJ2aWNlLFxuICAgIHByaXZhdGUgYWxlcnRTZXJ2aWNlOiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgbW9kYWxTZXJ2aWNlOiBCc01vZGFsU2VydmljZSxcbiAgICBwcml2YXRlIG1vZGFsOiBNb2RhbFNlcnZpY2VcbiAgKSB7fVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIGF3YWl0IHRoaXMubG9hZENvbm5lY3Rpb25zKCk7XG4gIH1cblxuICBhc3luYyBsb2FkQ29ubmVjdGlvbnMoKSB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5jb25uZWN0b3JTZXJ2aWNlLmxpc3QoQ29ubmVjdGlvblR5cGUuU0lHRk9YKTtcbiAgICBpZiAocmVzICYmIHJlcy5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgY29uc3QgZGF0YSA9IHJlcy5qc29uID8gYXdhaXQgcmVzLmpzb24oKSA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZFNlcnZlckZhaWx1cmUoeyBkYXRhLCByZXMgfSk7XG4gICAgICB0aGlzLnN0YXRlID0gJ2xvYWRpbmdFcnJvcic7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGxpc3QgPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgdGhpcy5jb25uZWN0aW9ucyA9IG9yZGVyQnkobGlzdCwgWyduYW1lJ10sIFsnYXNjJ10pO1xuICAgICAgYXdhaXQgdGhpcy5zZXRNb2RlbCgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNldE1vZGVsKGNvbm5lY3Rpb25PYmogPSBudWxsKSB7XG4gICAgY29uc3QgcmVzZXRDb25uZWN0aW9uID0gYXdhaXQgdGhpcy5yZXNldEVkaXRlZFVuc2F2ZWRDb25uZWN0aW9uKCk7XG4gICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbk9ialxuICAgICAgPyBjb25uZWN0aW9uT2JqXG4gICAgICA6IHRoaXMuc3RhdGUgPT09ICdzYXZlZFN1Y2Nlc3NmdWxseSdcbiAgICAgICAgPyB0aGlzLmNvbm5lY3Rpb25cbiAgICAgICAgOiByZXNldENvbm5lY3Rpb24gPz8gY2xvbmVEZWVwKGhlYWQodGhpcy5jb25uZWN0aW9ucykpO1xuICAgIHRoaXMuc3RhdGUgPSAndXBkYXRlQ29ubmVjdGlvbic7XG4gICAgdGhpcy5zaG93UGFzc3dvcmQgPSBmYWxzZTtcbiAgICB0aGlzLm9yaWdpbmFsQ29ubmVjdGlvbiA9IHRoaXMuY29ubmVjdGlvbiA/IGNsb25lRGVlcCh0aGlzLmNvbm5lY3Rpb24pIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgYXN5bmMgcmVzZXRFZGl0ZWRVbnNhdmVkQ29ubmVjdGlvbigpOiBQcm9taXNlPFNpZ2ZveENvbm5lY3Rpb24gfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAodGhpcy5zdGF0ZSAhPT0gJ3VwZGF0ZUNvbm5lY3Rpb24nIHx8ICF0aGlzLm9yaWdpbmFsQ29ubmVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbmFtZSB9ID0gdGhpcy5vcmlnaW5hbENvbm5lY3Rpb247XG4gICAgY29uc3Qgb3JpZ2luYWxEYXRhID0gZmluZCh0aGlzLmNvbm5lY3Rpb25zLCB7IG5hbWUgfSk7XG4gICAgaWYgKG9yaWdpbmFsRGF0YSkge1xuICAgICAgcmV0dXJuIGNsb25lRGVlcChvcmlnaW5hbERhdGEpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGFkZENvbm5lY3Rpb24oKSB7XG4gICAgYXdhaXQgdGhpcy5yZXNldEVkaXRlZFVuc2F2ZWRDb25uZWN0aW9uKCk7XG4gICAgdGhpcy5jb25uZWN0aW9uID0ge30gYXMgU2lnZm94Q29ubmVjdGlvbjtcbiAgICB0aGlzLm9yaWdpbmFsQ29ubmVjdGlvbiA9IHt9IGFzIFNpZ2ZveENvbm5lY3Rpb247XG4gICAgdGhpcy5zdGF0ZSA9ICdhZGRDb25uZWN0aW9ucyc7XG4gICAgdGhpcy5zaG93UGFzc3dvcmQgPSB0cnVlO1xuICB9XG5cbiAgYXN5bmMgc2F2ZSgpIHtcbiAgICBjb25zdCBjaGVja0ZvckNvbm5lY3Rpb25OYW1lID1cbiAgICAgIHRoaXMub3JpZ2luYWxDb25uZWN0aW9uICYmIHRoaXMub3JpZ2luYWxDb25uZWN0aW9uLm5hbWUgJiYgdGhpcy5vcmlnaW5hbENvbm5lY3Rpb24ubmFtZSAhPT0gJydcbiAgICAgICAgPyB0aGlzLm9yaWdpbmFsQ29ubmVjdGlvbi5uYW1lXG4gICAgICAgIDogdGhpcy5jb25uZWN0aW9uLm5hbWU7XG4gICAgY29uc3QgaXNDb25uZWN0aW9uRXhpc3QgPSBhd2FpdCB0aGlzLmNvbm5lY3RvclNlcnZpY2UuZXhpc3RzKFxuICAgICAgQ29ubmVjdGlvblR5cGUuU0lHRk9YLFxuICAgICAgY2hlY2tGb3JDb25uZWN0aW9uTmFtZVxuICAgICk7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT09ICdhZGRDb25uZWN0aW9ucycgJiYgaXNDb25uZWN0aW9uRXhpc3QpIHtcbiAgICAgIGNvbnN0IG1lc2cgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgICAgZ2V0dGV4dChgQ29ubmVjdGlvbiB3aXRoIG5hbWUgXCJ7eyBuYW1lIH19XCIgYWxyZWFkeSBleGlzdHMuYCksXG4gICAgICAgIHsgbmFtZTogdGhpcy5jb25uZWN0aW9uLm5hbWUgfVxuICAgICAgKTtcbiAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmRhbmdlcihtZXNnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuc2F2ZUNvbm5lY3Rpb24oKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkZWxldGVDb25uZWN0aW9uKG9yaWdpbmFsQ29ubmVjdGlvbikge1xuICAgIGNvbnN0IHsgbmFtZSB9ID0gb3JpZ2luYWxDb25uZWN0aW9uO1xuICAgIGNvbnN0IG1lc2cgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgIGdldHRleHQoYFlvdSBhcmUgYWJvdXQgdG8gZGVsZXRlIHRoZSBjb25uZWN0aW9uIFwie3sgbmFtZSB9fVwiLiBEbyB5b3Ugd2FudCB0byBwcm9jZWVkP2ApLFxuICAgICAgeyBuYW1lIH1cbiAgICApO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMubW9kYWwuY29uZmlybShnZXR0ZXh0KCdEZWxldGUgY29ubmVjdGlvbicpLCBtZXNnLCBTdGF0dXMuREFOR0VSLCB7XG4gICAgICAgIG9rOiBnZXR0ZXh0KCdEZWxldGUnKSxcbiAgICAgICAgY2FuY2VsOiBnZXR0ZXh0KCdDYW5jZWwnKVxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMuZGVsZXRlKG9yaWdpbmFsQ29ubmVjdGlvbik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIGVtcHR5IGNhdGNoIGJsb2NrXG4gICAgfVxuICB9XG5cbiAgY2hhbmdlUGFzc3dvcmQoKSB7XG4gICAgdGhpcy5zaG93UGFzc3dvcmQgPSAhdGhpcy5zaG93UGFzc3dvcmQ7XG4gICAgaWYgKHRoaXMuY29ubmVjdG9yc0Zvcm0uY29udHJvbHMucGFzc3dvcmQpIHtcbiAgICAgIHRoaXMuY29ubmVjdG9yc0Zvcm0uY29udHJvbHMucGFzc3dvcmQuc2V0VmFsdWUobnVsbCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzYXZlQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmNvbm5lY3RvclNlcnZpY2Uuc2F2ZSh0aGlzLmNvbm5lY3Rpb24sIHRoaXMub3JpZ2luYWxDb25uZWN0aW9uPy5uYW1lKTtcbiAgICBpZiAocmVzICYmIChyZXMuc3RhdHVzID09PSAyMDEgfHwgcmVzLnN0YXR1cyA9PT0gMjAwKSkge1xuICAgICAgdGhpcy5zdGF0ZSA9ICdzYXZlZFN1Y2Nlc3NmdWxseSc7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5zdWNjZXNzKGdldHRleHQoJ0Nvbm5lY3Rpb24gc2F2ZWQuJykpO1xuICAgICAgYXdhaXQgdGhpcy5sb2FkQ29ubmVjdGlvbnMoKTtcbiAgICB9IGVsc2UgaWYgKHJlcyAmJiByZXMuc3RhdHVzID09PSA1MDApIHtcbiAgICAgIGNvbnN0IGRhdGEgPSByZXMuanNvbiA/IGF3YWl0IHJlcy5qc29uKCkgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBhcHAgPSB0aGlzLmNvbm5lY3RvclNlcnZpY2UuZ2V0QXBwbGljYXRpb24oJ3NpZ2ZveC1hZ2VudCcpO1xuICAgICAgY29uc3QgaW5pdGlhbFN0YXRlID0ge1xuICAgICAgICBtZXNzYWdlRGF0YTogZGF0YSxcbiAgICAgICAgYXBwRGF0YTogYXBwLFxuICAgICAgICBtb2RhbFRpdGxlOiBnZXR0ZXh0KCdGYWlsZWQgdG8gdXBkYXRlIHRoZSBjb25uZWN0aW9uJyksXG4gICAgICAgIGFyaWFEZXNjcmliZWRieTogJ21vZGFsLWJvZHknLFxuICAgICAgICBhcmlhTGFiZWxsZWRCeTogJ21vZGFsLXRpdGxlJyxcbiAgICAgICAgY29ubmVjdGlvbk5hbWU6IHRoaXMuY29ubmVjdGlvbi5uYW1lXG4gICAgICB9O1xuICAgICAgdGhpcy5tb2RhbFNlcnZpY2Uuc2hvdyhDb25uZWN0aW9uSW5mb1dpdGhEb3dubG9hZENzdkNvbXBvbmVudCwgeyBpbml0aWFsU3RhdGUgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRhdGEgPSByZXMuanNvbiA/IGF3YWl0IHJlcy5qc29uKCkgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKHsgZGF0YSwgcmVzIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZGVsZXRlKG9yaWdpbmFsQ29ubmVjdGlvbikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY29ubmVjdG9yU2VydmljZS5kZWxldGUob3JpZ2luYWxDb25uZWN0aW9uKTtcblxuICAgICAgaWYgKHJlc3BvbnNlLm9rICYmIHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0KSB7XG4gICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLnN1Y2Nlc3MoZ2V0dGV4dCgnQ29ubmVjdGlvbiBkZWxldGVkLicpKTtcbiAgICAgICAgYXdhaXQgdGhpcy5sb2FkQ29ubmVjdGlvbnMoKTtcbiAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2Uuc3RhdHVzID09PSA1MDApIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHJlc3BvbnNlLmpzb24gPyBhd2FpdCByZXNwb25zZS5qc29uKCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IGFwcCA9IHRoaXMuY29ubmVjdG9yU2VydmljZS5nZXRBcHBsaWNhdGlvbignc2lnZm94LWFnZW50Jyk7XG4gICAgICAgIGNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgICAgICAgICBtZXNzYWdlRGF0YTogZGF0YSxcbiAgICAgICAgICBhcHBEYXRhOiBhcHAsXG4gICAgICAgICAgYXJpYURlc2NyaWJlZGJ5OiAnbW9kYWwtYm9keScsXG4gICAgICAgICAgYXJpYUxhYmVsbGVkQnk6ICdtb2RhbC10aXRsZScsXG4gICAgICAgICAgbW9kYWxUaXRsZTogZ2V0dGV4dCgnRmFpbGVkIHRvIGRlbGV0ZSB0aGUgY29ubmVjdGlvbicpLFxuICAgICAgICAgIGNvbm5lY3Rpb25OYW1lOiBvcmlnaW5hbENvbm5lY3Rpb24ubmFtZVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm1vZGFsU2VydmljZS5zaG93KENvbm5lY3Rpb25JbmZvV2l0aERvd25sb2FkQ3N2Q29tcG9uZW50LCB7IGluaXRpYWxTdGF0ZSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSByZXNwb25zZS5qc29uID8gYXdhaXQgcmVzcG9uc2UuanNvbigpIDogdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKHsgZGF0YSwgcmVzcG9uc2UgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIGVtcHR5IGNhdGNoIGJsb2NrXG4gICAgfVxuICB9XG59XG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwic3RhdGUgPT09ICdsb2FkaW5nQ29ubmVjdGlvbic7IGVsc2UgcmVuZGVyTGlzdEFuZEZvcm1cIj5cbiAgPGM4eS1sb2FkaW5nPjwvYzh5LWxvYWRpbmc+XG48L25nLWNvbnRhaW5lcj5cbjxjOHktdGl0bGU+e3sgJ0Nvbm5lY3Rpdml0eScgfCB0cmFuc2xhdGUgfX08L2M4eS10aXRsZT5cblxuPGM4eS1i