@c8y/ngx-components 1021.60.0 → 1021.62.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/alarms/alarm-details.component.d.ts +0 -4
- package/alarms/alarm-details.component.d.ts.map +1 -1
- package/core/authentication/new-password.component.d.ts +6 -3
- package/core/authentication/new-password.component.d.ts.map +1 -1
- package/core/common/interval-based-reload.abstract.d.ts +12 -1
- package/core/common/interval-based-reload.abstract.d.ts.map +1 -1
- package/core/common/permissions.service.d.ts +2 -0
- package/core/common/permissions.service.d.ts.map +1 -1
- package/core/common/tenant-ui.service.d.ts +9 -2
- package/core/common/tenant-ui.service.d.ts.map +1 -1
- package/core/forms/phone-validation.directive.d.ts +3 -6
- package/core/forms/phone-validation.directive.d.ts.map +1 -1
- package/core/router/router.module.d.ts.map +1 -1
- package/device-provisioned-certificates/device-provisioned-certificates.service.d.ts.map +1 -1
- package/esm2022/alarms/alarm-details.component.mjs +10 -10
- package/esm2022/core/authentication/new-password.component.mjs +26 -5
- package/esm2022/core/common/interval-based-reload.abstract.mjs +50 -2
- package/esm2022/core/common/permissions.service.mjs +3 -1
- package/esm2022/core/common/tenant-ui.service.mjs +28 -6
- package/esm2022/core/forms/phone-validation.directive.mjs +18 -19
- package/esm2022/core/router/router.module.mjs +1 -5
- package/esm2022/core/user/user-edit.component.mjs +1 -1
- package/esm2022/device-provisioned-certificates/device-provisioned-certificates.service.mjs +8 -3
- package/esm2022/tenants/custom-properties/custom-properties.component.mjs +25 -5
- package/esm2022/tenants/existing-tenant.guard.mjs +18 -0
- package/esm2022/tenants/index.mjs +3 -1
- package/esm2022/tenants/support-user-access/support-user-access.component.mjs +31 -0
- package/esm2022/tenants/tenant-form/tenant-form-inputs-definitions.mjs +116 -0
- package/esm2022/tenants/tenant-form/tenant-form.component.mjs +294 -0
- package/esm2022/tenants/tenant-limits/tenant-limits-definitions.mjs +10 -17
- package/esm2022/tenants/tenant-limits/tenant-limits.component.mjs +42 -29
- package/esm2022/tenants/tenant-list/tenant-list.component.mjs +17 -8
- package/esm2022/tenants/tenants.model.mjs +30 -1
- package/esm2022/tenants/tenants.module.mjs +57 -22
- package/esm2022/translation-editor/data/translation-store.service.mjs +11 -8
- package/esm2022/translation-editor/index.mjs +22 -5
- package/esm2022/translation-editor/lazy/advanced-translation-editor/advanced-translation-editor.component.mjs +136 -0
- package/esm2022/translation-editor/lazy/index.mjs +2 -1
- package/esm2022/translation-editor/translation-editor-tab-factory.service.mjs +40 -0
- package/esm2022/translation-editor/translation-editor.constants.mjs +4 -0
- package/esm2022/upgrade/upgraded-services/index.mjs +2 -1
- package/esm2022/upgrade/upgraded-services/tenant-policies.service.mjs +11 -0
- package/esm2022/upgrade/upgraded-services/upgraded-services.module.mjs +12 -3
- package/esm2022/widgets/implementations/alarms/alarm-widget-alarms-reload.component.mjs +9 -7
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.mjs +9 -7
- package/fesm2022/c8y-ngx-components-alarms.mjs +5 -5
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-provisioned-certificates.mjs +7 -2
- package/fesm2022/c8y-ngx-components-device-provisioned-certificates.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-tenants.mjs +603 -82
- package/fesm2022/c8y-ngx-components-tenants.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-translation-editor-data.mjs +9 -6
- package/fesm2022/c8y-ngx-components-translation-editor-data.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs +127 -2
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-translation-editor.mjs +58 -4
- package/fesm2022/c8y-ngx-components-translation-editor.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-upgrade-upgraded-services.mjs +22 -3
- package/fesm2022/c8y-ngx-components-upgrade-upgraded-services.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +8 -6
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +8 -6
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +499 -413
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/de.po +17 -25
- package/locales/es.po +17 -25
- package/locales/fr.po +17 -25
- package/locales/ja_JP.po +17 -25
- package/locales/ko.po +17 -25
- package/locales/locales.pot +34 -24
- package/locales/nl.po +17 -25
- package/locales/pl.po +17 -25
- package/locales/pt_BR.po +17 -25
- package/locales/zh_CN.po +17 -25
- package/locales/zh_TW.po +17 -25
- package/package.json +1 -1
- package/tenants/custom-properties/custom-properties.component.d.ts +4 -2
- package/tenants/custom-properties/custom-properties.component.d.ts.map +1 -1
- package/tenants/existing-tenant.guard.d.ts +13 -0
- package/tenants/existing-tenant.guard.d.ts.map +1 -0
- package/tenants/index.d.ts +2 -0
- package/tenants/index.d.ts.map +1 -1
- package/tenants/support-user-access/support-user-access.component.d.ts +18 -0
- package/tenants/support-user-access/support-user-access.component.d.ts.map +1 -0
- package/tenants/tenant-form/tenant-form-inputs-definitions.d.ts +113 -0
- package/tenants/tenant-form/tenant-form-inputs-definitions.d.ts.map +1 -0
- package/tenants/tenant-form/tenant-form.component.d.ts +79 -0
- package/tenants/tenant-form/tenant-form.component.d.ts.map +1 -0
- package/tenants/tenant-limits/tenant-limits-definitions.d.ts +11 -15
- package/tenants/tenant-limits/tenant-limits-definitions.d.ts.map +1 -1
- package/tenants/tenant-limits/tenant-limits.component.d.ts +9 -7
- package/tenants/tenant-limits/tenant-limits.component.d.ts.map +1 -1
- package/tenants/tenant-list/tenant-list.component.d.ts +6 -3
- package/tenants/tenant-list/tenant-list.component.d.ts.map +1 -1
- package/tenants/tenants.model.d.ts +31 -0
- package/tenants/tenants.model.d.ts.map +1 -1
- package/tenants/tenants.module.d.ts +4 -2
- package/tenants/tenants.module.d.ts.map +1 -1
- package/translation-editor/data/translation-store.service.d.ts +3 -2
- package/translation-editor/data/translation-store.service.d.ts.map +1 -1
- package/translation-editor/index.d.ts.map +1 -1
- package/translation-editor/lazy/advanced-translation-editor/advanced-translation-editor.component.d.ts +28 -0
- package/translation-editor/lazy/advanced-translation-editor/advanced-translation-editor.component.d.ts.map +1 -0
- package/translation-editor/lazy/index.d.ts +1 -0
- package/translation-editor/lazy/index.d.ts.map +1 -1
- package/translation-editor/translation-editor-tab-factory.service.d.ts +22 -0
- package/translation-editor/translation-editor-tab-factory.service.d.ts.map +1 -0
- package/translation-editor/translation-editor.constants.d.ts +4 -0
- package/translation-editor/translation-editor.constants.d.ts.map +1 -0
- package/upgrade/upgraded-services/index.d.ts +1 -0
- package/upgrade/upgraded-services/index.d.ts.map +1 -1
- package/upgrade/upgraded-services/tenant-policies.service.d.ts +11 -0
- package/upgrade/upgraded-services/tenant-policies.service.d.ts.map +1 -0
- package/upgrade/upgraded-services/upgraded-services.module.d.ts.map +1 -1
- package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts +7 -2
- package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts +7 -2
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts.map +1 -1
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { Component, Optional, ViewChild } from '@angular/core';
|
|
2
|
+
import { TenantService } from '@c8y/client';
|
|
3
|
+
import { FormControl, FormGroup, NgForm } from '@angular/forms';
|
|
4
|
+
import { TenantUiService, AlertService, gettext, GainsightService } from '@c8y/ngx-components';
|
|
5
|
+
import { ActivatedRoute } from '@angular/router';
|
|
6
|
+
import { assign, cloneDeep, find } from 'lodash-es';
|
|
7
|
+
import { Location } from '@angular/common';
|
|
8
|
+
import { Ng1TenantPoliciesService } from '@c8y/ngx-components/upgrade/upgraded-services';
|
|
9
|
+
import { tenantFormInputsDefinitions } from './tenant-form-inputs-definitions';
|
|
10
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
11
|
+
import { PRODUCT_EXPERIENCE_TENANT_MANAGEMENT } from '../tenants.model';
|
|
12
|
+
import { take } from 'rxjs/operators';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "@c8y/ngx-components/upgrade/upgraded-services";
|
|
15
|
+
import * as i2 from "@c8y/client";
|
|
16
|
+
import * as i3 from "@c8y/ngx-components";
|
|
17
|
+
import * as i4 from "@angular/common";
|
|
18
|
+
import * as i5 from "@angular/router";
|
|
19
|
+
import * as i6 from "@ngx-translate/core";
|
|
20
|
+
import * as i7 from "@angular/forms";
|
|
21
|
+
import * as i8 from "../support-user-access/support-user-access.component";
|
|
22
|
+
const { ACTIONS, COMPONENTS, EVENTS, RESULTS } = PRODUCT_EXPERIENCE_TENANT_MANAGEMENT;
|
|
23
|
+
export class TenantFormComponent {
|
|
24
|
+
constructor(tenantPoliciesServiceProvider, tenantService, tenantUiService, location, alertService, activatedRoute, translateService, gainsightService) {
|
|
25
|
+
this.tenantPoliciesServiceProvider = tenantPoliciesServiceProvider;
|
|
26
|
+
this.tenantService = tenantService;
|
|
27
|
+
this.tenantUiService = tenantUiService;
|
|
28
|
+
this.location = location;
|
|
29
|
+
this.alertService = alertService;
|
|
30
|
+
this.activatedRoute = activatedRoute;
|
|
31
|
+
this.translateService = translateService;
|
|
32
|
+
this.gainsightService = gainsightService;
|
|
33
|
+
this.MANAGEMENT_TENANT_NAME = this.tenantUiService.MANAGEMENT;
|
|
34
|
+
this.tenant = null;
|
|
35
|
+
this.tenantPolicyNone = { name: this.translateService.instant(gettext('None')) };
|
|
36
|
+
this.saveInProgress = false;
|
|
37
|
+
this.showPasswordComponent = false;
|
|
38
|
+
this.tenantForm = new FormGroup({});
|
|
39
|
+
this.fieldDefinitions = { ...tenantFormInputsDefinitions };
|
|
40
|
+
this.initialized = false;
|
|
41
|
+
}
|
|
42
|
+
async ngOnInit() {
|
|
43
|
+
await this.getHost();
|
|
44
|
+
this.getTenantId();
|
|
45
|
+
await this.getTenant();
|
|
46
|
+
await this.checkIfIsEnterpriseEdition();
|
|
47
|
+
this.initialized = true;
|
|
48
|
+
if (!this.isNew) {
|
|
49
|
+
this.sendGainsightEvent(ACTIONS.TENANT_PROPERTIES_OPENED);
|
|
50
|
+
}
|
|
51
|
+
this.tenantForm.valueChanges.pipe(take(1)).subscribe(() => {
|
|
52
|
+
this.sendGainsightEvent(this.isNew
|
|
53
|
+
? ACTIONS.TENANT_CREATION_STARTED_FILLING
|
|
54
|
+
: ACTIONS.TENANT_PROPERTIES_STARTED_CHANGING);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async onTenantPolicyChange() {
|
|
58
|
+
const passwordSettings = await this.tenantUiService.getPasswordStrengthSettings();
|
|
59
|
+
this.tenantPolicy = find(this.tenantPolicies, {
|
|
60
|
+
id: this.tenantForm.controls.tenantPolicy.value.id
|
|
61
|
+
});
|
|
62
|
+
const enforcedOnSystemLevel = passwordSettings.enforceStrength;
|
|
63
|
+
const enforcedOnTenantLevel = passwordSettings.strengthValidity;
|
|
64
|
+
const enforcedOnTenantPolicyLevel = this.tenantPoliciesServiceProvider
|
|
65
|
+
? await this.tenantPoliciesServiceProvider.doesEnforceStrongPassword(this.tenantPolicy)
|
|
66
|
+
: undefined;
|
|
67
|
+
if (this.isNew) {
|
|
68
|
+
this.passwordStrengthEnforced = enforcedOnSystemLevel || enforcedOnTenantPolicyLevel;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.passwordStrengthEnforced = enforcedOnSystemLevel || enforcedOnTenantLevel;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
setForm() {
|
|
75
|
+
this.tenantForm.patchValue({
|
|
76
|
+
tenantId: this.tenant.id,
|
|
77
|
+
domain: this.tenant.domain,
|
|
78
|
+
companyName: this.tenant.company,
|
|
79
|
+
contactName: this.tenant.contactName,
|
|
80
|
+
contactPhone: this.tenant.contactPhone,
|
|
81
|
+
administratorEmail: this.tenant.adminEmail,
|
|
82
|
+
administratorUsername: this.tenant.adminName,
|
|
83
|
+
sendPasswordResetEmail: this.tenant.sendPasswordResetEmail,
|
|
84
|
+
allowCreateTenants: this.tenant.allowCreateTenants,
|
|
85
|
+
externalReference: this.tenant.customProperties.externalReference,
|
|
86
|
+
gainsightEnabled: this.tenant.customProperties.gainsightEnabled
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
getTenantId() {
|
|
90
|
+
this.tenantId = this.activatedRoute.snapshot.parent.data.contextData.id;
|
|
91
|
+
this.isNew = !this.tenantId;
|
|
92
|
+
}
|
|
93
|
+
async onSubmit() {
|
|
94
|
+
let tenantToBeSaved;
|
|
95
|
+
if (!this.isNew) {
|
|
96
|
+
const formRawValue = this.tenantForm.getRawValue();
|
|
97
|
+
const customProperties = {
|
|
98
|
+
...this.tenant.customProperties,
|
|
99
|
+
externalReference: formRawValue.externalReference,
|
|
100
|
+
gainsightEnabled: formRawValue.gainsightEnabled
|
|
101
|
+
};
|
|
102
|
+
tenantToBeSaved = {
|
|
103
|
+
id: this.tenant.id,
|
|
104
|
+
company: formRawValue.companyName,
|
|
105
|
+
contactName: formRawValue.contactName,
|
|
106
|
+
contactPhone: formRawValue.contactPhone,
|
|
107
|
+
domain: formRawValue.domain,
|
|
108
|
+
status: this.tenant.status,
|
|
109
|
+
allowCreateTenants: this.tenantForm.value.allowCreateTenants,
|
|
110
|
+
customProperties: customProperties
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
tenantToBeSaved = {
|
|
115
|
+
adminEmail: this.tenantForm.value.administratorEmail,
|
|
116
|
+
adminName: this.tenantForm.value.administratorUsername,
|
|
117
|
+
company: this.tenantForm.value.companyName,
|
|
118
|
+
contactName: this.tenantForm.value.contactName,
|
|
119
|
+
contactPhone: this.tenantForm.value.contactPhone,
|
|
120
|
+
domain: this.tenantForm.value.domain,
|
|
121
|
+
adminPass: this.tenantForm.value.password,
|
|
122
|
+
sendPasswordResetEmail: this.tenantForm.value.sendPasswordResetEmail,
|
|
123
|
+
tenantPolicyId: this.tenantForm.value.tenantPolicy?.id
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (this.isNew && this.host) {
|
|
127
|
+
tenantToBeSaved.domain = tenantToBeSaved.domain + this.host;
|
|
128
|
+
}
|
|
129
|
+
const t = cloneDeep(tenantToBeSaved);
|
|
130
|
+
if (t.storageLimitPerDevice === undefined) {
|
|
131
|
+
t.storageLimitPerDevice = 0;
|
|
132
|
+
}
|
|
133
|
+
this.setSaveInProgress(true);
|
|
134
|
+
try {
|
|
135
|
+
let savedTenant;
|
|
136
|
+
if (this.isNew) {
|
|
137
|
+
savedTenant = (await this.tenantService.create(t)).data;
|
|
138
|
+
if (this.tenantForm.value.allowCreateTenants) {
|
|
139
|
+
assign(savedTenant, { allowCreateTenants: this.tenantForm.value.allowCreateTenants });
|
|
140
|
+
await this.tenantService.update(savedTenant);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
savedTenant = (await this.tenantService.update(t)).data;
|
|
145
|
+
}
|
|
146
|
+
this.sendGainsightEvent(this.isNew ? ACTIONS.TENANT_CREATION_SAVED : ACTIONS.TENANT_PROPERTIES_SAVED, { result: RESULTS.SUCCESS });
|
|
147
|
+
this.onSave(savedTenant, this.tenantForm);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
this.alertService.addServerFailure(error);
|
|
151
|
+
this.sendGainsightEvent(this.isNew ? ACTIONS.TENANT_CREATION_SAVED : ACTIONS.TENANT_PROPERTIES_SAVED, { result: RESULTS.FAILURE, error });
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
this.setSaveInProgress(false);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
onSave(tenant, form) {
|
|
158
|
+
if (this.isNew) {
|
|
159
|
+
setTimeout(() => {
|
|
160
|
+
this.location.go(`/tenants/${tenant.id}`);
|
|
161
|
+
location.reload();
|
|
162
|
+
}, 2000);
|
|
163
|
+
this.alertService.success(gettext('Tenant saved.'));
|
|
164
|
+
}
|
|
165
|
+
assign(this.tenant, tenant);
|
|
166
|
+
this.alertService.success(gettext('Tenant saved.'));
|
|
167
|
+
form.markAsPristine();
|
|
168
|
+
}
|
|
169
|
+
setSaveInProgress(value) {
|
|
170
|
+
this.saveInProgress = value;
|
|
171
|
+
}
|
|
172
|
+
cancel() {
|
|
173
|
+
this.location.go('tenants');
|
|
174
|
+
}
|
|
175
|
+
shouldDisableSave() {
|
|
176
|
+
const disabled = !this.tenantForm.valid || !this.tenantForm.dirty || this.saveInProgress;
|
|
177
|
+
if (this.showPasswordComponent) {
|
|
178
|
+
if (this.passwordForm) {
|
|
179
|
+
return disabled || !this.passwordForm.valid;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
return disabled;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
onNewPasswordChanged(newPassword) {
|
|
190
|
+
this.tenantForm.addControl('password', new FormControl(newPassword.password));
|
|
191
|
+
}
|
|
192
|
+
onCheckboxChange(inputField) {
|
|
193
|
+
if (inputField === 'sendPasswordResetEmail') {
|
|
194
|
+
this.showPasswordComponent = !this.tenantForm.value.sendPasswordResetEmail;
|
|
195
|
+
this.removePasswordControl(this.showPasswordComponent);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
setDisabledState() {
|
|
199
|
+
if (!this.isNew) {
|
|
200
|
+
this.tenantForm.controls.tenantId.disable();
|
|
201
|
+
this.tenantForm.controls.domain.disable();
|
|
202
|
+
this.tenantForm.controls.administratorEmail.disable();
|
|
203
|
+
this.tenantForm.controls.administratorUsername.disable();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async shouldShowSubtenantCheckbox() {
|
|
207
|
+
const currentTenantIsManagement = await this.tenantUiService.isManagementTenant();
|
|
208
|
+
const editedTenantIsChildOfManagement = this.tenant && this.tenant.parent === this.MANAGEMENT_TENANT_NAME;
|
|
209
|
+
return currentTenantIsManagement && (editedTenantIsChildOfManagement || this.isNew);
|
|
210
|
+
}
|
|
211
|
+
removePasswordControl(passwordComponentShown) {
|
|
212
|
+
if (!passwordComponentShown) {
|
|
213
|
+
this.tenantForm.removeControl('password');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async getTenant() {
|
|
217
|
+
if (this.tenantId && this.tenantId !== 'new') {
|
|
218
|
+
const detailedTenant = (await this.tenantService.detail(this.tenantId)).data;
|
|
219
|
+
this.title = detailedTenant.company;
|
|
220
|
+
this.onTenant(detailedTenant);
|
|
221
|
+
await this.generateForm();
|
|
222
|
+
this.setForm();
|
|
223
|
+
this.setDisabledState();
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
this.title = this.translateService.instant(gettext('New tenant'));
|
|
227
|
+
await this.generateForm();
|
|
228
|
+
await this.loadTenantPolicies();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async loadTenantPolicies() {
|
|
232
|
+
if (this.tenantPoliciesServiceProvider) {
|
|
233
|
+
this.onTenantPolicies(await this.tenantPoliciesServiceProvider.list());
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async getHost() {
|
|
237
|
+
const currentTenant = await this.tenantService.current();
|
|
238
|
+
this.host = `.${currentTenant.data.domainName.split('.').slice(1).join('.')}`;
|
|
239
|
+
}
|
|
240
|
+
async checkIfIsEnterpriseEdition() {
|
|
241
|
+
this.isEnterpriseEditionTenant = await this.tenantUiService.isEnterpriseTenant();
|
|
242
|
+
}
|
|
243
|
+
onTenantPolicies(tenantPolicies) {
|
|
244
|
+
this.tenantPolicies = [this.tenantPolicyNone, ...tenantPolicies];
|
|
245
|
+
}
|
|
246
|
+
onTenant(tenant = {}) {
|
|
247
|
+
this.tenant = tenant;
|
|
248
|
+
}
|
|
249
|
+
async generateForm() {
|
|
250
|
+
const shouldShowSubtenantCheckbox = await this.shouldShowSubtenantCheckbox();
|
|
251
|
+
const gainsightAvailable = !!(await this.gainsightService.getGainsightKey());
|
|
252
|
+
if (!shouldShowSubtenantCheckbox) {
|
|
253
|
+
delete this.fieldDefinitions.allowCreateTenants;
|
|
254
|
+
}
|
|
255
|
+
if (!this.isNew) {
|
|
256
|
+
delete this.fieldDefinitions.sendPasswordResetEmail;
|
|
257
|
+
}
|
|
258
|
+
if (this.isNew || (this.host && this.isEnterpriseEditionTenant)) {
|
|
259
|
+
delete this.fieldDefinitions.tenantID;
|
|
260
|
+
}
|
|
261
|
+
if (!this.isNew && !this.host) {
|
|
262
|
+
delete this.fieldDefinitions.domain;
|
|
263
|
+
}
|
|
264
|
+
if (this.isNew || !gainsightAvailable) {
|
|
265
|
+
delete this.fieldDefinitions.gainsightEnabled;
|
|
266
|
+
}
|
|
267
|
+
if (this.isNew) {
|
|
268
|
+
delete this.fieldDefinitions.externalReference;
|
|
269
|
+
}
|
|
270
|
+
for (const field of Object.values(this.fieldDefinitions)) {
|
|
271
|
+
this.tenantForm.addControl(field.id, new FormControl(field.defaultValue, field.validators));
|
|
272
|
+
}
|
|
273
|
+
this.fieldKeys = Object.keys(this.fieldDefinitions);
|
|
274
|
+
}
|
|
275
|
+
sendGainsightEvent(action, props = {}) {
|
|
276
|
+
this.gainsightService.triggerEvent(EVENTS.TENANT_MANAGEMENT, {
|
|
277
|
+
component: COMPONENTS.TENANT_FORM,
|
|
278
|
+
action,
|
|
279
|
+
...props
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TenantFormComponent, deps: [{ token: i1.Ng1TenantPoliciesService, optional: true }, { token: i2.TenantService }, { token: i3.TenantUiService }, { token: i4.Location }, { token: i3.AlertService }, { token: i5.ActivatedRoute }, { token: i6.TranslateService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
283
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TenantFormComponent, selector: "c8y-tenant-form", viewQueries: [{ propertyName: "passwordForm", first: true, predicate: ["passwordForm"], descendants: true }], ngImport: i0, template: "<c8y-title *ngIf=\"title\">\n {{ title }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Tenants' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Subtenants' | translate\"\n [path]=\"'/tenants'\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<form\n [formGroup]=\"tenantForm\"\n (ngSubmit)=\"onSubmit()\"\n>\n <div class=\"card content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"inner-scroll bg-level-0\">\n <div class=\"card-header separator large-padding sticky-top\">\n <div\n class=\"card-title\"\n translate\n >\n Identification\n </div>\n </div>\n\n <div>\n <div\n class=\"card-block\"\n *ngIf=\"!initialized\"\n >\n <c8y-loading></c8y-loading>\n </div>\n\n <div\n class=\"card-block\"\n *ngIf=\"initialized\"\n >\n <ng-container *ngFor=\"let key of fieldKeys\">\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'text'\">\n <ng-container\n *ngTemplateOutlet=\"textField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'number'\">\n <ng-container\n *ngTemplateOutlet=\"numberField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'checkbox'\">\n <ng-container\n *ngTemplateOutlet=\"checkboxField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'select'\">\n <ng-container\n *ngTemplateOutlet=\"selectField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <div\n class=\"inner-scroll bg-level-1\"\n *ngIf=\"!isNew && tenant\"\n >\n <c8y-support-user-access [tenant]=\"tenant\"></c8y-support-user-access>\n </div>\n\n <!-- FOOTER CARD -->\n <div\n class=\"card-footer separator large-padding grid__col--fullspan\"\n *ngIf=\"initialized\"\n >\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n [routerLink]=\"['/tenants']\"\n data-cy=\"c8y-tenant-form--cancelButton\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n [disabled]=\"shouldDisableSave()\"\n data-cy=\"c8y-tenant-form--saveButton\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n\n <!-- NG TEMPLATES -->\n <ng-template\n #textField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"text\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span\n class=\"input-group-addon\"\n *ngIf=\"fieldDefinition.id === 'domain' && host && isNew\"\n >\n {{ host }}\n </span>\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #numberField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <input\n class=\"form-control\"\n type=\"number\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #checkboxField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n [title]=\"fieldDefinition.label | translate\"\n [for]=\"fieldDefinition.id\"\n >\n <input\n type=\"checkbox\"\n [id]=\"fieldDefinition.id\"\n [formControlName]=\"fieldDefinition.id\"\n (change)=\"onCheckboxChange(fieldDefinition.id)\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span></span>\n <span>{{ fieldDefinition.label | translate }}</span>\n </label>\n </c8y-form-group>\n <form\n #passwordForm=\"ngForm\"\n *ngIf=\"showPasswordComponent && fieldDefinition.id === 'sendPasswordResetEmail'\"\n >\n <c8y-new-password\n [showChangePasswordButton]=\"false\"\n [requireStrongPassword]=\"passwordStrengthEnforced\"\n (password)=\"onNewPasswordChanged($event)\"\n ></c8y-new-password>\n </form>\n </ng-template>\n\n <ng-template\n #selectField\n let-fieldDefinition\n >\n <c8y-form-group *ngIf=\"tenantPolicies && tenantPolicies.length > 0\">\n <label>{{ fieldDefinition.label | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n title=\"{{ fieldDefinition.label | translate }}\"\n name=\"tenantPolicy\"\n (change)=\"onTenantPolicyChange()\"\n formControlName=\"tenantPolicy\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n >\n <option\n *ngFor=\"let tenantPolicy of tenantPolicies\"\n [ngValue]=\"tenantPolicy\"\n >\n {{ tenantPolicy.name }}\n </option>\n </select>\n <span></span>\n </div>\n </c8y-form-group>\n </ng-template>\n</form>\n", dependencies: [{ kind: "component", type: i3.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i3.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i3.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i3.NewPasswordComponent, selector: "c8y-new-password", inputs: ["showChangePasswordButton", "requireStrongPassword"], outputs: ["password"] }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.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: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i8.SupportUserAccessComponent, selector: "c8y-support-user-access", inputs: ["tenant"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); }
|
|
284
|
+
}
|
|
285
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TenantFormComponent, decorators: [{
|
|
286
|
+
type: Component,
|
|
287
|
+
args: [{ selector: 'c8y-tenant-form', template: "<c8y-title *ngIf=\"title\">\n {{ title }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Tenants' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Subtenants' | translate\"\n [path]=\"'/tenants'\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<form\n [formGroup]=\"tenantForm\"\n (ngSubmit)=\"onSubmit()\"\n>\n <div class=\"card content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"inner-scroll bg-level-0\">\n <div class=\"card-header separator large-padding sticky-top\">\n <div\n class=\"card-title\"\n translate\n >\n Identification\n </div>\n </div>\n\n <div>\n <div\n class=\"card-block\"\n *ngIf=\"!initialized\"\n >\n <c8y-loading></c8y-loading>\n </div>\n\n <div\n class=\"card-block\"\n *ngIf=\"initialized\"\n >\n <ng-container *ngFor=\"let key of fieldKeys\">\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'text'\">\n <ng-container\n *ngTemplateOutlet=\"textField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'number'\">\n <ng-container\n *ngTemplateOutlet=\"numberField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'checkbox'\">\n <ng-container\n *ngTemplateOutlet=\"checkboxField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"fieldDefinitions[key].type === 'select'\">\n <ng-container\n *ngTemplateOutlet=\"selectField; context: { $implicit: fieldDefinitions[key] }\"\n ></ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <div\n class=\"inner-scroll bg-level-1\"\n *ngIf=\"!isNew && tenant\"\n >\n <c8y-support-user-access [tenant]=\"tenant\"></c8y-support-user-access>\n </div>\n\n <!-- FOOTER CARD -->\n <div\n class=\"card-footer separator large-padding grid__col--fullspan\"\n *ngIf=\"initialized\"\n >\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n [routerLink]=\"['/tenants']\"\n data-cy=\"c8y-tenant-form--cancelButton\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n [disabled]=\"shouldDisableSave()\"\n data-cy=\"c8y-tenant-form--saveButton\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n\n <!-- NG TEMPLATES -->\n <ng-template\n #textField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"text\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span\n class=\"input-group-addon\"\n *ngIf=\"fieldDefinition.id === 'domain' && host && isNew\"\n >\n {{ host }}\n </span>\n </div>\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #numberField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label [for]=\"fieldDefinition.id\">\n {{ fieldDefinition.label | translate: fieldDefinition.labelArgs }}\n </label>\n <input\n class=\"form-control\"\n type=\"number\"\n [id]=\"fieldDefinition.id\"\n [placeholder]=\"fieldDefinition.placeholder | translate: fieldDefinition.placeholderArgs\"\n [formControlName]=\"fieldDefinition.id\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n </c8y-form-group>\n </ng-template>\n\n <ng-template\n #checkboxField\n let-fieldDefinition\n >\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n [title]=\"fieldDefinition.label | translate\"\n [for]=\"fieldDefinition.id\"\n >\n <input\n type=\"checkbox\"\n [id]=\"fieldDefinition.id\"\n [formControlName]=\"fieldDefinition.id\"\n (change)=\"onCheckboxChange(fieldDefinition.id)\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n />\n <span></span>\n <span>{{ fieldDefinition.label | translate }}</span>\n </label>\n </c8y-form-group>\n <form\n #passwordForm=\"ngForm\"\n *ngIf=\"showPasswordComponent && fieldDefinition.id === 'sendPasswordResetEmail'\"\n >\n <c8y-new-password\n [showChangePasswordButton]=\"false\"\n [requireStrongPassword]=\"passwordStrengthEnforced\"\n (password)=\"onNewPasswordChanged($event)\"\n ></c8y-new-password>\n </form>\n </ng-template>\n\n <ng-template\n #selectField\n let-fieldDefinition\n >\n <c8y-form-group *ngIf=\"tenantPolicies && tenantPolicies.length > 0\">\n <label>{{ fieldDefinition.label | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n title=\"{{ fieldDefinition.label | translate }}\"\n name=\"tenantPolicy\"\n (change)=\"onTenantPolicyChange()\"\n formControlName=\"tenantPolicy\"\n [attr.data-cy]=\"'c8y-tenant-form--' + fieldDefinition.id\"\n >\n <option\n *ngFor=\"let tenantPolicy of tenantPolicies\"\n [ngValue]=\"tenantPolicy\"\n >\n {{ tenantPolicy.name }}\n </option>\n </select>\n <span></span>\n </div>\n </c8y-form-group>\n </ng-template>\n</form>\n" }]
|
|
288
|
+
}], ctorParameters: () => [{ type: i1.Ng1TenantPoliciesService, decorators: [{
|
|
289
|
+
type: Optional
|
|
290
|
+
}] }, { type: i2.TenantService }, { type: i3.TenantUiService }, { type: i4.Location }, { type: i3.AlertService }, { type: i5.ActivatedRoute }, { type: i6.TranslateService }, { type: i3.GainsightService }], propDecorators: { passwordForm: [{
|
|
291
|
+
type: ViewChild,
|
|
292
|
+
args: ['passwordForm']
|
|
293
|
+
}] } });
|
|
294
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWZvcm0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVuYW50cy90ZW5hbnQtZm9ybS90ZW5hbnQtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi90ZW5hbnRzL3RlbmFudC1mb3JtL3RlbmFudC1mb3JtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQVcsYUFBYSxFQUFpQixNQUFNLGFBQWEsQ0FBQztBQUNwRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFlBQVksRUFDWixPQUFPLEVBRVAsZ0JBQWdCLEVBQ2pCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDekYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUVMLG9DQUFvQyxFQUVyQyxNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7OztBQUV0QyxNQUFNLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcs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dGlvbmFsLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElUZW5hbnQsIFRlbmFudFNlcnZpY2UsIElUZW5hbnRQb2xpY3kgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBOZ0Zvcm0gfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBUZW5hbnRVaVNlcnZpY2UsXG4gIEFsZXJ0U2VydmljZSxcbiAgZ2V0dGV4dCxcbiAgTmV3UGFzc3dvcmQsXG4gIEdhaW5zaWdodFNlcnZpY2Vcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBhc3NpZ24sIGNsb25lRGVlcCwgZmluZCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBOZzFUZW5hbnRQb2xpY2llc1NlcnZpY2UgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL3VwZ3JhZGUvdXBncmFkZWQtc2VydmljZXMnO1xuaW1wb3J0IHsgdGVuYW50Rm9ybUlucHV0c0RlZmluaXRpb25zIH0gZnJvbSAnLi90ZW5hbnQtZm9ybS1pbnB1dHMtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtcbiAgVGVuYW50TWFuYWdlbWVudEFjdGlvblR5cGUsXG4gIFBST0RVQ1RfRVhQRVJJRU5DRV9URU5BTlRfTUFOQUdFTUVOVCxcbiAgVGVuYW50TWFuYWdlbWVudFJlc3VsdFR5cGVcbn0gZnJvbSAnLi4vdGVuYW50cy5tb2RlbCc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCB7IEFDVElPTlMsIENPTVBPTkVOVFMsIEVWRU5UUywgUkVTVUxUUyB9ID0gUFJPRFVDVF9FWFBFUklFTkNFX1RFTkFOVF9NQU5BR0VNRU5UO1xuXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGVVcmw6ICcuL3RlbmFudC1mb3JtLmNvbXBvbmVudC5odG1sJyxcbiAgc2VsZWN0b3I6ICdjOHktdGVuYW50LWZvcm0nXG59KVxuZXhwb3J0IGNsYXNzIFRlbmFudEZvcm1Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBAVmlld0NoaWxkKCdwYXNzd29yZEZvcm0nKSBwYXNzd29yZEZvcm06IE5nRm9ybTtcbiAgTUFOQUdFTUVOVF9URU5BTlRfTkFNRSA9IHRoaXMudGVuYW50VWlTZXJ2aWNlLk1BTkFHRU1FTlQ7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGhvc3Q6IHN0cmluZztcbiAgaXNUb3BUZW5hbnQ6IGJvb2xlYW47XG4gIGlzTmV3OiBib29sZWFuO1xuICBpc0VudGVycHJpc2VFZGl0aW9uVGVuYW50OiBib29sZWFuO1xuICB0ZW5hbnQ6IElUZW5hbnQgfCBudWxsID0gbnVsbDtcbiAgdGVuYW50UG9saWNpZXM6IEFycmF5PElUZW5hbnRQb2xpY3k+O1xuICB0ZW5hbnRQb2xpY3lOb25lID0geyBuYW1lOiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChnZXR0ZXh0KCdOb25lJykpIH07XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIHBhc3N3b3JkU3RyZW5ndGhFbmZvcmNlZDogYm9vbGVhbjtcbiAgc2F2ZUluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgc2hvd1Bhc3N3b3JkQ29tcG9uZW50ID0gZmFsc2U7XG4gIHRlbmFudFBvbGljeTogSVRlbmFudFBvbGljeTtcbiAgZmllbGRLZXlzOiBzdHJpbmdbXTtcbiAgdGVuYW50Rm9ybTogRm9ybUdyb3VwID0gbmV3IEZvcm1Hcm91cCh7fSk7XG4gIGZpZWxkRGVmaW5pdGlvbnMgPSB7IC4uLnRlbmFudEZvcm1JbnB1dHNEZWZpbml0aW9ucyB9O1xuICBpbml0aWFsaXplZCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBPcHRpb25hbCgpIHB1YmxpYyB0ZW5hbnRQb2xpY2llc1NlcnZpY2VQcm92aWRlcjogTmcxVGVuYW50UG9saWNpZXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgdGVuYW50U2VydmljZTogVGVuYW50U2VydmljZSxcbiAgICBwcml2YXRlIHRlbmFudFVpU2VydmljZTogVGVuYW50VWlTZXJ2aWNlLFxuICAgIHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uLFxuICAgIHByaXZhdGUgYWxlcnRTZXJ2aWNlOiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgZ2FpbnNpZ2h0U2VydmljZTogR2FpbnNpZ2h0U2VydmljZVxuICApIHt9XG5cbiAgYXN5bmMgbmdPbkluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5nZXRIb3N0KCk7XG4gICAgdGhpcy5nZXRUZW5hbnRJZCgpO1xuICAgIGF3YWl0IHRoaXMuZ2V0VGVuYW50KCk7XG4gICAgYXdhaXQgdGhpcy5jaGVja0lmSXNFbnRlcnByaXNlRWRpdGlvbigpO1xuXG4gICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICBpZiAoIXRoaXMuaXNOZXcpIHtcbiAgICAgIHRoaXMuc2VuZEdhaW5zaWdodEV2ZW50KEFDVElPTlMuVEVOQU5UX1BST1BFUlRJRVNfT1BFTkVEKTtcbiAgICB9XG5cbiAgICB0aGlzLnRlbmFudEZvcm0udmFsdWVDaGFuZ2VzLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuc2VuZEdhaW5zaWdodEV2ZW50KFxuICAgICAgICB0aGlzLmlzTmV3XG4gICAgICAgICAgPyBBQ1RJT05TLlRFTkFOVF9DUkVBVElPTl9TVEFSVEVEX0ZJTExJTkdcbiAgICAgICAgICA6IEFDVElPTlMuVEVOQU5UX1BST1BFUlRJRVNfU1RBUlRFRF9DSEFOR0lOR1xuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIG9uVGVuYW50UG9saWN5Q2hhbmdlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBhc3N3b3JkU2V0dGluZ3MgPSBhd2FpdCB0aGlzLnRlbmFudFVpU2VydmljZS5nZXRQYXNzd29yZFN0cmVuZ3RoU2V0dGluZ3MoKTtcbiAgICB0aGlzLnRlbmFudFBvbGljeSA9IGZpbmQodGhpcy50ZW5hbnRQb2xpY2llcywge1xuICAgICAgaWQ6IHRoaXMudGVuYW50Rm9ybS5jb250cm9scy50ZW5hbnRQb2xpY3kudmFsdWUuaWRcbiAgICB9KTtcbiAgICBjb25zdCBlbmZvcmNlZE9uU3lzdGVtTGV2ZWwgPSBwYXNzd29yZFNldHRpbmdzLmVuZm9yY2VTdHJlbmd0aDtcbiAgICBjb25zdCBlbmZvcmNlZE9uVGVuYW50TGV2ZWwgPSBwYXNzd29yZFNldHRpbmdzLnN0cmVuZ3RoVmFsaWRpdHk7XG4gICAgY29uc3QgZW5mb3JjZWRPblRlbmFudFBvbGljeUxldmVsID0gdGhpcy50ZW5hbnRQb2xpY2llc1NlcnZpY2VQcm92aWRlclxuICAgICAgPyBhd2FpdCB0aGlzLnRlbmFudFBvbGljaWVzU2VydmljZVByb3ZpZGVyLmRvZXNFbmZvcmNlU3Ryb25nUGFzc3dvcmQodGhpcy50ZW5hbnRQb2xpY3kpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGlmICh0aGlzLmlzTmV3KSB7XG4gICAgICB0aGlzLnBhc3N3b3JkU3RyZW5ndGhFbmZvcmNlZCA9IGVuZm9yY2VkT25TeXN0ZW1MZXZlbCB8fCBlbmZvcmNlZE9uVGVuYW50UG9saWN5TGV2ZWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFzc3dvcmRTdHJlbmd0aEVuZm9yY2VkID0gZW5mb3JjZWRPblN5c3RlbUxldmVsIHx8IGVuZm9yY2VkT25UZW5hbnRMZXZlbDtcbiAgICB9XG4gIH1cblxuICBzZXRGb3JtKCk6IHZvaWQge1xuICAgIHRoaXMudGVuYW50Rm9ybS5wYXRjaFZhbHVlKHtcbiAgICAgIHRlbmFudElkOiB0aGlzLnRlbmFudC5pZCxcbiAgICAgIGRvbWFpbjogdGhpcy50ZW5hbnQuZG9tYWluLFxuICAgICAgY29tcGFueU5hbWU6IHRoaXMudGVuYW50LmNvbXBhbnksXG4gICAgICBjb250YWN0TmFtZTogdGhpcy50ZW5hbnQuY29udGFjdE5hbWUsXG4gICAgICBjb250YWN0UGhvbmU6IHRoaXMudGVuYW50LmNvbnRhY3RQaG9uZSxcbiAgICAgIGFkbWluaXN0cmF0b3JFbWFpbDogdGhpcy50ZW5hbnQuYWRtaW5FbWFpbCxcbiAgICAgIGFkbWluaXN0cmF0b3JVc2VybmFtZTogdGhpcy50ZW5hbnQuYWRtaW5OYW1lLFxuICAgICAgc2VuZFBhc3N3b3JkUmVzZXRFbWFpbDogdGhpcy50ZW5hbnQuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCxcbiAgICAgIGFsbG93Q3JlYXRlVGVuYW50czogdGhpcy50ZW5hbnQuYWxsb3dDcmVhdGVUZW5hbnRzLFxuICAgICAgZXh0ZXJuYWxSZWZlcmVuY2U6IHRoaXMudGVuYW50LmN1c3RvbVByb3BlcnRpZXMuZXh0ZXJuYWxSZWZlcmVuY2UsXG4gICAgICBnYWluc2lnaHRFbmFibGVkOiB0aGlzLnRlbmFudC5jdXN0b21Qcm9wZXJ0aWVzLmdhaW5zaWdodEVuYWJsZWRcbiAgICB9KTtcbiAgfVxuXG4gIGdldFRlbmFudElkKCk6IHZvaWQge1xuICAgIHRoaXMudGVuYW50SWQgPSB0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnBhcmVudC5kYXRhLmNvbnRleHREYXRhLmlkO1xuICAgIHRoaXMuaXNOZXcgPSAhdGhpcy50ZW5hbnRJZDtcbiAgfVxuXG4gIGFzeW5jIG9uU3VibWl0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCB0ZW5hbnRUb0JlU2F2ZWQ6IElUZW5hbnQ7XG5cbiAgICBpZiAoIXRoaXMuaXNOZXcpIHtcbiAgICAgIGNvbnN0IGZvcm1SYXdWYWx1ZSA9IHRoaXMudGVuYW50Rm9ybS5nZXRSYXdWYWx1ZSgpO1xuICAgICAgY29uc3QgY3VzdG9tUHJvcGVydGllcyA9IHtcbiAgICAgICAgLi4udGhpcy50ZW5hbnQuY3VzdG9tUHJvcGVydGllcyxcbiAgICAgICAgZXh0ZXJuYWxSZWZlcmVuY2U6IGZvcm1SYXdWYWx1ZS5leHRlcm5hbFJlZmVyZW5jZSxcbiAgICAgICAgZ2FpbnNpZ2h0RW5hYmxlZDogZm9ybVJhd1ZhbHVlLmdhaW5zaWdodEVuYWJsZWRcbiAgICAgIH07XG4gICAgICB0ZW5hbnRUb0JlU2F2ZWQgPSB7XG4gICAgICAgIGlkOiB0aGlzLnRlbmFudC5pZCxcbiAgICAgICAgY29tcGFueTogZm9ybVJhd1ZhbHVlLmNvbXBhbnlOYW1lLFxuICAgICAgICBjb250YWN0TmFtZTogZm9ybVJhd1ZhbHVlLmNvbnRhY3ROYW1lLFxuICAgICAgICBjb250YWN0UGhvbmU6IGZvcm1SYXdWYWx1ZS5jb250YWN0UGhvbmUsXG4gICAgICAgIGRvbWFpbjogZm9ybVJhd1ZhbHVlLmRvbWFpbixcbiAgICAgICAgc3RhdHVzOiB0aGlzLnRlbmFudC5zdGF0dXMsXG4gICAgICAgIGFsbG93Q3JlYXRlVGVuYW50czogdGhpcy50ZW5hbnRGb3JtLnZhbHVlLmFsbG93Q3JlYXRlVGVuYW50cyxcbiAgICAgICAgY3VzdG9tUHJvcGVydGllczogY3VzdG9tUHJvcGVydGllc1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGVuYW50VG9CZVNhdmVkID0ge1xuICAgICAgICBhZG1pbkVtYWlsOiB0aGlzLnRlbmFudEZvcm0udmFsdWUuYWRtaW5pc3RyYXRvckVtYWlsLFxuICAgICAgICBhZG1pbk5hbWU6IHRoaXMudGVuYW50Rm9ybS52YWx1ZS5hZG1pbmlzdHJhdG9yVXNlcm5hbWUsXG4gICAgICAgIGNvbXBhbnk6IHRoaXMudGVuYW50Rm9ybS52YWx1ZS5jb21wYW55TmFtZSxcbiAgICAgICAgY29udGFjdE5hbWU6IHRoaXMudGVuYW50Rm9ybS52YWx1ZS5jb250YWN0TmFtZSxcbiAgICAgICAgY29udGFjdFBob25lOiB0aGlzLnRlbmFudEZvcm0udmFsdWUuY29udGFjdFBob25lLFxuICAgICAgICBkb21haW46IHRoaXMudGVuYW50Rm9ybS52YWx1ZS5kb21haW4sXG4gICAgICAgIGFkbWluUGFzczogdGhpcy50ZW5hbnRGb3JtLnZhbHVlLnBhc3N3b3JkLFxuICAgICAgICBzZW5kUGFzc3dvcmRSZXNldEVtYWlsOiB0aGlzLnRlbmFudEZvcm0udmFsdWUuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCxcbiAgICAgICAgdGVuYW50UG9saWN5SWQ6IHRoaXMudGVuYW50Rm9ybS52YWx1ZS50ZW5hbnRQb2xpY3k/LmlkXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzTmV3ICYmIHRoaXMuaG9zdCkge1xuICAgICAgdGVuYW50VG9CZVNhdmVkLmRvbWFpbiA9IHRlbmFudFRvQmVTYXZlZC5kb21haW4gKyB0aGlzLmhvc3Q7XG4gICAgfVxuICAgIGNvbnN0IHQ6IElUZW5hbnQgPSBjbG9uZURlZXAodGVuYW50VG9CZVNhdmVkKTtcbiAgICBpZiAodC5zdG9yYWdlTGltaXRQZXJEZXZpY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdC5zdG9yYWdlTGltaXRQZXJEZXZpY2UgPSAwO1xuICAgIH1cblxuICAgIHRoaXMuc2V0U2F2ZUluUHJvZ3Jlc3ModHJ1ZSk7XG5cbiAgICB0cnkge1xuICAgICAgbGV0IHNhdmVkVGVuYW50O1xuICAgICAgaWYgKHRoaXMuaXNOZXcpIHtcbiAgICAgICAgc2F2ZWRUZW5hbnQgPSAoYXdhaXQgdGhpcy50ZW5hbnRTZXJ2aWNlLmNyZWF0ZSh0KSkuZGF0YTtcbiAgICAgICAgaWYgKHRoaXMudGVuYW50Rm9ybS52YWx1ZS5hbGxvd0NyZWF0ZVRlbmFudHMpIHtcbiAgICAgICAgICBhc3NpZ24oc2F2ZWRUZW5hbnQsIHsgYWxsb3dDcmVhdGVUZW5hbnRzOiB0aGlzLnRlbmFudEZvcm0udmFsdWUuYWxsb3dDcmVhdGVUZW5hbnRzIH0pO1xuICAgICAgICAgIGF3YWl0IHRoaXMudGVuYW50U2VydmljZS51cGRhdGUoc2F2ZWRUZW5hbnQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzYXZlZFRlbmFudCA9IChhd2FpdCB0aGlzLnRlbmFudFNlcnZpY2UudXBkYXRlKHQpKS5kYXRhO1xuICAgICAgfVxuICAgICAgdGhpcy5zZW5kR2FpbnNpZ2h0RXZlbnQoXG4gICAgICAgIHRoaXMuaXNOZXcgPyBBQ1RJT05TLlRFTkFOVF9DUkVBVElPTl9TQVZFRCA6IEFDVElPTlMuVEVOQU5UX1BST1BFUlRJRVNfU0FWRUQsXG4gICAgICAgIHsgcmVzdWx0OiBSRVNVTFRTLlNVQ0NFU1MgfVxuICAgICAgKTtcbiAgICAgIHRoaXMub25TYXZlKHNhdmVkVGVuYW50LCB0aGlzLnRlbmFudEZvcm0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICAgIHRoaXMuc2VuZEdhaW5zaWdodEV2ZW50KFxuICAgICAgICB0aGlzLmlzTmV3ID8gQUNUSU9OUy5URU5BTlRfQ1JFQVRJT05fU0FWRUQgOiBBQ1RJT05TLlRFTkFOVF9QUk9QRVJUSUVTX1NBVkVELFxuICAgICAgICB7IHJlc3VsdDogUkVTVUxUUy5GQUlMVVJFLCBlcnJvciB9XG4gICAgICApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnNldFNhdmVJblByb2dyZXNzKGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBvblNhdmUodGVuYW50OiBJVGVuYW50LCBmb3JtOiBGb3JtR3JvdXApOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc05ldykge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMubG9jYXRpb24uZ28oYC90ZW5hbnRzLyR7dGVuYW50LmlkfWApO1xuICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgIH0sIDIwMDApO1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2Uuc3VjY2VzcyhnZXR0ZXh0KCdUZW5hbnQgc2F2ZWQuJykpO1xuICAgIH1cbiAgICBhc3NpZ24odGhpcy50ZW5hbnQsIHRlbmFudCk7XG4gICAgdGhpcy5hbGVydFNlcnZpY2Uuc3VjY2VzcyhnZXR0ZXh0KCdUZW5hbnQgc2F2ZWQuJykpO1xuICAgIGZvcm0ubWFya0FzUHJpc3RpbmUoKTtcbiAgfVxuXG4gIHNldFNhdmVJblByb2dyZXNzKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5zYXZlSW5Qcm9ncmVzcyA9IHZhbHVlO1xuICB9XG5cbiAgY2FuY2VsKCk6IHZvaWQge1xuICAgIHRoaXMubG9jYXRpb24uZ28oJ3RlbmFudHMnKTtcbiAgfVxuXG4gIHNob3VsZERpc2FibGVTYXZlKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRpc2FibGVkID0gIXRoaXMudGVuYW50Rm9ybS52YWxpZCB8fCAhdGhpcy50ZW5hbnRGb3JtLmRpcnR5IHx8IHRoaXMuc2F2ZUluUHJvZ3Jlc3M7XG5cbiAgICBpZiAodGhpcy5zaG93UGFzc3dvcmRDb21wb25lbnQpIHtcbiAgICAgIGlmICh0aGlzLnBhc3N3b3JkRm9ybSkge1xuICAgICAgICByZXR1cm4gZGlzYWJsZWQgfHwgIXRoaXMucGFzc3dvcmRGb3JtLnZhbGlkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkaXNhYmxlZDtcbiAgICB9XG4gIH1cblxuICBvbk5ld1Bhc3N3b3JkQ2hhbmdlZChuZXdQYXNzd29yZDogTmV3UGFzc3dvcmQpOiB2b2lkIHtcbiAgICB0aGlzLnRlbmFudEZvcm0uYWRkQ29udHJvbCgncGFzc3dvcmQnLCBuZXcgRm9ybUNvbnRyb2wobmV3UGFzc3dvcmQucGFzc3dvcmQpKTtcbiAgfVxuXG4gIG9uQ2hlY2tib3hDaGFuZ2UoaW5wdXRGaWVsZCk6IHZvaWQge1xuICAgIGlmIChpbnB1dEZpZWxkID09PSAnc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCcpIHtcbiAgICAgIHRoaXMuc2hvd1Bhc3N3b3JkQ29tcG9uZW50ID0gIXRoaXMudGVuYW50Rm9ybS52YWx1ZS5zZW5kUGFzc3dvcmRSZXNldEVtYWlsO1xuICAgICAgdGhpcy5yZW1vdmVQYXNzd29yZENvbnRyb2wodGhpcy5zaG93UGFzc3dvcmRDb21wb25lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0RGlzYWJsZWRTdGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNOZXcpIHtcbiAgICAgIHRoaXMudGVuYW50Rm9ybS5jb250cm9scy50ZW5hbnRJZC5kaXNhYmxlKCk7XG4gICAgICB0aGlzLnRlbmFudEZvcm0uY29udHJvbHMuZG9tYWluLmRpc2FibGUoKTtcbiAgICAgIHRoaXMudGVuYW50Rm9ybS5jb250cm9scy5hZG1pbmlzdHJhdG9yRW1haWwuZGlzYWJsZSgpO1xuICAgICAgdGhpcy50ZW5hbnRGb3JtLmNvbnRyb2xzLmFkbWluaXN0cmF0b3JVc2VybmFtZS5kaXNhYmxlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzaG91bGRTaG93U3VidGVuYW50Q2hlY2tib3goKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgY3VycmVudFRlbmFudElzTWFuYWdlbWVudCA9IGF3YWl0IHRoaXMudGVuYW50VWlTZXJ2aWNlLmlzTWFuYWdlbWVudFRlbmFudCgpO1xuICAgIGNvbnN0IGVkaXRlZFRlbmFudElzQ2hpbGRPZk1hbmFnZW1lbnQgPVxuICAgICAgdGhpcy50ZW5hbnQgJiYgdGhpcy50ZW5hbnQucGFyZW50ID09PSB0aGlzLk1BTkFHRU1FTlRfVEVOQU5UX05BTUU7XG4gICAgcmV0dXJuIGN1cnJlbnRUZW5hbnRJc01hbmFnZW1lbnQgJiYgKGVkaXRlZFRlbmFudElzQ2hpbGRPZk1hbmFnZW1lbnQgfHwgdGhpcy5pc05ldyk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZVBhc3N3b3JkQ29udHJvbChwYXNzd29yZENvbXBvbmVudFNob3duOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKCFwYXNzd29yZENvbXBvbmVudFNob3duKSB7XG4gICAgICB0aGlzLnRlbmFudEZvcm0ucmVtb3ZlQ29udHJvbCgncGFzc3dvcmQnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldFRlbmFudCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy50ZW5hbnRJZCAmJiB0aGlzLnRlbmFudElkICE9PSAnbmV3Jykge1xuICAgICAgY29uc3QgZGV0YWlsZWRUZW5hbnQgPSAoYXdhaXQgdGhpcy50ZW5hbnRTZXJ2aWNlLmRldGFpbCh0aGlzLnRlbmFudElkKSkuZGF0YTtcbiAgICAgIHRoaXMudGl0bGUgPSBkZXRhaWxlZFRlbmFudC5jb21wYW55O1xuICAgICAgdGhpcy5vblRlbmFudChkZXRhaWxlZFRlbmFudCk7XG4gICAgICBhd2FpdCB0aGlzLmdlbmVyYXRlRm9ybSgpO1xuICAgICAgdGhpcy5zZXRGb3JtKCk7XG4gICAgICB0aGlzLnNldERpc2FibGVkU3RhdGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50aXRsZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KGdldHRleHQoJ05ldyB0ZW5hbnQnKSk7XG4gICAgICBhd2FpdCB0aGlzLmdlbmVyYXRlRm9ybSgpO1xuICAgICAgYXdhaXQgdGhpcy5sb2FkVGVuYW50UG9saWNpZXMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRUZW5hbnRQb2xpY2llcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy50ZW5hbnRQb2xpY2llc1NlcnZpY2VQcm92aWRlcikge1xuICAgICAgdGhpcy5vblRlbmFudFBvbGljaWVzKGF3YWl0IHRoaXMudGVuYW50UG9saWNpZXNTZXJ2aWNlUHJvdmlkZXIubGlzdCgpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEhvc3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY3VycmVudFRlbmFudCA9IGF3YWl0IHRoaXMudGVuYW50U2VydmljZS5jdXJyZW50KCk7XG4gICAgdGhpcy5ob3N0ID0gYC4ke2N1cnJlbnRUZW5hbnQuZGF0YS5kb21haW5OYW1lLnNwbGl0KCcuJykuc2xpY2UoMSkuam9pbignLicpfWA7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNoZWNrSWZJc0VudGVycHJpc2VFZGl0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuaXNFbnRlcnByaXNlRWRpdGlvblRlbmFudCA9IGF3YWl0IHRoaXMudGVuYW50VWlTZXJ2aWNlLmlzRW50ZXJwcmlzZVRlbmFudCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBvblRlbmFudFBvbGljaWVzKHRlbmFudFBvbGljaWVzKTogdm9pZCB7XG4gICAgdGhpcy50ZW5hbnRQb2xpY2llcyA9IFt0aGlzLnRlbmFudFBvbGljeU5vbmUsIC4uLnRlbmFudFBvbGljaWVzXTtcbiAgfVxuXG4gIHByaXZhdGUgb25UZW5hbnQodGVuYW50OiBJVGVuYW50ID0ge30pOiB2b2lkIHtcbiAgICB0aGlzLnRlbmFudCA9IHRlbmFudDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2VuZXJhdGVGb3JtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNob3VsZFNob3dTdWJ0ZW5hbnRDaGVja2JveCA9IGF3YWl0IHRoaXMuc2hvdWxkU2hvd1N1YnRlbmFudENoZWNrYm94KCk7XG4gICAgY29uc3QgZ2FpbnNpZ2h0QXZhaWxhYmxlID0gISEoYXdhaXQgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLmdldEdhaW5zaWdodEtleSgpKTtcbiAgICBpZiAoIXNob3VsZFNob3dTdWJ0ZW5hbnRDaGVja2JveCkge1xuICAgICAgZGVsZXRlIHRoaXMuZmllbGREZWZpbml0aW9ucy5hbGxvd0NyZWF0ZVRlbmFudHM7XG4gICAgfVxuICAgIGlmICghdGhpcy5pc05ldykge1xuICAgICAgZGVsZXRlIHRoaXMuZmllbGREZWZpbml0aW9ucy5zZW5kUGFzc3dvcmRSZXNldEVtYWlsO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc05ldyB8fCAodGhpcy5ob3N0ICYmIHRoaXMuaXNFbnRlcnByaXNlRWRpdGlvblRlbmFudCkpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLmZpZWxkRGVmaW5pdGlvbnMudGVuYW50SUQ7XG4gICAgfVxuICAgIGlmICghdGhpcy5pc05ldyAmJiAhdGhpcy5ob3N0KSB7XG4gICAgICBkZWxldGUgdGhpcy5maWVsZERlZmluaXRpb25zLmRvbWFpbjtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNOZXcgfHwgIWdhaW5zaWdodEF2YWlsYWJsZSkge1xuICAgICAgZGVsZXRlIHRoaXMuZmllbGREZWZpbml0aW9ucy5nYWluc2lnaHRFbmFibGVkO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc05ldykge1xuICAgICAgZGVsZXRlIHRoaXMuZmllbGREZWZpbml0aW9ucy5leHRlcm5hbFJlZmVyZW5jZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIE9iamVjdC52YWx1ZXModGhpcy5maWVsZERlZmluaXRpb25zKSkge1xuICAgICAgdGhpcy50ZW5hbnRGb3JtLmFkZENvbnRyb2woZmllbGQuaWQsIG5ldyBGb3JtQ29udHJvbChmaWVsZC5kZWZhdWx0VmFsdWUsIGZpZWxkLnZhbGlkYXRvcnMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmZpZWxkS2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuZmllbGREZWZpbml0aW9ucyk7XG4gIH1cblxuICBwcml2YXRlIHNlbmRHYWluc2lnaHRFdmVudChcbiAgICBhY3Rpb246IFRlbmFudE1hbmFnZW1lbnRBY3Rpb25UeXBlLFxuICAgIHByb3BzOiB7IHJlc3VsdD86IFRlbmFudE1hbmFnZW1lbnRSZXN1bHRUeXBlOyBlcnJvcj86IHVua25vd24gfSA9IHt9XG4gICkge1xuICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS50cmlnZ2VyRXZlbnQoRVZFTlRTLlRFTkFOVF9NQU5BR0VNRU5ULCB7XG4gICAgICBjb21wb25lbnQ6IENPTVBPTkVOVFMuVEVOQU5UX0ZPUk0sXG4gICAgICBhY3Rpb24sXG4gICAgICAuLi5wcm9wc1xuICAgIH0pO1xuICB9XG59XG4iLCI8Yzh5LXRpdGxlICpuZ0lmPVwidGl0bGVcIj5cbiAge3sgdGl0bGUgfX1cbjwvYzh5LXRpdGxlPlxuXG48Yzh5LWJyZWFkY3J1bWI+XG4gIDxjOHktYnJlYWRjcnVtYi1pdGVtXG4gICAgW2ljb25dPVwiJ2M4eS1sYXllcnMnXCJcbiAgICBbbGFiZWxdPVwiJ1RlbmFudHMnIHwgdHJhbnNsYXRlXCJcbiAgPjwvYzh5LWJyZWFkY3J1bWItaXRlbT5cbiAgPGM4eS1icmVhZGNydW1iLWl0ZW1cbiAgICBbaWNvbl09XCInYzh5LWxheWVycydcIlxuICAgIFtsYWJlbF09XCInU3VidGVuYW50cycgfCB0cmFuc2xhdGVcIlxuICAgIFtwYXRoXT1cIicvdGVuYW50cydcIlxuICA+PC9jOHktYnJlYWRjcnVtYi1pdGVtPlxuPC9jOHktYnJlYWRjcnVtYj5cblxuPGZvcm1cbiAgW2Zvcm1Hcm91cF09XCJ0ZW5hbnRGb3JtXCJcbiAgKG5nU3VibWl0KT1cIm9uU3VibWl0KClcIlxuPlxuICA8ZGl2IGNsYXNzPVwiY2FyZCBjb250ZW50LWZ1bGxwYWdlIGQtZ3JpZCBncmlkX19jb2wtLTgtNC0tbWRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaW5uZXItc2Nyb2xsIGJnLWxldmVsLTBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBzZXBhcmF0b3IgbGFyZ2UtcGFkZGluZyBzdGlja3ktdG9wXCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImNhcmQtdGl0bGVcIlxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICA+XG4gICAgICAgICAgSWRlbnRpZmljYXRpb25cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiY2FyZC1ibG9ja1wiXG4gICAgICAgICAgKm5nSWY9XCIhaW5pdGlhbGl6ZWRcIlxuICAgICAgICA+XG4gICAgICAgICAgPGM4eS1sb2FkaW5nPjwvYzh5LWxvYWRpbmc+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImNhcmQtYmxvY2tcIlxuICAgICAgICAgICpuZ0lmPVwiaW5pdGlhbGl6ZWRcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQga2V5IG9mIGZpZWxkS2V5c1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZpZWxkRGVmaW5pdGlvbnNba2V5XS50eXBlID09PSAndGV4dCdcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwidGV4dEZpZWxkOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogZmllbGREZWZpbml0aW9uc1trZXldIH1cIlxuICAgICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWVsZERlZmluaXRpb25zW2tleV0udHlwZSA9PT0gJ251bWJlcidcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwibnVtYmVyRmllbGQ7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBmaWVsZERlZmluaXRpb25zW2tleV0gfVwiXG4gICAgICAgICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZpZWxkRGVmaW5pdGlvbnNba2V5XS50eXBlID09PSAnY2hlY2tib3gnXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cImNoZWNrYm94RmllbGQ7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBmaWVsZERlZmluaXRpb25zW2tleV0gfVwiXG4gICAgICAgICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZpZWxkRGVmaW5pdGlvbnNba2V5XS50eXBlID09PSAnc2VsZWN0J1wiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzZWxlY3RGaWVsZDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGZpZWxkRGVmaW5pdGlvbnNba2V5XSB9XCJcbiAgICAgICAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJpbm5lci1zY3JvbGwgYmctbGV2ZWwtMVwiXG4gICAgICAqbmdJZj1cIiFpc05ldyAmJiB0ZW5hbnRcIlxuICAgID5cbiAgICAgIDxjOHktc3VwcG9ydC11c2VyLWFjY2VzcyBbdGVuYW50XT1cInRlbmFudFwiPjwvYzh5LXN1cHBvcnQtdXNlci1hY2Nlc3M+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEZPT1RFUiBDQVJEIC0tPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiY2FyZC1mb290ZXIgc2VwYXJhdG9yIGxhcmdlLXBhZGRpbmcgZ3JpZF9fY29sLS1mdWxsc3BhblwiXG4gICAgICAqbmdJZj1cImluaXRpYWxpemVkXCJcbiAgICA+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICAgICAgdGl0bGU9XCJ7eyAnQ2FuY2VsJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBbcm91dGVyTGlua109XCJbJy90ZW5hbnRzJ11cIlxuICAgICAgICBkYXRhLWN5PVwiYzh5LXRlbmFudC1mb3JtLS1jYW5jZWxCdXR0b25cIlxuICAgICAgPlxuICAgICAgICB7eyAnQ2FuY2VsJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgICAgdGl0bGU9XCJ7eyAnU2F2ZScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICB0eXBlPVwic3VibWl0XCJcbiAgICAgICAgW2Rpc2FibGVkXT1cInNob3VsZERpc2FibGVTYXZlKClcIlxuICAgICAgICBkYXRhLWN5PVwiYzh5LXRlbmFudC1mb3JtLS1zYXZlQnV0dG9uXCJcbiAgICAgID5cbiAgICAgICAge3sgJ1NhdmUnIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBORyBURU1QTEFURVMgLS0+XG4gIDxuZy10ZW1wbGF0ZVxuICAgICN0ZXh0RmllbGRcbiAgICBsZXQtZmllbGREZWZpbml0aW9uXG4gID5cbiAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICA8bGFiZWwgW2Zvcl09XCJmaWVsZERlZmluaXRpb24uaWRcIj5cbiAgICAgICAge3sgZmllbGREZWZpbml0aW9uLmxhYmVsIHwgdHJhbnNsYXRlOiBmaWVsZERlZmluaXRpb24ubGFiZWxBcmdzIH19XG4gICAgICA8L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgW2lkXT1cImZpZWxkRGVmaW5pdGlvbi5pZFwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImZpZWxkRGVmaW5pdGlvbi5wbGFjZWhvbGRlciB8IHRyYW5zbGF0ZTogZmllbGREZWZpbml0aW9uLnBsYWNlaG9sZGVyQXJnc1wiXG4gICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZERlZmluaXRpb24uaWRcIlxuICAgICAgICAgIFthdHRyLmRhdGEtY3ldPVwiJ2M4eS10ZW5hbnQtZm9ybS0tJyArIGZpZWxkRGVmaW5pdGlvbi5pZFwiXG4gICAgICAgIC8+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgY2xhc3M9XCJpbnB1dC1ncm91cC1hZGRvblwiXG4gICAgICAgICAgKm5nSWY9XCJmaWVsZERlZmluaXRpb24uaWQgPT09ICdkb21haW4nICYmIGhvc3QgJiYgaXNOZXdcIlxuICAgICAgICA+XG4gICAgICAgICAge3sgaG9zdCB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZVxuICAgICNudW1iZXJGaWVsZFxuICAgIGxldC1maWVsZERlZmluaXRpb25cbiAgPlxuICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgIDxsYWJlbCBbZm9yXT1cImZpZWxkRGVmaW5pdGlvbi5pZFwiPlxuICAgICAgICB7eyBmaWVsZERlZmluaXRpb24ubGFiZWwgfCB0cmFuc2xhdGU6IGZpZWxkRGVmaW5pdGlvbi5sYWJlbEFyZ3MgfX1cbiAgICAgIDwvbGFiZWw+XG4gICAgICA8aW5wdXRcbiAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgW2lkXT1cImZpZWxkRGVmaW5pdGlvbi5pZFwiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJmaWVsZERlZmluaXRpb24ucGxhY2Vob2xkZXIgfCB0cmFuc2xhdGU6IGZpZWxkRGVmaW5pdGlvbi5wbGFjZWhvbGRlckFyZ3NcIlxuICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkRGVmaW5pdGlvbi5pZFwiXG4gICAgICAgIFthdHRyLmRhdGEtY3ldPVwiJ2M4eS10ZW5hbnQtZm9ybS0tJyArIGZpZWxkRGVmaW5pdGlvbi5pZFwiXG4gICAgICAvPlxuICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPG5nLXRlbXBsYXRlXG4gICAgI2NoZWNrYm94RmllbGRcbiAgICBsZXQtZmllbGREZWZpbml0aW9uXG4gID5cbiAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICA8bGFiZWxcbiAgICAgICAgY2xhc3M9XCJjOHktY2hlY2tib3hcIlxuICAgICAgICBbdGl0bGVdPVwiZmllbGREZWZpbml0aW9uLmxhYmVsIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgW2Zvcl09XCJmaWVsZERlZmluaXRpb24uaWRcIlxuICAgICAgPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgIFtpZF09XCJmaWVsZERlZmluaXRpb24uaWRcIlxuICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGREZWZpbml0aW9uLmlkXCJcbiAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hlY2tib3hDaGFuZ2UoZmllbGREZWZpbml0aW9uLmlkKVwiXG4gICAgICAgICAgW2F0dHIuZGF0YS1jeV09XCInYzh5LXRlbmFudC1mb3JtLS0nICsgZmllbGREZWZpbml0aW9uLmlkXCJcbiAgICAgICAgLz5cbiAgICAgICAgPHNwYW4+PC9zcGFuPlxuICAgICAgICA8c3Bhbj57eyBmaWVsZERlZmluaXRpb24ubGFiZWwgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICA8L2xhYmVsPlxuICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gICAgPGZvcm1cbiAgICAgICNwYXNzd29yZEZvcm09XCJuZ0Zvcm1cIlxuICAgICAgKm5nSWY9XCJzaG93UGFzc3dvcmRDb21wb25lbnQgJiYgZmllbGREZWZpbml0aW9uLmlkID09PSAnc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCdcIlxuICAgID5cbiAgICAgIDxjOHktbmV3LXBhc3N3b3JkXG4gICAgICAgIFtzaG93Q2hhbmdlUGFzc3dvcmRCdXR0b25dPVwiZmFsc2VcIlxuICAgICAgICBbcmVxdWlyZVN0cm9uZ1Bhc3N3b3JkXT1cInBhc3N3b3JkU3RyZW5ndGhFbmZvcmNlZFwiXG4gICAgICAgIChwYXNzd29yZCk9XCJvbk5ld1Bhc3N3b3JkQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICAgID48L2M4eS1uZXctcGFzc3dvcmQ+XG4gICAgPC9mb3JtPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZVxuICAgICNzZWxlY3RGaWVsZFxuICAgIGxldC1maWVsZERlZmluaXRpb25cbiAgPlxuICAgIDxjOHktZm9ybS1ncm91cCAqbmdJZj1cInRlbmFudFBvbGljaWVzICYmIHRlbmFudFBvbGljaWVzLmxlbmd0aCA+IDBcIj5cbiAgICAgIDxsYWJlbD57eyBmaWVsZERlZmluaXRpb24ubGFiZWwgfCB0cmFuc2xhdGUgfX08L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImM4eS1zZWxlY3Qtd3JhcHBlclwiPlxuICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgIHRpdGxlPVwie3sgZmllbGREZWZpbml0aW9uLmxhYmVsIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICBuYW1lPVwidGVuYW50UG9saWN5XCJcbiAgICAgICAgICAoY2hhbmdlKT1cIm9uVGVuYW50UG9saWN5Q2hhbmdlKClcIlxuICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInRlbmFudFBvbGljeVwiXG4gICAgICAgICAgW2F0dHIuZGF0YS1jeV09XCInYzh5LXRlbmFudC1mb3JtLS0nICsgZmllbGREZWZpbml0aW9uLmlkXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxvcHRpb25cbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCB0ZW5hbnRQb2xpY3kgb2YgdGVuYW50UG9saWNpZXNcIlxuICAgICAgICAgICAgW25nVmFsdWVdPVwidGVuYW50UG9saWN5XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyB0ZW5hbnRQb2xpY3kubmFtZSB9fVxuICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgPHNwYW4+PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9jOHktZm9ybS1ncm91cD5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvZm9ybT5cbiJdfQ==
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Validators } from '@angular/forms';
|
|
2
2
|
import { gettext } from '@c8y/ngx-components/gettext';
|
|
3
|
+
const MAX_DEVICE_STORAGE_LIMIT_MiB = Math.round(Number.MAX_SAFE_INTEGER / 1024 / 1024);
|
|
3
4
|
/**
|
|
4
5
|
* Define all hardTyped custom properties, and their configuration in one place.
|
|
5
6
|
*
|
|
@@ -7,15 +8,6 @@ import { gettext } from '@c8y/ngx-components/gettext';
|
|
|
7
8
|
* while still benefiting from hard typing, thanks to "satisfies" keyword
|
|
8
9
|
*/
|
|
9
10
|
const tenantLimitsCustomPropertiesDefinition = {
|
|
10
|
-
//TODO: External reference - going to be moved to the Properties tab.
|
|
11
|
-
externalReference: {
|
|
12
|
-
id: 'externalReference',
|
|
13
|
-
validators: [],
|
|
14
|
-
defaultValue: null,
|
|
15
|
-
type: 'text',
|
|
16
|
-
label: gettext('External reference'),
|
|
17
|
-
placeholder: gettext('e.g. REF12345`reference number`')
|
|
18
|
-
},
|
|
19
11
|
limitDevicesNumber: {
|
|
20
12
|
id: 'limit.devices.number',
|
|
21
13
|
validators: [Validators.min(0)],
|
|
@@ -79,14 +71,15 @@ const tenantLimitsCustomPropertiesDefinition = {
|
|
|
79
71
|
placeholder: gettext('e.g. {{ example }}'),
|
|
80
72
|
placeholderArgs: { example: 100 }
|
|
81
73
|
},
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
74
|
+
deviceStorageLimitMiB: {
|
|
75
|
+
id: 'deviceStorageLimitMiB',
|
|
76
|
+
validators: [Validators.min(0), Validators.max(MAX_DEVICE_STORAGE_LIMIT_MiB)],
|
|
77
|
+
defaultValue: 0,
|
|
78
|
+
type: 'number',
|
|
79
|
+
label: gettext('Storage limit per device (MiB)'),
|
|
80
|
+
placeholder: gettext('e.g. {{ example }}'),
|
|
81
|
+
placeholderArgs: { example: 100 }
|
|
89
82
|
}
|
|
90
83
|
};
|
|
91
84
|
export const tenantLimitsCustomProperties = tenantLimitsCustomPropertiesDefinition;
|
|
92
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWxpbWl0cy1kZWZpbml0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RlbmFudHMvdGVuYW50LWxpbWl0cy90ZW5hbnQtbGltaXRzLWRlZmluaXRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFjdEQsTUFBTSw0QkFBNEIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFFdkY7Ozs7O0dBS0c7QUFDSCxNQUFNLHNDQUFzQyxHQUFHO0lBQzdDLGtCQUFrQixFQUFFO1FBQ2xCLEVBQUUsRUFBRSxzQkFBc0I7UUFDMUIsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQixZQUFZLEVBQUUsSUFBSTtRQUNsQixJQUFJLEVBQUUsUUFBUTtRQUNkLEtBQUssRUFBRSxPQUFPLENBQUMseUJBQXlCLENBQUM7UUFDekMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQztRQUMxQyxlQUFlLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFO0tBQ25DO0lBQ0QsaUJBQWlCLEVBQUU7UUFDakIsRUFBRSxFQUFFLHFCQUFxQjtRQUN6QixVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsWUFBWSxFQUFFLElBQUk7UUFDbEIsSUFBSSxFQUFFLFFBQVE7UUFDZCxLQUFLLEVBQUUsT0FBTyxDQUFDLHFCQUFxQixDQUFDO1FBQ3JDLFdBQVcsRUFBRSxPQUFPLENBQUMsb0JBQW9CLENBQUM7UUFDMUMsZUFBZSxFQUFFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRTtLQUNwQztJQUNELGNBQWMsRUFBRTtRQUNkLEVBQUUsRUFBRSxrQkFBa0I7UUFDdEIsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLFlBQVksRUFBRSxJQUFJO1FBQ2xCLElBQUksRUFBRSxRQUFRO1FBQ2QsS0FBSyxFQUFFLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUNsQyxXQUFXLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDO1FBQzFDLGVBQWUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUU7S0FDbEM7SUFDRCxtQkFBbUIsRUFBRTtRQUNuQixFQUFFLEVBQUUsdUJBQXVCO1FBQzNCLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxZQUFZLEVBQUUsSUFBSTtRQUNsQixJQUFJLEVBQUUsUUFBUTtRQUNkLEtBQUssRUFBRSxPQUFPLENBQUMsdUJBQXVCLENBQUM7UUFDdkMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQztRQUMxQyxlQUFlLEVBQUUsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFO0tBQ2xDO0lBQ0QsZ0JBQWdCLEVBQUU7UUFDaEIsRUFBRSxFQUFFLG9CQUFvQjtRQUN4QixVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsWUFBWSxFQUFFLElBQUk7UUFDbEIsSUFBSSxFQUFFLFFBQVE7UUFDZCxLQUFLLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDO1FBQ3BDLFdBQVcsRUFBRSxPQUFPLENBQUMsb0JBQW9CLENBQUM7UUFDMUMsZUFBZSxFQUFFLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRTtLQUNsQztJQUNELG1CQUFtQixFQUFFO1FBQ25CLEVBQUUsRUFBRSx1QkFBdUI7UUFDM0IsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLFlBQVksRUFBRSxJQUFJO1FBQ2xCLElBQUksRUFBRSxRQUFRO1FBQ2QsS0FBSyxFQUFFLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQztRQUN4QyxXQUFXLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDO1FBQzFDLGVBQWUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUU7S0FDbEM7SUFDRCxvQkFBb0IsRUFBRTtRQUNwQixFQUFFLEVBQUUseUJBQXlCO1FBQzdCLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0IsWUFBWSxFQUFFLElBQUk7UUFDbEIsSUFBSSxFQUFFLFFBQVE7UUFDZCxLQUFLLEVBQUUsT0FBTyxDQUFDLHlCQUF5QixDQUFDO1FBQ3pDLFdBQVcsRUFBRSxPQUFPLENBQUMsb0JBQW9CLENBQUM7UUFDMUMsZUFBZSxFQUFFLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRTtLQUNsQztJQUNELHFCQUFxQixFQUFFO1FBQ3JCLEVBQUUsRUFBRSx1QkFBdUI7UUFDM0IsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDN0UsWUFBWSxFQUFFLENBQUM7UUFDZixJQUFJLEVBQUUsUUFBUTtRQUNkLEtBQUssRUFBRSxPQUFPLENBQUMsZ0NBQWdDLENBQUM7UUFDaEQsV0FBVyxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQztRQUMxQyxlQUFlLEVBQUUsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFO0tBQ2xDO0NBQ29DLENBQUM7QUFJeEMsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBRXJDLHNDQUFzQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBnZXR0ZXh0IH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9nZXR0ZXh0JztcblxuLy8gTW9kZWwgZm9yIGluZGl2aWR1YWwgdGVuYW50IGxpbWl0IGZpZWxkXG5leHBvcnQgaW50ZXJmYWNlIFRlbmFudExpbWl0IHtcbiAgaWQ6IHN0cmluZztcbiAgdmFsaWRhdG9yczogVmFsaWRhdG9yRm5bXTtcbiAgZGVmYXVsdFZhbHVlOiBudW1iZXIgfCBzdHJpbmcgfCBib29sZWFuIHwgbnVsbDtcbiAgdHlwZTogJ3RleHQnIHwgJ2NoZWNrYm94JyB8ICdudW1iZXInO1xuICBsYWJlbDogc3RyaW5nO1xuICBsYWJlbEFyZ3M/OiBvYmplY3Q7XG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICBwbGFjZWhvbGRlckFyZ3M/OiBvYmplY3Q7XG59XG5cbmNvbnN0IE1BWF9ERVZJQ0VfU1RPUkFHRV9MSU1JVF9NaUIgPSBNYXRoLnJvdW5kKE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIC8gMTAyNCAvIDEwMjQpO1xuXG4vKipcbiAqIERlZmluZSBhbGwgaGFyZFR5cGVkIGN1c3RvbSBwcm9wZXJ0aWVzLCBhbmQgdGhlaXIgY29uZmlndXJhdGlvbiBpbiBvbmUgcGxhY2UuXG4gKlxuICogVGhpcyBleHBvcnRlZCBjb25zdCB1dGlsaXplcyB0eXBlc2NyaXB0IGluZmVycmluZyxcbiAqIHdoaWxlIHN0aWxsIGJlbmVmaXRpbmcgZnJvbSBoYXJkIHR5cGluZywgdGhhbmtzIHRvIFwic2F0aXNmaWVzXCIga2V5d29yZFxuICovXG5jb25zdCB0ZW5hbnRMaW1pdHNDdXN0b21Qcm9wZXJ0aWVzRGVmaW5pdGlvbiA9IHtcbiAgbGltaXREZXZpY2VzTnVtYmVyOiB7XG4gICAgaWQ6ICdsaW1pdC5kZXZpY2VzLm51bWJlcicsXG4gICAgdmFsaWRhdG9yczogW1ZhbGlkYXRvcnMubWluKDApXSxcbiAgICBkZWZhdWx0VmFsdWU6IG51bGwsXG4gICAgdHlwZTogJ251bWJlcicsXG4gICAgbGFiZWw6IGdldHRleHQoJ0xpbWl0IG51bWJlciBvZiBkZXZpY2VzJyksXG4gICAgcGxhY2Vob2xkZXI6IGdldHRleHQoJ2UuZy4ge3sgZXhhbXBsZSB9fScpLFxuICAgIHBsYWNlaG9sZGVyQXJnczogeyBleGFtcGxlOiAxMDAwIH1cbiAgfSxcbiAgbGltaXRIdHRwUmVxdWVzdHM6IHtcbiAgICBpZDogJ2xpbWl0Lmh0dHAucmVxdWVzdHMnLFxuICAgIHZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLm1pbigtMSldLFxuICAgIGRlZmF1bHRWYWx1ZTogbnVsbCxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBsYWJlbDogZ2V0dGV4dCgnTGltaXQgSFRUUCByZXF1ZXN0cycpLFxuICAgIHBsYWNlaG9sZGVyOiBnZXR0ZXh0KCdlLmcuIHt7IGV4YW1wbGUgfX0nKSxcbiAgICBwbGFjZWhvbGRlckFyZ3M6IHsgZXhhbXBsZTogMTAwMDAgfVxuICB9LFxuICBsaW1pdEh0dHBRdWV1ZToge1xuICAgIGlkOiAnbGltaXQuaHR0cC5xdWV1ZScsXG4gICAgdmFsaWRhdG9yczogW1ZhbGlkYXRvcnMubWluKC0xKV0sXG4gICAgZGVmYXVsdFZhbHVlOiBudWxsLFxuICAgIHR5cGU6ICdudW1iZXInLFxuICAgIGxhYmVsOiBnZXR0ZXh0KCdMaW1pdCBIVFRQIHF1ZXVlJyksXG4gICAgcGxhY2Vob2xkZXI6IGdldHRleHQoJ2UuZy4ge3sgZXhhbXBsZSB9fScpLFxuICAgIHBsYWNlaG9sZGVyQXJnczogeyBleGFtcGxlOiAxMDAgfVxuICB9LFxuICBsaW1pdFN0cmVhbVJlcXVlc3RzOiB7XG4gICAgaWQ6ICdsaW1pdC5zdHJlYW0ucmVxdWVzdHMnLFxuICAgIHZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLm1pbigtMSldLFxuICAgIGRlZmF1bHRWYWx1ZTogbnVsbCxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBsYWJlbDogZ2V0dGV4dCgnTGltaXQgc3RyZWFtIHJlcXVlc3RzJyksXG4gICAgcGxhY2Vob2xkZXI6IGdldHRleHQoJ2UuZy4ge3sgZXhhbXBsZSB9fScpLFxuICAgIHBsYWNlaG9sZGVyQXJnczogeyBleGFtcGxlOiAxMDAgfVxuICB9LFxuICBsaW1pdFN0cmVhbVF1ZXVlOiB7XG4gICAgaWQ6ICdsaW1pdC5zdHJlYW0ucXVldWUnLFxuICAgIHZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLm1pbigtMSldLFxuICAgIGRlZmF1bHRWYWx1ZTogbnVsbCxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBsYWJlbDogZ2V0dGV4dCgnTGltaXQgc3RyZWFtIHF1ZXVlJyksXG4gICAgcGxhY2Vob2xkZXI6IGdldHRleHQoJ2UuZy4ge3sgZXhhbXBsZSB9fScpLFxuICAgIHBsYWNlaG9sZGVyQXJnczogeyBleGFtcGxlOiAxMDAgfVxuICB9LFxuICBjZXBTZXJ2ZXJRdWV1ZUxpbWl0OiB7XG4gICAgaWQ6ICdjZXBTZXJ2ZXIucXVldWUubGltaXQnLFxuICAgIHZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLm1pbigtMSldLFxuICAgIGRlZmF1bHRWYWx1ZTogbnVsbCxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBsYWJlbDogZ2V0dGV4dCgnTGltaXQgQ0VQIHNlcnZlciBxdWV1ZScpLFxuICAgIHBsYWNlaG9sZGVyOiBnZXR0ZXh0KCdlLmcuIHt7IGV4YW1wbGUgfX0nKSxcbiAgICBwbGFjZWhvbGRlckFyZ3M6IHsgZXhhbXBsZTogMTAwIH1cbiAgfSxcbiAgZGF0YUJyb2tlclF1ZXVlTGltaXQ6IHtcbiAgICBpZDogJ2RhdGEtYnJva2VyLnF1ZXVlLmxpbWl0JyxcbiAgICB2YWxpZGF0b3JzOiBbVmFsaWRhdG9ycy5taW4oMCldLFxuICAgIGRlZmF1bHRWYWx1ZTogbnVsbCxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBsYWJlbDogZ2V0dGV4dCgnTGltaXQgZGF0YSBicm9rZXIgcXVldWUnKSxcbiAgICBwbGFjZWhvbGRlcjogZ2V0dGV4dCgnZS5nLiB7eyBleGFtcGxlIH19JyksXG4gICAgcGxhY2Vob2xkZXJBcmdzOiB7IGV4YW1wbGU6IDEwMCB9XG4gIH0sXG4gIGRldmljZVN0b3JhZ2VMaW1pdE1pQjoge1xuICAgIGlkOiAnZGV2aWNlU3RvcmFnZUxpbWl0TWlCJyxcbiAgICB2YWxpZGF0b3JzOiBbVmFsaWRhdG9ycy5taW4oMCksIFZhbGlkYXRvcnMubWF4KE1BWF9ERVZJQ0VfU1RPUkFHRV9MSU1JVF9NaUIpXSxcbiAgICBkZWZhdWx0VmFsdWU6IDAsXG4gICAgdHlwZTogJ251bWJlcicsXG4gICAgbGFiZWw6IGdldHRleHQoJ1N0b3JhZ2UgbGltaXQgcGVyIGRldmljZSAoTWlCKScpLFxuICAgIHBsYWNlaG9sZGVyOiBnZXR0ZXh0KCdlLmcuIHt7IGV4YW1wbGUgfX0nKSxcbiAgICBwbGFjZWhvbGRlckFyZ3M6IHsgZXhhbXBsZTogMTAwIH1cbiAgfVxufSBzYXRpc2ZpZXMgUmVjb3JkPHN0cmluZywgVGVuYW50TGltaXQ+O1xuXG5leHBvcnQgdHlwZSBUZW5hbnRMaW1pdHNDdXN0b21Qcm9wZXJ0aWVzS2V5cyA9IGtleW9mIHR5cGVvZiB0ZW5hbnRMaW1pdHNDdXN0b21Qcm9wZXJ0aWVzRGVmaW5pdGlvbjtcblxuZXhwb3J0IGNvbnN0IHRlbmFudExpbWl0c0N1c3RvbVByb3BlcnRpZXM6IHtcbiAgW0sgaW4gVGVuYW50TGltaXRzQ3VzdG9tUHJvcGVydGllc0tleXNdOiBUZW5hbnRMaW1pdDtcbn0gPSB0ZW5hbnRMaW1pdHNDdXN0b21Qcm9wZXJ0aWVzRGVmaW5pdGlvbjtcbiJdfQ==
|