@smarterplan/ngx-smarterplan-admin 0.2.2 → 0.3.0

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.
Files changed (64) hide show
  1. package/esm2022/lib/admin/admin.component.mjs +36 -0
  2. package/esm2022/lib/chevron/chevron.component.mjs +19 -0
  3. package/{esm2020 → esm2022}/lib/guest-link/guest-link.component.mjs +70 -62
  4. package/esm2022/lib/guide.guard.mjs +29 -0
  5. package/{esm2020 → esm2022}/lib/helpers.mjs +24 -24
  6. package/esm2022/lib/name-from-id.pipe.mjs +31 -0
  7. package/esm2022/lib/ngx-smarterplan-admin-routing.module.mjs +48 -0
  8. package/esm2022/lib/ngx-smarterplan-admin.module.mjs +89 -0
  9. package/esm2022/lib/ngx-smarterplan-admin.service.mjs +15 -0
  10. package/esm2022/lib/organisation/organisation.component.mjs +182 -0
  11. package/esm2022/lib/sp-admin.guard.mjs +29 -0
  12. package/esm2022/lib/user/detail-organisation/detail-organisation.component.mjs +207 -0
  13. package/esm2022/lib/user/form-mission/form-mission.component.mjs +290 -0
  14. package/esm2022/lib/user/form-organisation/form-organisation.component.mjs +139 -0
  15. package/esm2022/lib/user/user-mission-form/user-mission-form.component.mjs +132 -0
  16. package/esm2022/lib/user/user.component.mjs +353 -0
  17. package/esm2022/lib/visitor/create-batch/create-batch.component.mjs +112 -0
  18. package/esm2022/lib/visitor/template/template.component.mjs +295 -0
  19. package/esm2022/lib/visitor/visitor.component.mjs +318 -0
  20. package/{esm2020 → esm2022}/public-api.mjs +5 -5
  21. package/{esm2020 → esm2022}/smarterplan-ngx-smarterplan-admin.mjs +4 -4
  22. package/{fesm2020 → fesm2022}/smarterplan-ngx-smarterplan-admin.mjs +2205 -2065
  23. package/{fesm2015 → fesm2022}/smarterplan-ngx-smarterplan-admin.mjs.map +1 -1
  24. package/index.d.ts +5 -5
  25. package/lib/admin/admin.component.d.ts +13 -13
  26. package/lib/chevron/chevron.component.d.ts +9 -9
  27. package/lib/guest-link/guest-link.component.d.ts +20 -20
  28. package/lib/guide.guard.d.ts +11 -11
  29. package/lib/helpers.d.ts +2 -2
  30. package/lib/name-from-id.pipe.d.ts +11 -11
  31. package/lib/ngx-smarterplan-admin-routing.module.d.ts +7 -7
  32. package/lib/ngx-smarterplan-admin.module.d.ts +26 -26
  33. package/lib/ngx-smarterplan-admin.service.d.ts +6 -6
  34. package/lib/organisation/organisation.component.d.ts +54 -54
  35. package/lib/sp-admin.guard.d.ts +11 -11
  36. package/lib/user/detail-organisation/detail-organisation.component.d.ts +49 -49
  37. package/lib/user/form-mission/form-mission.component.d.ts +63 -63
  38. package/lib/user/form-organisation/form-organisation.component.d.ts +32 -32
  39. package/lib/user/user-mission-form/user-mission-form.component.d.ts +32 -32
  40. package/lib/user/user.component.d.ts +102 -102
  41. package/lib/visitor/create-batch/create-batch.component.d.ts +23 -23
  42. package/lib/visitor/template/template.component.d.ts +58 -58
  43. package/lib/visitor/visitor.component.d.ts +70 -70
  44. package/package.json +11 -17
  45. package/public-api.d.ts +2 -2
  46. package/esm2020/lib/admin/admin.component.mjs +0 -34
  47. package/esm2020/lib/chevron/chevron.component.mjs +0 -19
  48. package/esm2020/lib/guide.guard.mjs +0 -26
  49. package/esm2020/lib/name-from-id.pipe.mjs +0 -29
  50. package/esm2020/lib/ngx-smarterplan-admin-routing.module.mjs +0 -47
  51. package/esm2020/lib/ngx-smarterplan-admin.module.mjs +0 -88
  52. package/esm2020/lib/ngx-smarterplan-admin.service.mjs +0 -14
  53. package/esm2020/lib/organisation/organisation.component.mjs +0 -171
  54. package/esm2020/lib/sp-admin.guard.mjs +0 -26
  55. package/esm2020/lib/user/detail-organisation/detail-organisation.component.mjs +0 -191
  56. package/esm2020/lib/user/form-mission/form-mission.component.mjs +0 -265
  57. package/esm2020/lib/user/form-organisation/form-organisation.component.mjs +0 -125
  58. package/esm2020/lib/user/user-mission-form/user-mission-form.component.mjs +0 -121
  59. package/esm2020/lib/user/user.component.mjs +0 -336
  60. package/esm2020/lib/visitor/create-batch/create-batch.component.mjs +0 -106
  61. package/esm2020/lib/visitor/template/template.component.mjs +0 -277
  62. package/esm2020/lib/visitor/visitor.component.mjs +0 -299
  63. package/fesm2015/smarterplan-ngx-smarterplan-admin.mjs +0 -2245
  64. package/fesm2020/smarterplan-ngx-smarterplan-admin.mjs.map +0 -1
@@ -0,0 +1,290 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { LevelStatus, Locale, enumToArray, EmailStatus, stringLocaleToEnum, } from '@smarterplan/ngx-smarterplan-core';
3
+ import { DateTime } from 'luxon';
4
+ import { Validators } from '@angular/forms';
5
+ import { textValidator, noEmptyValidator, floatValidator, } from '@smarterplan/ngx-smarterplan-core';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/forms";
8
+ import * as i2 from "@smarterplan/ngx-smarterplan-core";
9
+ import * as i3 from "@ng-bootstrap/ng-bootstrap";
10
+ import * as i4 from "@angular/common";
11
+ import * as i5 from "@ngx-translate/core";
12
+ class FormMissionComponent {
13
+ fb;
14
+ spaceService;
15
+ userService;
16
+ domainService;
17
+ organisationService;
18
+ zoneService;
19
+ hashtagService;
20
+ localeService;
21
+ validatorsService;
22
+ missionToEdit;
23
+ organisationForMission;
24
+ isSP;
25
+ userForMissionID;
26
+ currentUserOrganisation;
27
+ missionForm;
28
+ availableSpaces;
29
+ addedMissionInput = new EventEmitter();
30
+ availableRoles;
31
+ availableLevels;
32
+ availableHashtags = [];
33
+ domains;
34
+ allOrgs;
35
+ isGuide = false;
36
+ zonesForSpace;
37
+ defaultZone;
38
+ missionTimeStart = 12 * 60 * 60000; // midday in milliseconds
39
+ missionTimeEnd = 12 * 60 * 60000;
40
+ addedHashtags = [];
41
+ currentLocale;
42
+ locales;
43
+ dateError = false;
44
+ errorForm = false;
45
+ constructor(fb, spaceService, userService, domainService, organisationService, zoneService, hashtagService, localeService, validatorsService) {
46
+ this.fb = fb;
47
+ this.spaceService = spaceService;
48
+ this.userService = userService;
49
+ this.domainService = domainService;
50
+ this.organisationService = organisationService;
51
+ this.zoneService = zoneService;
52
+ this.hashtagService = hashtagService;
53
+ this.localeService = localeService;
54
+ this.validatorsService = validatorsService;
55
+ }
56
+ async ngOnInit() {
57
+ this.updateUserInfo();
58
+ await this.setDomains();
59
+ if (this.isSP) {
60
+ this.allOrgs = await this.organisationService.listOrganisations();
61
+ }
62
+ this.currentLocale = stringLocaleToEnum(this.localeService.getLocale()); // to match enum Locale
63
+ this.locales = enumToArray(Locale);
64
+ if (this.missionToEdit) {
65
+ this.initFormForEdit();
66
+ }
67
+ else {
68
+ this.initEmptyForm();
69
+ }
70
+ }
71
+ updateUserInfo() {
72
+ this.availableRoles = this.userService.getAvailableRolesForCurrentUser();
73
+ this.availableLevels = this.userService.getAvalableLevelsForCurrentUser();
74
+ this.isGuide = this.userService.isGuide();
75
+ }
76
+ async setDomains() {
77
+ if (!this.isGuide) {
78
+ const domains = await this.domainService.getDomainsForMissionsForOrg(this.currentUserOrganisation.id);
79
+ this.domains = domains;
80
+ }
81
+ }
82
+ async setHashtags(spaceID) {
83
+ this.availableHashtags = await this.hashtagService.getHashtagsForSpace(spaceID);
84
+ }
85
+ get spaceID() {
86
+ return this.missionForm.get('space');
87
+ }
88
+ get role() {
89
+ return this.missionForm.get('role');
90
+ }
91
+ async initFormForEdit() {
92
+ let startDate = null;
93
+ let endDate = null;
94
+ const m = this.missionToEdit;
95
+ if (m.startDateTime) {
96
+ const date = DateTime.fromISO(m.startDateTime);
97
+ this.missionTimeStart = (date.hour * 60 + date.minute) * 60 * 1000;
98
+ startDate = date.toMillis() - this.missionTimeStart;
99
+ }
100
+ if (m.endDateTime) {
101
+ const date = DateTime.fromISO(m.endDateTime);
102
+ this.missionTimeEnd = (date.hour * 60 + date.minute) * 60 * 1000;
103
+ endDate = date.toMillis() - this.missionTimeEnd;
104
+ }
105
+ this.userForMissionID = m.userID;
106
+ this.availableSpaces = await this.spaceService.getAllowedSpacesForOrg(this.missionToEdit.organisationID, this.currentUserOrganisation.id);
107
+ await this.setHashtags(m.spaceID);
108
+ this.missionForm = this.fb.group({
109
+ id: m.id,
110
+ organisation: [{ value: m.organisation.name, disabled: true }],
111
+ organisationID: m.organisationID,
112
+ orderedOrganisationID: m.orderedOrganisationID,
113
+ role: [m.role, Validators.required],
114
+ level: [m.level],
115
+ space: [m.spaceID, Validators.required],
116
+ description: [m.description, [textValidator(), noEmptyValidator()]],
117
+ domains: [m.domains],
118
+ zone: [m.zoneID],
119
+ locale: [m.locale],
120
+ startDate: [startDate, [floatValidator()]],
121
+ endDate: [endDate, [floatValidator()]],
122
+ });
123
+ if (m.hashtags && m.hashtags.length > 0) {
124
+ this.addedHashtags = this.availableHashtags.filter((hashtag) => m.hashtags.includes(hashtag.id));
125
+ }
126
+ this.onSpaceClick();
127
+ }
128
+ async onSpaceClick() {
129
+ const zones = await this.zoneService.getZonesBySpace(this.spaceID.value);
130
+ this.defaultZone = zones.find((zone) => !zone.parentID);
131
+ const indexOfDefaultZone = zones.indexOf(this.defaultZone);
132
+ zones.splice(indexOfDefaultZone, 1);
133
+ this.zonesForSpace = zones.filter((zone) => !zone.audioID);
134
+ await this.setHashtags(this.spaceID.value);
135
+ }
136
+ async initEmptyForm() {
137
+ this.availableSpaces = await this.spaceService.getAllowedSpacesForOrg(this.organisationForMission.id, this.currentUserOrganisation.id);
138
+ this.missionForm = this.fb.group({
139
+ role: ['', Validators.required],
140
+ level: [LevelStatus.MINIMUM],
141
+ organisation: [
142
+ { value: this.organisationForMission.name, disabled: true },
143
+ ],
144
+ organisationID: this.organisationForMission.id,
145
+ orderedOrganisationID: this.currentUserOrganisation.id,
146
+ space: ['', Validators.required],
147
+ zone: [''],
148
+ description: ['', [textValidator(), noEmptyValidator()]],
149
+ domains: [null],
150
+ locale: [this.currentLocale],
151
+ startDate: [null, [floatValidator()]],
152
+ endDate: [null, [floatValidator()]],
153
+ });
154
+ }
155
+ onHashtagClick(hashtag) {
156
+ if (!this.hashtagAdded(hashtag)) {
157
+ this.addedHashtags.push(hashtag);
158
+ }
159
+ else {
160
+ this.addedHashtags.splice(this.addedHashtags.indexOf(hashtag), 1);
161
+ }
162
+ }
163
+ hashtagAdded(hashtag) {
164
+ return (this.addedHashtags.find((_hashtag) => _hashtag.id === hashtag.id) !==
165
+ undefined);
166
+ }
167
+ removeHashtag(hashtag) {
168
+ this.addedHashtags.splice(this.addedHashtags.indexOf(hashtag), 1);
169
+ }
170
+ async onSubmit() {
171
+ if (!this.missionForm.valid) {
172
+ this.errorForm = true;
173
+ return;
174
+ }
175
+ const datesValues = await this.onVerifDate();
176
+ if (datesValues.error) {
177
+ this.dateError = true;
178
+ this.errorForm = true;
179
+ return;
180
+ }
181
+ const formValue = this.missionForm.value;
182
+ // if (!this.missionForm.valid) {
183
+ // // this shows errors in the form
184
+ // this.missionForm.markAllAsTouched();
185
+ // return;
186
+ // }
187
+ // let startDateString: string;
188
+ // let endDateString: string;
189
+ // if (formValue.startDate) {
190
+ // const dateHourStartNumber = formValue.startDate + this.missionTimeStart;
191
+ // const startDate = DateTime.fromMillis(dateHourStartNumber);
192
+ // startDateString = startDate.toISO();
193
+ // }
194
+ // if (formValue.endDate) {
195
+ // const dateHourEndNumber = formValue.endDate + this.missionTimeEnd;
196
+ // const endDate = DateTime.fromMillis(dateHourEndNumber);
197
+ // endDateString = endDate.toISO();
198
+ // }
199
+ // if (endDateString && startDateString && (endDateString < startDateString)) {
200
+ // this.dateError = true;
201
+ // return;
202
+ // } else {
203
+ // this.dateError = false;
204
+ // }
205
+ const missionInput = {
206
+ organisationID: formValue.organisationID,
207
+ orderedOrganisationID: formValue.orderedOrganisationID,
208
+ level: formValue.level,
209
+ role: formValue.role,
210
+ description: formValue.description,
211
+ startDateTime: datesValues.startDateString,
212
+ endDateTime: datesValues.endDateString,
213
+ domains: formValue.domains,
214
+ userID: this.userForMissionID,
215
+ emailStatus: this.missionToEdit
216
+ ? this.missionToEdit.emailStatus
217
+ : EmailStatus.CREATION_TO_DELIVER,
218
+ locale: formValue.locale,
219
+ };
220
+ missionInput.hashtags = this.addedHashtags.map((h) => h.id);
221
+ if (formValue.space) {
222
+ missionInput.spaceID = formValue.space;
223
+ }
224
+ if (formValue.zone) {
225
+ missionInput.zoneID = formValue.zone;
226
+ }
227
+ if (this.missionToEdit) {
228
+ missionInput.id = this.missionToEdit.id;
229
+ }
230
+ this.addedMissionInput.emit(missionInput);
231
+ }
232
+ onCancel() {
233
+ this.addedMissionInput.emit(null);
234
+ }
235
+ isFormError(control) {
236
+ return control && control.invalid && this.errorForm;
237
+ }
238
+ onVerifDate() {
239
+ return new Promise((resolve) => {
240
+ const formValue = this.missionForm.getRawValue();
241
+ let startDateString;
242
+ let endDateString;
243
+ if (formValue.startDate) {
244
+ const dateHourStartNumber = formValue.startDate + this.missionTimeStart;
245
+ const startDate = DateTime.fromMillis(dateHourStartNumber);
246
+ startDateString = startDate.toISO();
247
+ }
248
+ if (formValue.endDate) {
249
+ const dateHourEndNumber = formValue.endDate + this.missionTimeEnd;
250
+ const endDate = DateTime.fromMillis(dateHourEndNumber);
251
+ endDateString = endDate.toISO();
252
+ }
253
+ if (endDateString &&
254
+ startDateString &&
255
+ endDateString <= startDateString) {
256
+ this.dateError = true;
257
+ resolve({ error: true });
258
+ }
259
+ else {
260
+ this.dateError = false;
261
+ resolve({ startDateString, endDateString });
262
+ }
263
+ });
264
+ }
265
+ async onVerifForm() {
266
+ if (this.errorForm && this.missionForm.valid && !this.dateError) {
267
+ this.errorForm = false;
268
+ }
269
+ }
270
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormMissionComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.SpaceService }, { token: i2.BaseUserService }, { token: i2.DomainService }, { token: i2.OrganisationService }, { token: i2.ZoneService }, { token: i2.HashtagService }, { token: i2.LocaleService }, { token: i2.ValidatorsService }], target: i0.ɵɵFactoryTarget.Component });
271
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FormMissionComponent, selector: "lib-form-mission", inputs: { missionToEdit: "missionToEdit", organisationForMission: "organisationForMission", isSP: "isSP", userForMissionID: "userForMissionID", currentUserOrganisation: "currentUserOrganisation" }, outputs: { addedMissionInput: "addedMissionInput" }, ngImport: i0, template: "<div class=\"form-containter\" *ngIf=\"missionForm\">\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'Mission details' | translate }}</h4>\r\n </div>\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"missionForm\">\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Organisation' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" data-testid=\"form-mission-organisation\" class=\"form-control\"\r\n formControlName=\"organisation\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\" *ngIf=\"isSP\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Ordered by' | translate }}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"orderedOrganisationID\">\r\n <option *ngFor=\"let org of allOrgs\" [ngValue]=\"org.id\">\r\n {{ org.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Description' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <textarea class=\"form-control\" formControlName=\"description\" rows=\"10\" (ngModelChange)=\"onVerifForm()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['description'])|| isFormError(missionForm.controls['description'])} \"\r\n data-testid=\"form-mission-description\"></textarea>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-description-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['description']) \r\n || isFormError(missionForm.controls['description'])\">\r\n {{validatorsService.getError(missionForm.controls['description']) |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Role' | translate}}*</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"role\" data-testid=\"form-mission-role\" (ngModelChange)=\"onVerifForm()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['role'])|| isFormError(missionForm.controls['role'])} \">\r\n <option *ngFor=\"let r of availableRoles\" [ngValue]=\"r\">\r\n {{ r }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-role-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['role']) \r\n || isFormError(missionForm.controls['role'])\">\r\n {{validatorsService.getError(missionForm.controls['role']) |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\"\r\n *ngIf=\"missionForm.get('role').value !== 'VISITOR_MUSEUM' && missionForm.get('role').value !== 'GUIDE_MUSEUM'\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Domains' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"domains\">\r\n <select class=\"form-control\" multiple formControlName=\"domains\">\r\n <option *ngFor=\"let domain of domains\" [ngValue]=\"domain.id\">\r\n {{ domain.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Access level' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"level\" data-testid=\"form-mission-level\">\r\n <option *ngFor=\"let level of availableLevels\" [ngValue]=\"level\">\r\n {{ level }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized location' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"availableSpaces\">\r\n <select class=\"form-control\" required formControlName=\"space\" (ngModelChange)=\"onVerifForm()\" (change)=\"onSpaceClick()\"\r\n data-testid=\"form-mission-space\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['space'])|| isFormError(missionForm.controls['space'])} \">\r\n <option *ngFor=\"let space of availableSpaces\" [ngValue]=\"space.id\">\r\n {{ space.name }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-space-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['space']) \r\n || isFormError(missionForm.controls['space'])\">\r\n {{validatorsService.getError(missionForm.controls['space']) |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!availableSpaces\">\r\n {{ 'No locations available' | translate}}\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized zone' | translate }}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace; else noSpace\">\r\n <select class=\"form-control\" formControlName=\"zone\" data-testid=\"form-mission-zone\">\r\n <option [ngValue]=\"defaultZone.id\">\r\n {{ 'All zones' | translate }}\r\n </option>\r\n <option *ngFor=\"let zone of zonesForSpace\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <ng-template #noSpace>\r\n <div class=\"col-sm-8 hint-container\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Language' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" formControlName=\"locale\">\r\n <option [ngValue]=\"null\">{{'Not applicable' | translate}}</option>\r\n <option *ngFor=\"let locale of locales\" [ngValue]=\"locale\">\r\n {{ locale }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n <!-- Hashtags are available after Space is set -->\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Hashtags' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"spaceID.value\">\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length > 0\">{{'Available hashtags' | translate}} </p>\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length === 0\">\r\n {{'No hashtags created for this location' | translate}} </p>\r\n <div *ngIf=\"availableHashtags.length > 0\">\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li *ngFor=\"let hashtag of availableHashtags\"\r\n [class]=\"hashtagAdded(hashtag) ? 'keywordsItem added' : 'keywordsItem'\"\r\n (click)=\"onHashtagClick(hashtag)\" style=\"cursor: pointer;\"\r\n ngbTooltip=\"{{hashtagAdded(hashtag) ? ('Remove'|translate) : ('Add'|translate) }}\">\r\n {{hashtag.name}}\r\n </li>\r\n </div>\r\n </ul>\r\n <p class=\"keywordsRules\">{{'Added hashtags' | translate}} </p>\r\n <ul class=\"keywordsDisplay\">\r\n <div class=\"keywordsdisplayContainer\" *ngIf=\"addedHashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of addedHashtags\">{{ hashtag.name }}\r\n <a type=\"button\" class=\"closeButton\" (click)=\"removeHashtag(hashtag)\">\r\n <span class=\"crossItem\"></span>\r\n </a>\r\n </li>\r\n </div>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8 hint-container\" *ngIf=\"!spaceID.value\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" formControlName=\"startDate\" ngbDatepicker\r\n #d1=\"ngbDatepicker\" data-testid=\"form-mission-startDate\" (ngModelChange)=\"onVerifDate();onVerifForm()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['startDate'])|| isFormError(missionForm.controls['startDate'])} \">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\" type=\"button\"></button>\r\n </div>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-startDate-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['startDate']) \r\n || isFormError(missionForm.controls['startDate'])\">\r\n {{validatorsService.getError(missionForm.controls['startDate']) |\r\n translate}}\r\n </ngb-alert>\r\n\r\n <ngb-alert data-testid=\"form-mission-startDate-invalid-verif\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"dateError\">\r\n {{'errorForm.date_start_end' |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeStart\" [ngModelOptions]=\"{standalone: true}\"\r\n (ngModelChange)=\"onVerifDate();onVerifForm()\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" ngbDatepicker #d2=\"ngbDatepicker\"\r\n formControlName=\"endDate\" data-testid=\"form-mission-endDate\"\r\n [class.is-invalid]=\"validatorsService.isControlError(missionForm.controls['endDate'])\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['endDate'])|| isFormError(missionForm.controls['endDate'])} \"\r\n (ngModelChange)=\"onVerifDate();onVerifForm()\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d2.toggle()\" type=\"button\"></button>\r\n </div>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-endDate-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['endDate']) \r\n || isFormError(missionForm.controls['endDate'])\">\r\n {{validatorsService.getError(missionForm.controls['endDate']) |\r\n translate}}\r\n </ngb-alert>\r\n\r\n <ngb-alert data-testid=\"form-mission-endDate-invalid-verif\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"dateError\">\r\n {{'errorForm.date_end_start' |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeEnd\" [ngModelOptions]=\"{standalone: true}\"\r\n (ngModelChange)=\"onVerifDate();onVerifForm()\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"btn-control-div action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n data-testid=\"form-mission-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" data-testid=\"form-mission-cancel-btn\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"form-mission-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n </ngb-alert>\r\n </div>\r\n </form>\r\n</div>", styles: [".form-containter{padding:0rem 1rem;margin-bottom:2rem}.checkbox-apply{margin-top:calc(.375rem + 1px)}.keywordsDisplay{min-height:40px}.hint{margin:0!important}.hint-container{display:flex;align-items:center}.crossItem{margin:0;padding:0;border:0;background:none;position:relative;width:7px;height:20px}.crossItem:before,.crossItem:after{content:\"\";position:absolute;top:6.25px;left:0;right:0;height:1.5px;background:#fff;border-radius:1.5px}.crossItem:before{transform:rotate(45deg)}.crossItem:after{transform:rotate(-45deg)}.crossItem span{display:block}.btn-control-div .btn{width:8rem}.timeZoneContainer{align-items:center}.timeZoneContainer span{margin-left:5px}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"], dependencies: [{ kind: "component", type: i3.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i3.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "component", type: i3.NgbTimepicker, selector: "ngb-timepicker", inputs: ["meridian", "spinners", "seconds", "hourStep", "minuteStep", "secondStep", "readonlyInputs", "size"], exportAs: ["ngbTimepicker"] }, { kind: "directive", type: i3.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.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: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
272
+ }
273
+ export { FormMissionComponent };
274
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormMissionComponent, decorators: [{
275
+ type: Component,
276
+ args: [{ selector: 'lib-form-mission', template: "<div class=\"form-containter\" *ngIf=\"missionForm\">\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'Mission details' | translate }}</h4>\r\n </div>\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"missionForm\">\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Organisation' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" data-testid=\"form-mission-organisation\" class=\"form-control\"\r\n formControlName=\"organisation\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\" *ngIf=\"isSP\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Ordered by' | translate }}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"orderedOrganisationID\">\r\n <option *ngFor=\"let org of allOrgs\" [ngValue]=\"org.id\">\r\n {{ org.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Description' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <textarea class=\"form-control\" formControlName=\"description\" rows=\"10\" (ngModelChange)=\"onVerifForm()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['description'])|| isFormError(missionForm.controls['description'])} \"\r\n data-testid=\"form-mission-description\"></textarea>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-description-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['description']) \r\n || isFormError(missionForm.controls['description'])\">\r\n {{validatorsService.getError(missionForm.controls['description']) |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Role' | translate}}*</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"role\" data-testid=\"form-mission-role\" (ngModelChange)=\"onVerifForm()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['role'])|| isFormError(missionForm.controls['role'])} \">\r\n <option *ngFor=\"let r of availableRoles\" [ngValue]=\"r\">\r\n {{ r }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-role-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['role']) \r\n || isFormError(missionForm.controls['role'])\">\r\n {{validatorsService.getError(missionForm.controls['role']) |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\"\r\n *ngIf=\"missionForm.get('role').value !== 'VISITOR_MUSEUM' && missionForm.get('role').value !== 'GUIDE_MUSEUM'\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Domains' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"domains\">\r\n <select class=\"form-control\" multiple formControlName=\"domains\">\r\n <option *ngFor=\"let domain of domains\" [ngValue]=\"domain.id\">\r\n {{ domain.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Access level' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"level\" data-testid=\"form-mission-level\">\r\n <option *ngFor=\"let level of availableLevels\" [ngValue]=\"level\">\r\n {{ level }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized location' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"availableSpaces\">\r\n <select class=\"form-control\" required formControlName=\"space\" (ngModelChange)=\"onVerifForm()\" (change)=\"onSpaceClick()\"\r\n data-testid=\"form-mission-space\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['space'])|| isFormError(missionForm.controls['space'])} \">\r\n <option *ngFor=\"let space of availableSpaces\" [ngValue]=\"space.id\">\r\n {{ space.name }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-space-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['space']) \r\n || isFormError(missionForm.controls['space'])\">\r\n {{validatorsService.getError(missionForm.controls['space']) |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!availableSpaces\">\r\n {{ 'No locations available' | translate}}\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized zone' | translate }}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace; else noSpace\">\r\n <select class=\"form-control\" formControlName=\"zone\" data-testid=\"form-mission-zone\">\r\n <option [ngValue]=\"defaultZone.id\">\r\n {{ 'All zones' | translate }}\r\n </option>\r\n <option *ngFor=\"let zone of zonesForSpace\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <ng-template #noSpace>\r\n <div class=\"col-sm-8 hint-container\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Language' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" formControlName=\"locale\">\r\n <option [ngValue]=\"null\">{{'Not applicable' | translate}}</option>\r\n <option *ngFor=\"let locale of locales\" [ngValue]=\"locale\">\r\n {{ locale }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n <!-- Hashtags are available after Space is set -->\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Hashtags' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"spaceID.value\">\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length > 0\">{{'Available hashtags' | translate}} </p>\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length === 0\">\r\n {{'No hashtags created for this location' | translate}} </p>\r\n <div *ngIf=\"availableHashtags.length > 0\">\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li *ngFor=\"let hashtag of availableHashtags\"\r\n [class]=\"hashtagAdded(hashtag) ? 'keywordsItem added' : 'keywordsItem'\"\r\n (click)=\"onHashtagClick(hashtag)\" style=\"cursor: pointer;\"\r\n ngbTooltip=\"{{hashtagAdded(hashtag) ? ('Remove'|translate) : ('Add'|translate) }}\">\r\n {{hashtag.name}}\r\n </li>\r\n </div>\r\n </ul>\r\n <p class=\"keywordsRules\">{{'Added hashtags' | translate}} </p>\r\n <ul class=\"keywordsDisplay\">\r\n <div class=\"keywordsdisplayContainer\" *ngIf=\"addedHashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of addedHashtags\">{{ hashtag.name }}\r\n <a type=\"button\" class=\"closeButton\" (click)=\"removeHashtag(hashtag)\">\r\n <span class=\"crossItem\"></span>\r\n </a>\r\n </li>\r\n </div>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8 hint-container\" *ngIf=\"!spaceID.value\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" formControlName=\"startDate\" ngbDatepicker\r\n #d1=\"ngbDatepicker\" data-testid=\"form-mission-startDate\" (ngModelChange)=\"onVerifDate();onVerifForm()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['startDate'])|| isFormError(missionForm.controls['startDate'])} \">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\" type=\"button\"></button>\r\n </div>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-startDate-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['startDate']) \r\n || isFormError(missionForm.controls['startDate'])\">\r\n {{validatorsService.getError(missionForm.controls['startDate']) |\r\n translate}}\r\n </ngb-alert>\r\n\r\n <ngb-alert data-testid=\"form-mission-startDate-invalid-verif\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"dateError\">\r\n {{'errorForm.date_start_end' |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeStart\" [ngModelOptions]=\"{standalone: true}\"\r\n (ngModelChange)=\"onVerifDate();onVerifForm()\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" ngbDatepicker #d2=\"ngbDatepicker\"\r\n formControlName=\"endDate\" data-testid=\"form-mission-endDate\"\r\n [class.is-invalid]=\"validatorsService.isControlError(missionForm.controls['endDate'])\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(missionForm.controls['endDate'])|| isFormError(missionForm.controls['endDate'])} \"\r\n (ngModelChange)=\"onVerifDate();onVerifForm()\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d2.toggle()\" type=\"button\"></button>\r\n </div>\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"form-mission-endDate-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\" validatorsService.isControlError(missionForm.controls['endDate']) \r\n || isFormError(missionForm.controls['endDate'])\">\r\n {{validatorsService.getError(missionForm.controls['endDate']) |\r\n translate}}\r\n </ngb-alert>\r\n\r\n <ngb-alert data-testid=\"form-mission-endDate-invalid-verif\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"dateError\">\r\n {{'errorForm.date_end_start' |\r\n translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeEnd\" [ngModelOptions]=\"{standalone: true}\"\r\n (ngModelChange)=\"onVerifDate();onVerifForm()\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"btn-control-div action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n data-testid=\"form-mission-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" data-testid=\"form-mission-cancel-btn\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"form-mission-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n </ngb-alert>\r\n </div>\r\n </form>\r\n</div>", styles: [".form-containter{padding:0rem 1rem;margin-bottom:2rem}.checkbox-apply{margin-top:calc(.375rem + 1px)}.keywordsDisplay{min-height:40px}.hint{margin:0!important}.hint-container{display:flex;align-items:center}.crossItem{margin:0;padding:0;border:0;background:none;position:relative;width:7px;height:20px}.crossItem:before,.crossItem:after{content:\"\";position:absolute;top:6.25px;left:0;right:0;height:1.5px;background:#fff;border-radius:1.5px}.crossItem:before{transform:rotate(45deg)}.crossItem:after{transform:rotate(-45deg)}.crossItem span{display:block}.btn-control-div .btn{width:8rem}.timeZoneContainer{align-items:center}.timeZoneContainer span{margin-left:5px}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"] }]
277
+ }], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }, { type: i2.SpaceService }, { type: i2.BaseUserService }, { type: i2.DomainService }, { type: i2.OrganisationService }, { type: i2.ZoneService }, { type: i2.HashtagService }, { type: i2.LocaleService }, { type: i2.ValidatorsService }]; }, propDecorators: { missionToEdit: [{
278
+ type: Input
279
+ }], organisationForMission: [{
280
+ type: Input
281
+ }], isSP: [{
282
+ type: Input
283
+ }], userForMissionID: [{
284
+ type: Input
285
+ }], currentUserOrganisation: [{
286
+ type: Input
287
+ }], addedMissionInput: [{
288
+ type: Output
289
+ }] } });
290
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1taXNzaW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1hZG1pbi9zcmMvbGliL3VzZXIvZm9ybS1taXNzaW9uL2Zvcm0tbWlzc2lvbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc21hcnRlcnBsYW4tYWRtaW4vc3JjL2xpYi91c2VyL2Zvcm0tbWlzc2lvbi9mb3JtLW1pc3Npb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUvRSxPQUFPLEVBTUwsV0FBVyxFQUVYLE1BQU0sRUFLTixXQUFXLEVBQ1gsV0FBVyxFQUtYLGtCQUFrQixHQUNuQixNQUFNLG1DQUFtQyxDQUFDO0FBQzNDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDakMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzVDLE9BQU8sRUFFTCxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGNBQWMsR0FDZixNQUFNLG1DQUFtQyxDQUFDOzs7Ozs7O0FBRTNDLE1BS2Esb0JBQW9CO0lBZ0RyQjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0Q7SUF2REEsYUFBYSxDQUFVO0lBRXZCLHNCQUFzQixDQUFlO0lBRXJDLElBQUksQ0FBVTtJQUVkLGdCQUFnQixDQUFTO0lBRXpCLHVCQUF1QixDQUFlO0lBRS9DLFdBQVcsQ0FBbUI7SUFFOUIsZUFBZSxDQUFVO0lBRWYsaUJBQWlCLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztJQUUxRCxjQUFjLENBQWU7SUFFN0IsZUFBZSxDQUFnQjtJQUUvQixpQkFBaUIsR0FBYyxFQUFFLENBQUM7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QUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVztRQUNmLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDL0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7U0FDeEI7SUFDSCxDQUFDO3dHQTFUVSxvQkFBb0I7NEZBQXBCLG9CQUFvQixtVENyQ2pDLDI4ZEEyUE07O1NEdE5PLG9CQUFvQjs0RkFBcEIsb0JBQW9CO2tCQUxoQyxTQUFTOytCQUNFLGtCQUFrQjttVkFLbkIsYUFBYTtzQkFBckIsS0FBSztnQkFFRyxzQkFBc0I7c0JBQTlCLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFFRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBTUksaUJBQWlCO3NCQUExQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBVbnR5cGVkRm9ybUdyb3VwLCBVbnR5cGVkRm9ybUJ1aWxkZXIsIEFic3RyYWN0Q29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHtcclxuICBab25lLFxyXG4gIE1pc3Npb24sXHJcbiAgT3JnYW5pc2F0aW9uLFxyXG4gIFNwYWNlLFxyXG4gIFJvbGVTdGF0dXMsXHJcbiAgTGV2ZWxTdGF0dXMsXHJcbiAgRG9tYWluLFxyXG4gIExvY2FsZSxcclxuICBCYXNlVXNlclNlcnZpY2UsXHJcbiAgRG9tYWluU2VydmljZSxcclxuICBPcmdhbmlzYXRpb25TZXJ2aWNlLFxyXG4gIFpvbmVTZXJ2aWNlLFxyXG4gIGVudW1Ub0FycmF5LFxyXG4gIEVtYWlsU3RhdHVzLFxyXG4gIEhhc2h0YWcsXHJcbiAgU3BhY2VTZXJ2aWNlLFxyXG4gIExvY2FsZVNlcnZpY2UsXHJcbiAgSGFzaHRhZ1NlcnZpY2UsXHJcbiAgc3RyaW5nTG9jYWxlVG9FbnVtLFxyXG59IGZyb20gJ0BzbWFydGVycGxhbi9uZ3gtc21hcnRlcnBsYW4tY29yZSc7XHJcbmltcG9ydCB7IERhdGVUaW1lIH0gZnJvbSAnbHV4b24nO1xyXG5pbXBvcnQgeyBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQge1xyXG4gIFZhbGlkYXRvcnNTZXJ2aWNlLFxyXG4gIHRleHRWYWxpZGF0b3IsXHJcbiAgbm9FbXB0eVZhbGlkYXRvcixcclxuICBmbG9hdFZhbGlkYXRvcixcclxufSBmcm9tICdAc21hcnRlcnBsYW4vbmd4LXNtYXJ0ZXJwbGFuLWNvcmUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdsaWItZm9ybS1taXNzaW9uJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vZm9ybS1taXNzaW9uLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9mb3JtLW1pc3Npb24uY29tcG9uZW50LnNjc3MnXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIEZvcm1NaXNzaW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuICBASW5wdXQoKSBtaXNzaW9uVG9FZGl0OiBNaXNzaW9uO1xyXG5cclxuICBASW5wdXQoKSBvcmdhbmlzYXRpb25Gb3JNaXNzaW9uOiBPcmdhbmlzYXRpb247XHJcblxyXG4gIEBJbnB1dCgpIGlzU1A6IGJvb2xlYW47XHJcblxyXG4gIEBJbnB1dCgpIHVzZXJGb3JNaXNzaW9uSUQ6IHN0cmluZztcclxuXHJcbiAgQElucHV0KCkgY3VycmVudFVzZXJPcmdhbmlzYXRpb246IE9yZ2FuaXNhdGlvbjtcclxuXHJcbiAgbWlzc2lvbkZvcm06IFVudHlwZWRGb3JtR3JvdXA7XHJcblxyXG4gIGF2YWlsYWJsZVNwYWNlczogU3BhY2VbXTtcclxuXHJcbiAgQE91dHB1dCgpIGFkZGVkTWlzc2lvbklucHV0ID0gbmV3IEV2ZW50RW1pdHRlcjxNaXNzaW9uPigpO1xyXG5cclxuICBhdmFpbGFibGVSb2xlczogUm9sZVN0YXR1c1tdO1xyXG5cclxuICBhdmFpbGFibGVMZXZlbHM6IExldmVsU3RhdHVzW107XHJcblxyXG4gIGF2YWlsYWJsZUhhc2h0YWdzOiBIYXNodGFnW10gPSBbXTtcclxuXHJcbiAgZG9tYWluczogRG9tYWluW107XHJcblxyXG4gIGFsbE9yZ3M6IE9yZ2FuaXNhdGlvbltdO1xyXG5cclxuICBpc0d1aWRlID0gZmFsc2U7XHJcblxyXG4gIHpvbmVzRm9yU3BhY2U6IFpvbmVbXTtcclxuXHJcbiAgZGVmYXVsdFpvbmU6IFpvbmU7XHJcblxyXG4gIG1pc3Npb25UaW1lU3RhcnQ6IG51bWJlciA9IDEyICogNjAgKiA2MDAwMDsgLy8gbWlkZGF5IGluIG1pbGxpc2Vjb25kc1xyXG5cclxuICBtaXNzaW9uVGltZUVuZDogbnVtYmVyID0gMTIgKiA2MCAqIDYwMDAwO1xyXG5cclxuICBhZGRlZEhhc2h0YWdzOiBIYXNodGFnW10gPSBbXTtcclxuXHJcbiAgY3VycmVudExvY2FsZTogTG9jYWxlO1xyXG5cclxuICBsb2NhbGVzOiBzdHJpbmdbXTtcclxuXHJcbiAgZGF0ZUVycm9yOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGVycm9yRm9ybTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZmI6IFVudHlwZWRGb3JtQnVpbGRlcixcclxuICAgIHByaXZhdGUgc3BhY2VTZXJ2aWNlOiBTcGFjZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHVzZXJTZXJ2aWNlOiBCYXNlVXNlclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGRvbWFpblNlcnZpY2U6IERvbWFpblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIG9yZ2FuaXNhdGlvblNlcnZpY2U6IE9yZ2FuaXNhdGlvblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHpvbmVTZXJ2aWNlOiBab25lU2VydmljZSxcclxuICAgIHByaXZhdGUgaGFzaHRhZ1NlcnZpY2U6IEhhc2h0YWdTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBsb2NhbGVTZXJ2aWNlOiBMb2NhbGVTZXJ2aWNlLFxyXG4gICAgcHVibGljIHZhbGlkYXRvcnNTZXJ2aWNlOiBWYWxpZGF0b3JzU2VydmljZVxyXG4gICkgeyB9XHJcblxyXG4gIGFzeW5jIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy51cGRhdGVVc2VySW5mbygpO1xyXG4gICAgYXdhaXQgdGhpcy5zZXREb21haW5zKCk7XHJcbiAgICBpZiAodGhpcy5pc1NQKSB7XHJcbiAgICAgIHRoaXMuYWxsT3JncyA9IGF3YWl0IHRoaXMub3JnYW5pc2F0aW9uU2VydmljZS5saXN0T3JnYW5pc2F0aW9ucygpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jdXJyZW50TG9jYWxlID0gc3RyaW5nTG9jYWxlVG9FbnVtKHRoaXMubG9jYWxlU2VydmljZS5nZXRMb2NhbGUoKSk7IC8vIHRvIG1hdGNoIGVudW0gTG9jYWxlXHJcbiAgICB0aGlzLmxvY2FsZXMgPSBlbnVtVG9BcnJheShMb2NhbGUpO1xyXG4gICAgaWYgKHRoaXMubWlzc2lvblRvRWRpdCkge1xyXG4gICAgICB0aGlzLmluaXRGb3JtRm9yRWRpdCgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5pbml0RW1wdHlGb3JtKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB1cGRhdGVVc2VySW5mbygpIHtcclxuICAgIHRoaXMuYXZhaWxhYmxlUm9sZXMgPSB0aGlzLnVzZXJTZXJ2aWNlLmdldEF2YWlsYWJsZVJvbGVzRm9yQ3VycmVudFVzZXIoKTtcclxuICAgIHRoaXMuYXZhaWxhYmxlTGV2ZWxzID0gdGhpcy51c2VyU2VydmljZS5nZXRBdmFsYWJsZUxldmVsc0ZvckN1cnJlbnRVc2VyKCk7XHJcbiAgICB0aGlzLmlzR3VpZGUgPSB0aGlzLnVzZXJTZXJ2aWNlLmlzR3VpZGUoKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIHNldERvbWFpbnMoKSB7XHJcbiAgICBpZiAoIXRoaXMuaXNHdWlkZSkge1xyXG4gICAgICBjb25zdCBkb21haW5zID0gYXdhaXQgdGhpcy5kb21haW5TZXJ2aWNlLmdldERvbWFpbnNGb3JNaXNzaW9uc0Zvck9yZyhcclxuICAgICAgICB0aGlzLmN1cnJlbnRVc2VyT3JnYW5pc2F0aW9uLmlkXHJcbiAgICAgICk7XHJcbiAgICAgIHRoaXMuZG9tYWlucyA9IGRvbWFpbnM7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhc3luYyBzZXRIYXNodGFncyhzcGFjZUlEOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuYXZhaWxhYmxlSGFzaHRhZ3MgPSBhd2FpdCB0aGlzLmhhc2h0YWdTZXJ2aWNlLmdldEhhc2h0YWdzRm9yU3BhY2UoXHJcbiAgICAgIHNwYWNlSURcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBnZXQgc3BhY2VJRCgpOiBBYnN0cmFjdENvbnRyb2wge1xyXG4gICAgcmV0dXJuIHRoaXMubWlzc2lvbkZvcm0uZ2V0KCdzcGFjZScpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHJvbGUoKTogQWJzdHJhY3RDb250cm9sIHtcclxuICAgIHJldHVybiB0aGlzLm1pc3Npb25Gb3JtLmdldCgncm9sZScpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgaW5pdEZvcm1Gb3JFZGl0KCkge1xyXG4gICAgbGV0IHN0YXJ0RGF0ZTogYW55ID0gbnVsbDtcclxuICAgIGxldCBlbmREYXRlOiBhbnkgPSBudWxsO1xyXG5cclxuICAgIGNvbnN0IG0gPSB0aGlzLm1pc3Npb25Ub0VkaXQ7XHJcblxyXG4gICAgaWYgKG0uc3RhcnREYXRlVGltZSkge1xyXG4gICAgICBjb25zdCBkYXRlID0gRGF0ZVRpbWUuZnJvbUlTTyhtLnN0YXJ0RGF0ZVRpbWUpO1xyXG4gICAgICB0aGlzLm1pc3Npb25UaW1lU3RhcnQgPSAoZGF0ZS5ob3VyICogNjAgKyBkYXRlLm1pbnV0ZSkgKiA2MCAqIDEwMDA7XHJcbiAgICAgIHN0YXJ0RGF0ZSA9IGRhdGUudG9NaWxsaXMoKSAtIHRoaXMubWlzc2lvblRpbWVTdGFydDtcclxuICAgIH1cclxuICAgIGlmIChtLmVuZERhdGVUaW1lKSB7XHJcbiAgICAgIGNvbnN0IGRhdGUgPSBEYXRlVGltZS5mcm9tSVNPKG0uZW5kRGF0ZVRpbWUpO1xyXG4gICAgICB0aGlzLm1pc3Npb25UaW1lRW5kID0gKGRhdGUuaG91ciAqIDYwICsgZGF0ZS5taW51dGUpICogNjAgKiAxMDAwO1xyXG4gICAgICBlbmREYXRlID0gZGF0ZS50b01pbGxpcygpIC0gdGhpcy5taXNzaW9uVGltZUVuZDtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnVzZXJGb3JNaXNzaW9uSUQgPSBtLnVzZXJJRDtcclxuICAgIHRoaXMuYXZhaWxhYmxlU3BhY2VzID0gYXdhaXQgdGhpcy5zcGFjZVNlcnZpY2UuZ2V0QWxsb3dlZFNwYWNlc0Zvck9yZyhcclxuICAgICAgdGhpcy5taXNzaW9uVG9FZGl0Lm9yZ2FuaXNhdGlvbklELFxyXG4gICAgICB0aGlzLmN1cnJlbnRVc2VyT3JnYW5pc2F0aW9uLmlkXHJcbiAgICApO1xyXG4gICAgYXdhaXQgdGhpcy5zZXRIYXNodGFncyhtLnNwYWNlSUQpO1xyXG4gICAgdGhpcy5taXNzaW9uRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xyXG4gICAgICBpZDogbS5pZCxcclxuICAgICAgb3JnYW5pc2F0aW9uOiBbeyB2YWx1ZTogbS5vcmdhbmlzYXRpb24ubmFtZSwgZGlzYWJsZWQ6IHRydWUgfV0sXHJcbiAgICAgIG9yZ2FuaXNhdGlvbklEOiBtLm9yZ2FuaXNhdGlvbklELFxyXG4gICAgICBvcmRlcmVkT3JnYW5pc2F0aW9uSUQ6IG0ub3JkZXJlZE9yZ2FuaXNhdGlvbklELFxyXG4gICAgICByb2xlOiBbbS5yb2xlLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcclxuICAgICAgbGV2ZWw6IFttLmxldmVsXSxcclxuICAgICAgc3BhY2U6IFttLnNwYWNlSUQsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxyXG4gICAgICBkZXNjcmlwdGlvbjogW20uZGVzY3JpcHRpb24sIFt0ZXh0VmFsaWRhdG9yKCksIG5vRW1wdHlWYWxpZGF0b3IoKV1dLFxyXG4gICAgICBkb21haW5zOiBbbS5kb21haW5zXSxcclxuICAgICAgem9uZTogW20uem9uZUlEXSxcclxuICAgICAgbG9jYWxlOiBbbS5sb2NhbGVdLFxyXG4gICAgICBzdGFydERhdGU6IFtzdGFydERhdGUsIFtmbG9hdFZhbGlkYXRvcigpXV0sXHJcbiAgICAgIGVuZERhdGU6IFtlbmREYXRlLCBbZmxvYXRWYWxpZGF0b3IoKV1dLFxyXG4gICAgfSk7XHJcbiAgICBpZiAobS5oYXNodGFncyAmJiBtLmhhc2h0YWdzLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5hZGRlZEhhc2h0YWdzID0gdGhpcy5hdmFpbGFibGVIYXNodGFncy5maWx0ZXIoKGhhc2h0YWcpID0+XHJcbiAgICAgICAgbS5oYXNodGFncy5pbmNsdWRlcyhoYXNodGFnLmlkKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gICAgdGhpcy5vblNwYWNlQ2xpY2soKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIG9uU3BhY2VDbGljaygpIHtcclxuICAgIGNvbnN0IHpvbmVzID0gYXdhaXQgdGhpcy56b25lU2VydmljZS5nZXRab25lc0J5U3BhY2UodGhpcy5zcGFjZUlELnZhbHVlKTtcclxuICAgIHRoaXMuZGVmYXVsdFpvbmUgPSB6b25lcy5maW5kKCh6b25lKSA9PiAhem9uZS5wYXJlbnRJRCk7XHJcbiAgICBjb25zdCBpbmRleE9mRGVmYXVsdFpvbmUgPSB6b25lcy5pbmRleE9mKHRoaXMuZGVmYXVsdFpvbmUpO1xyXG4gICAgem9uZXMuc3BsaWNlKGluZGV4T2ZEZWZhdWx0Wm9uZSwgMSk7XHJcbiAgICB0aGlzLnpvbmVzRm9yU3BhY2UgPSB6b25lcy5maWx0ZXIoKHpvbmUpID0+ICF6b25lLmF1ZGlvSUQpO1xyXG4gICAgYXdhaXQgdGhpcy5zZXRIYXNodGFncyh0aGlzLnNwYWNlSUQudmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgaW5pdEVtcHR5Rm9ybSgpIHtcclxuICAgIHRoaXMuYXZhaWxhYmxlU3BhY2VzID0gYXdhaXQgdGhpcy5zcGFjZVNlcnZpY2UuZ2V0QWxsb3dlZFNwYWNlc0Zvck9yZyhcclxuICAgICAgdGhpcy5vcmdhbmlzYXRpb25Gb3JNaXNzaW9uLmlkLFxyXG4gICAgICB0aGlzLmN1cnJlbnRVc2VyT3JnYW5pc2F0aW9uLmlkXHJcbiAgICApO1xyXG4gICAgdGhpcy5taXNzaW9uRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xyXG4gICAgICByb2xlOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxyXG4gICAgICBsZXZlbDogW0xldmVsU3RhdHVzLk1JTklNVU1dLFxyXG4gICAgICBvcmdhbmlzYXRpb246IFtcclxuICAgICAgICB7IHZhbHVlOiB0aGlzLm9yZ2FuaXNhdGlvbkZvck1pc3Npb24ubmFtZSwgZGlzYWJsZWQ6IHRydWUgfSxcclxuICAgICAgXSxcclxuICAgICAgb3JnYW5pc2F0aW9uSUQ6IHRoaXMub3JnYW5pc2F0aW9uRm9yTWlzc2lvbi5pZCxcclxuICAgICAgb3JkZXJlZE9yZ2FuaXNhdGlvbklEOiB0aGlzLmN1cnJlbnRVc2VyT3JnYW5pc2F0aW9uLmlkLFxyXG4gICAgICBzcGFjZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcclxuICAgICAgem9uZTogWycnXSxcclxuICAgICAgZGVzY3JpcHRpb246IFsnJywgW3RleHRWYWxpZGF0b3IoKSwgbm9FbXB0eVZhbGlkYXRvcigpXV0sXHJcbiAgICAgIGRvbWFpbnM6IFtudWxsXSxcclxuICAgICAgbG9jYWxlOiBbdGhpcy5jdXJyZW50TG9jYWxlXSxcclxuICAgICAgc3RhcnREYXRlOiBbbnVsbCwgW2Zsb2F0VmFsaWRhdG9yKCldXSxcclxuICAgICAgZW5kRGF0ZTogW251bGwsIFtmbG9hdFZhbGlkYXRvcigpXV0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG9uSGFzaHRhZ0NsaWNrKGhhc2h0YWc6IEhhc2h0YWcpIHtcclxuICAgIGlmICghdGhpcy5oYXNodGFnQWRkZWQoaGFzaHRhZykpIHtcclxuICAgICAgdGhpcy5hZGRlZEhhc2h0YWdzLnB1c2goaGFzaHRhZyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmFkZGVkSGFzaHRhZ3Muc3BsaWNlKHRoaXMuYWRkZWRIYXNodGFncy5pbmRleE9mKGhhc2h0YWcpLCAxKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGhhc2h0YWdBZGRlZChoYXNodGFnOiBIYXNodGFnKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICB0aGlzLmFkZGVkSGFzaHRhZ3MuZmluZCgoX2hhc2h0YWcpID0+IF9oYXNodGFnLmlkID09PSBoYXNodGFnLmlkKSAhPT1cclxuICAgICAgdW5kZWZpbmVkXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlSGFzaHRhZyhoYXNodGFnOiBIYXNodGFnKSB7XHJcbiAgICB0aGlzLmFkZGVkSGFzaHRhZ3Muc3BsaWNlKHRoaXMuYWRkZWRIYXNodGFncy5pbmRleE9mKGhhc2h0YWcpLCAxKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIG9uU3VibWl0KCkge1xyXG4gICAgaWYgKCF0aGlzLm1pc3Npb25Gb3JtLnZhbGlkKSB7XHJcbiAgICAgIHRoaXMuZXJyb3JGb3JtID0gdHJ1ZTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGRhdGVzVmFsdWVzID0gYXdhaXQgdGhpcy5vblZlcmlmRGF0ZSgpO1xyXG4gICAgaWYgKGRhdGVzVmFsdWVzLmVycm9yKSB7XHJcbiAgICAgIHRoaXMuZGF0ZUVycm9yID0gdHJ1ZTtcclxuICAgICAgdGhpcy5lcnJvckZvcm0gPSB0cnVlO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZm9ybVZhbHVlID0gdGhpcy5taXNzaW9uRm9ybS52YWx1ZTtcclxuICAgIC8vIGlmICghdGhpcy5taXNzaW9uRm9ybS52YWxpZCkge1xyXG4gICAgLy8gICAgIC8vIHRoaXMgc2hvd3MgZXJyb3JzIGluIHRoZSBmb3JtXHJcbiAgICAvLyAgICAgdGhpcy5taXNzaW9uRm9ybS5tYXJrQWxsQXNUb3VjaGVkKCk7XHJcbiAgICAvLyAgICAgcmV0dXJuO1xyXG4gICAgLy8gfVxyXG4gICAgLy8gbGV0IHN0YXJ0RGF0ZVN0cmluZzogc3RyaW5nO1xyXG4gICAgLy8gbGV0IGVuZERhdGVTdHJpbmc6IHN0cmluZztcclxuICAgIC8vIGlmIChmb3JtVmFsdWUuc3RhcnREYXRlKSB7XHJcbiAgICAvLyAgICAgY29uc3QgZGF0ZUhvdXJTdGFydE51bWJlciA9IGZvcm1WYWx1ZS5zdGFydERhdGUgKyB0aGlzLm1pc3Npb25UaW1lU3RhcnQ7XHJcbiAgICAvLyAgICAgY29uc3Qgc3RhcnREYXRlID0gRGF0ZVRpbWUuZnJvbU1pbGxpcyhkYXRlSG91clN0YXJ0TnVtYmVyKTtcclxuICAgIC8vICAgICBzdGFydERhdGVTdHJpbmcgPSBzdGFydERhdGUudG9JU08oKTtcclxuICAgIC8vIH1cclxuICAgIC8vIGlmIChmb3JtVmFsdWUuZW5kRGF0ZSkge1xyXG4gICAgLy8gICAgIGNvbnN0IGRhdGVIb3VyRW5kTnVtYmVyID0gZm9ybVZhbHVlLmVuZERhdGUgKyB0aGlzLm1pc3Npb25UaW1lRW5kO1xyXG4gICAgLy8gICAgIGNvbnN0IGVuZERhdGUgPSBEYXRlVGltZS5mcm9tTWlsbGlzKGRhdGVIb3VyRW5kTnVtYmVyKTtcclxuICAgIC8vICAgICBlbmREYXRlU3RyaW5nID0gZW5kRGF0ZS50b0lTTygpO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIC8vIGlmIChlbmREYXRlU3RyaW5nICYmIHN0YXJ0RGF0ZVN0cmluZyAmJiAoZW5kRGF0ZVN0cmluZyA8IHN0YXJ0RGF0ZVN0cmluZykpIHtcclxuICAgIC8vICAgICB0aGlzLmRhdGVFcnJvciA9IHRydWU7XHJcbiAgICAvLyAgICAgcmV0dXJuO1xyXG4gICAgLy8gfSBlbHNlIHtcclxuICAgIC8vICAgICB0aGlzLmRhdGVFcnJvciA9IGZhbHNlO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIGNvbnN0IG1pc3Npb25JbnB1dDogTWlzc2lvbiA9IHtcclxuICAgICAgb3JnYW5pc2F0aW9uSUQ6IGZvcm1WYWx1ZS5vcmdhbmlzYXRpb25JRCxcclxuICAgICAgb3JkZXJlZE9yZ2FuaXNhdGlvbklEOiBmb3JtVmFsdWUub3JkZXJlZE9yZ2FuaXNhdGlvbklELFxyXG4gICAgICBsZXZlbDogZm9ybVZhbHVlLmxldmVsLFxyXG4gICAgICByb2xlOiBmb3JtVmFsdWUucm9sZSxcclxuICAgICAgZGVzY3JpcHRpb246IGZvcm1WYWx1ZS5kZXNjcmlwdGlvbixcclxuICAgICAgc3RhcnREYXRlVGltZTogZGF0ZXNWYWx1ZXMuc3RhcnREYXRlU3RyaW5nLFxyXG4gICAgICBlbmREYXRlVGltZTogZGF0ZXNWYWx1ZXMuZW5kRGF0ZVN0cmluZyxcclxuICAgICAgZG9tYWluczogZm9ybVZhbHVlLmRvbWFpbnMsXHJcbiAgICAgIHVzZXJJRDogdGhpcy51c2VyRm9yTWlzc2lvbklELFxyXG4gICAgICBlbWFpbFN0YXR1czogdGhpcy5taXNzaW9uVG9FZGl0XHJcbiAgICAgICAgPyB0aGlzLm1pc3Npb25Ub0VkaXQuZW1haWxTdGF0dXNcclxuICAgICAgICA6IEVtYWlsU3RhdHVzLkNSRUFUSU9OX1RPX0RFTElWRVIsXHJcbiAgICAgIGxvY2FsZTogZm9ybVZhbHVlLmxvY2FsZSxcclxuICAgIH07XHJcbiAgICBtaXNzaW9uSW5wdXQuaGFzaHRhZ3MgPSB0aGlzLmFkZGVkSGFzaHRhZ3MubWFwKChoKSA9PiBoLmlkKTtcclxuICAgIGlmIChmb3JtVmFsdWUuc3BhY2UpIHtcclxuICAgICAgbWlzc2lvbklucHV0LnNwYWNlSUQgPSBmb3JtVmFsdWUuc3BhY2U7XHJcbiAgICB9XHJcbiAgICBpZiAoZm9ybVZhbHVlLnpvbmUpIHtcclxuICAgICAgbWlzc2lvbklucHV0LnpvbmVJRCA9IGZvcm1WYWx1ZS56b25lO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMubWlzc2lvblRvRWRpdCkge1xyXG4gICAgICBtaXNzaW9uSW5wdXQuaWQgPSB0aGlzLm1pc3Npb25Ub0VkaXQuaWQ7XHJcbiAgICB9XHJcbiAgICB0aGlzLmFkZGVkTWlzc2lvbklucHV0LmVtaXQobWlzc2lvbklucHV0KTtcclxuICB9XHJcblxyXG4gIG9uQ2FuY2VsKCkge1xyXG4gICAgdGhpcy5hZGRlZE1pc3Npb25JbnB1dC5lbWl0KG51bGwpO1xyXG4gIH1cclxuXHJcbiAgaXNGb3JtRXJyb3IoY29udHJvbCkge1xyXG4gICAgcmV0dXJuIGNvbnRyb2wgJiYgY29udHJvbC5pbnZhbGlkICYmIHRoaXMuZXJyb3JGb3JtO1xyXG4gIH1cclxuXHJcbiAgb25WZXJpZkRhdGUoKTogUHJvbWlzZTx7XHJcbiAgICBzdGFydERhdGVTdHJpbmc/OiBzdHJpbmc7XHJcbiAgICBlbmREYXRlU3RyaW5nPzogc3RyaW5nO1xyXG4gICAgZXJyb3I/OiBib29sZWFuO1xyXG4gIH0+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xyXG4gICAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLm1pc3Npb25Gb3JtLmdldFJhd1ZhbHVlKCk7XHJcbiAgICAgIGxldCBzdGFydERhdGVTdHJpbmc6IHN0cmluZztcclxuICAgICAgbGV0IGVuZERhdGVTdHJpbmc6IHN0cmluZztcclxuXHJcbiAgICAgIGlmIChmb3JtVmFsdWUuc3RhcnREYXRlKSB7XHJcbiAgICAgICAgY29uc3QgZGF0ZUhvdXJTdGFydE51bWJlciA9IGZvcm1WYWx1ZS5zdGFydERhdGUgKyB0aGlzLm1pc3Npb25UaW1lU3RhcnQ7XHJcbiAgICAgICAgY29uc3Qgc3RhcnREYXRlID0gRGF0ZVRpbWUuZnJvbU1pbGxpcyhkYXRlSG91clN0YXJ0TnVtYmVyKTtcclxuICAgICAgICBzdGFydERhdGVTdHJpbmcgPSBzdGFydERhdGUudG9JU08oKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoZm9ybVZhbHVlLmVuZERhdGUpIHtcclxuICAgICAgICBjb25zdCBkYXRlSG91ckVuZE51bWJlciA9IGZvcm1WYWx1ZS5lbmREYXRlICsgdGhpcy5taXNzaW9uVGltZUVuZDtcclxuICAgICAgICBjb25zdCBlbmREYXRlID0gRGF0ZVRpbWUuZnJvbU1pbGxpcyhkYXRlSG91ckVuZE51bWJlcik7XHJcbiAgICAgICAgZW5kRGF0ZVN0cmluZyA9IGVuZERhdGUudG9JU08oKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKFxyXG4gICAgICAgIGVuZERhdGVTdHJpbmcgJiZcclxuICAgICAgICBzdGFydERhdGVTdHJpbmcgJiZcclxuICAgICAgICBlbmREYXRlU3RyaW5nIDw9IHN0YXJ0RGF0ZVN0cmluZ1xyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLmRhdGVFcnJvciA9IHRydWU7XHJcbiAgICAgICAgcmVzb2x2ZSh7IGVycm9yOiB0cnVlIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZGF0ZUVycm9yID0gZmFsc2U7XHJcbiAgICAgICAgcmVzb2x2ZSh7IHN0YXJ0RGF0ZVN0cmluZywgZW5kRGF0ZVN0cmluZyB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBvblZlcmlmRm9ybSgpIHtcclxuICAgIGlmICh0aGlzLmVycm9yRm9ybSAmJiB0aGlzLm1pc3Npb25Gb3JtLnZhbGlkICYmICF0aGlzLmRhdGVFcnJvcikge1xyXG4gICAgICB0aGlzLmVycm9yRm9ybSA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiZm9ybS1jb250YWludGVyXCIgKm5nSWY9XCJtaXNzaW9uRm9ybVwiPlxyXG4gICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDFyZW07XCI+XHJcbiAgICAgICAgPGg0Pnt7ICdNaXNzaW9uIGRldGFpbHMnIHwgdHJhbnNsYXRlIH19PC9oND5cclxuICAgIDwvZGl2PlxyXG4gICAgPGZvcm0gKG5nU3VibWl0KT1cIm9uU3VibWl0KClcIiBbZm9ybUdyb3VwXT1cIm1pc3Npb25Gb3JtXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcm93XCI+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS00IGNvbC1mb3JtLWxhYmVsXCI+e3snT3JnYW5pc2F0aW9uJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS04XCI+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBkYXRhLXRlc3RpZD1cImZvcm0tbWlzc2lvbi1vcmdhbmlzYXRpb25cIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwib3JnYW5pc2F0aW9uXCI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCByb3dcIiAqbmdJZj1cImlzU1BcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTQgY29sLWZvcm0tbGFiZWxcIj57eyAnT3JkZXJlZCBieScgfCB0cmFuc2xhdGUgfX08L2xhYmVsPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLThcIj5cclxuICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZXF1aXJlZCBmb3JtQ29udHJvbE5hbWU9XCJvcmRlcmVkT3JnYW5pc2F0aW9uSURcIj5cclxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcmcgb2YgYWxsT3Jnc1wiIFtuZ1ZhbHVlXT1cIm9yZy5pZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBvcmcubmFtZSB9fVxyXG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCByb3dcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTQgY29sLWZvcm0tbGFiZWxcIj57eydEZXNjcmlwdGlvbicgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOFwiPlxyXG4gICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwiZGVzY3JpcHRpb25cIiByb3dzPVwiMTBcIiAobmdNb2RlbENoYW5nZSk9XCJvblZlcmlmRm9ybSgpXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2lzLWludmFsaWQnIDogdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ2Rlc2NyaXB0aW9uJ10pfHwgaXNGb3JtRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ2Rlc2NyaXB0aW9uJ10pfSBcIlxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLWRlc2NyaXB0aW9uXCI+PC90ZXh0YXJlYT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cImZvcm0tbWlzc2lvbi1kZXNjcmlwdGlvbi1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiICpuZ0lmPVwiIHZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydkZXNjcmlwdGlvbiddKSBcclxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgIGlzRm9ybUVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydkZXNjcmlwdGlvbiddKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7e3ZhbGlkYXRvcnNTZXJ2aWNlLmdldEVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydkZXNjcmlwdGlvbiddKSB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHJvd1wiPlxyXG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tNCBjb2wtZm9ybS1sYWJlbFwiPnt7J1JvbGUnIHwgdHJhbnNsYXRlfX0qPC9sYWJlbD5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS04XCI+XHJcbiAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVxdWlyZWQgZm9ybUNvbnRyb2xOYW1lPVwicm9sZVwiIGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLXJvbGVcIiAobmdNb2RlbENoYW5nZSk9XCJvblZlcmlmRm9ybSgpXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2lzLWludmFsaWQnIDogdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ3JvbGUnXSl8fCBpc0Zvcm1FcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1sncm9sZSddKX0gXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgciBvZiBhdmFpbGFibGVSb2xlc1wiIFtuZ1ZhbHVlXT1cInJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3sgciB9fVxyXG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZ2ItYWxlcnQgZGF0YS10ZXN0aWQ9XCJmb3JtLW1pc3Npb24tcm9sZS1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiICpuZ0lmPVwiIHZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydyb2xlJ10pIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCAgaXNGb3JtRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ3JvbGUnXSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3t2YWxpZGF0b3JzU2VydmljZS5nZXRFcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1sncm9sZSddKSB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHJvd1wiXHJcbiAgICAgICAgICAgICpuZ0lmPVwibWlzc2lvbkZvcm0uZ2V0KCdyb2xlJykudmFsdWUgIT09ICdWSVNJVE9SX01VU0VVTScgJiYgbWlzc2lvbkZvcm0uZ2V0KCdyb2xlJykudmFsdWUgIT09ICdHVUlERV9NVVNFVU0nXCI+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS00IGNvbC1mb3JtLWxhYmVsXCI+e3snRG9tYWlucycgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOFwiICpuZ0lmPVwiZG9tYWluc1wiPlxyXG4gICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tY29udHJvbFwiIG11bHRpcGxlIGZvcm1Db250cm9sTmFtZT1cImRvbWFpbnNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBkb21haW4gb2YgZG9tYWluc1wiIFtuZ1ZhbHVlXT1cImRvbWFpbi5pZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBkb21haW4ubmFtZSB9fVxyXG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCByb3dcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTQgY29sLWZvcm0tbGFiZWxcIj57eydBY2Nlc3MgbGV2ZWwnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLThcIj5cclxuICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZXF1aXJlZCBmb3JtQ29udHJvbE5hbWU9XCJsZXZlbFwiIGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLWxldmVsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgbGV2ZWwgb2YgYXZhaWxhYmxlTGV2ZWxzXCIgW25nVmFsdWVdPVwibGV2ZWxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3sgbGV2ZWwgfX1cclxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cclxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcm93XCI+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS00IGNvbC1mb3JtLWxhYmVsXCI+e3sgJ0F1dGhvcml6ZWQgbG9jYXRpb24nIHwgdHJhbnNsYXRlIH19KjwvbGFiZWw+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOFwiICpuZ0lmPVwiYXZhaWxhYmxlU3BhY2VzXCI+XHJcbiAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVxdWlyZWQgZm9ybUNvbnRyb2xOYW1lPVwic3BhY2VcIiAobmdNb2RlbENoYW5nZSk9XCJvblZlcmlmRm9ybSgpXCIgKGNoYW5nZSk9XCJvblNwYWNlQ2xpY2soKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJmb3JtLW1pc3Npb24tc3BhY2VcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnaXMtaW52YWxpZCcgOiB2YWxpZGF0b3JzU2VydmljZS5pc0NvbnRyb2xFcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1snc3BhY2UnXSl8fCBpc0Zvcm1FcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1snc3BhY2UnXSl9IFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHNwYWNlIG9mIGF2YWlsYWJsZVNwYWNlc1wiIFtuZ1ZhbHVlXT1cInNwYWNlLmlkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IHNwYWNlLm5hbWUgfX1cclxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cclxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLXNwYWNlLWludmFsaWRcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCIgKm5nSWY9XCIgdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ3NwYWNlJ10pIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCAgaXNGb3JtRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ3NwYWNlJ10pXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7dmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ3NwYWNlJ10pIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX1cclxuICAgICAgICAgICAgICAgICAgICA8L25nYi1hbGVydD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS04XCIgKm5nSWY9XCIhYXZhaWxhYmxlU3BhY2VzXCI+XHJcbiAgICAgICAgICAgICAgICB7eyAnTm8gbG9jYXRpb25zIGF2YWlsYWJsZScgfCB0cmFuc2xhdGV9fVxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcm93XCI+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS00IGNvbC1mb3JtLWxhYmVsXCI+e3sgJ0F1dGhvcml6ZWQgem9uZScgfCB0cmFuc2xhdGUgfX08L2xhYmVsPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLThcIiAqbmdJZj1cInpvbmVzRm9yU3BhY2U7IGVsc2Ugbm9TcGFjZVwiPlxyXG4gICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cInpvbmVcIiBkYXRhLXRlc3RpZD1cImZvcm0tbWlzc2lvbi16b25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCJkZWZhdWx0Wm9uZS5pZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7eyAnQWxsIHpvbmVzJyB8IHRyYW5zbGF0ZSB9fVxyXG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHpvbmUgb2Ygem9uZXNGb3JTcGFjZVwiIFtuZ1ZhbHVlXT1cInpvbmUuaWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3sgem9uZS5uYW1lIH19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9TcGFjZT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOCBoaW50LWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiaGludCBrZXl3b3Jkc1J1bGVzXCI+e3snWW91IG5lZWQgdG8gY2hvb3NlIHRoZSBsb2NhdGlvbiBmaXJzdCcgfCB0cmFuc2xhdGV9fSA8L3A+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCByb3dcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTQgY29sLWZvcm0tbGFiZWxcIj57eydMYW5ndWFnZScgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOFwiPlxyXG4gICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cImxvY2FsZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwibnVsbFwiPnt7J05vdCBhcHBsaWNhYmxlJyB8IHRyYW5zbGF0ZX19PC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgbG9jYWxlIG9mIGxvY2FsZXNcIiBbbmdWYWx1ZV09XCJsb2NhbGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3sgbG9jYWxlIH19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPCEtLSBIYXNodGFncyBhcmUgYXZhaWxhYmxlIGFmdGVyIFNwYWNlIGlzIHNldCAtLT5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCByb3dcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTQgY29sLWZvcm0tbGFiZWxcIj57eydIYXNodGFncycgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOFwiICpuZ0lmPVwic3BhY2VJRC52YWx1ZVwiPlxyXG4gICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJrZXl3b3Jkc1J1bGVzXCIgKm5nSWY9XCJhdmFpbGFibGVIYXNodGFncy5sZW5ndGggPiAwXCI+e3snQXZhaWxhYmxlIGhhc2h0YWdzJyB8IHRyYW5zbGF0ZX19IDwvcD5cclxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwia2V5d29yZHNSdWxlc1wiICpuZ0lmPVwiYXZhaWxhYmxlSGFzaHRhZ3MubGVuZ3RoID09PSAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAge3snTm8gaGFzaHRhZ3MgY3JlYXRlZCBmb3IgdGhpcyBsb2NhdGlvbicgfCB0cmFuc2xhdGV9fSA8L3A+XHJcbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiYXZhaWxhYmxlSGFzaHRhZ3MubGVuZ3RoID4gMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cImtleXdvcmRzRGlzcGxheSBuby1ib3JkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImtleXdvcmRzZGlzcGxheUNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpICpuZ0Zvcj1cImxldCBoYXNodGFnIG9mIGF2YWlsYWJsZUhhc2h0YWdzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiaGFzaHRhZ0FkZGVkKGhhc2h0YWcpID8gJ2tleXdvcmRzSXRlbSBhZGRlZCcgOiAna2V5d29yZHNJdGVtJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uSGFzaHRhZ0NsaWNrKGhhc2h0YWcpXCIgc3R5bGU9XCJjdXJzb3I6IHBvaW50ZXI7XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZ2JUb29sdGlwPVwie3toYXNodGFnQWRkZWQoaGFzaHRhZykgPyAoJ1JlbW92ZSd8dHJhbnNsYXRlKSA6ICgnQWRkJ3x0cmFuc2xhdGUpIH19XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3toYXNodGFnLm5hbWV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImtleXdvcmRzUnVsZXNcIj57eydBZGRlZCBoYXNodGFncycgfCB0cmFuc2xhdGV9fSA8L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwia2V5d29yZHNEaXNwbGF5XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJrZXl3b3Jkc2Rpc3BsYXlDb250YWluZXJcIiAqbmdJZj1cImFkZGVkSGFzaHRhZ3MubGVuZ3RoPiAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJrZXl3b3Jkc0l0ZW1cIiAqbmdGb3I9XCJsZXQgaGFzaHRhZyBvZiBhZGRlZEhhc2h0YWdzXCI+e3sgaGFzaHRhZy5uYW1lIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiY2xvc2VCdXR0b25cIiAoY2xpY2spPVwicmVtb3ZlSGFzaHRhZyhoYXNodGFnKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNyb3NzSXRlbVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L3VsPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTggaGludC1jb250YWluZXJcIiAqbmdJZj1cIiFzcGFjZUlELnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImhpbnQga2V5d29yZHNSdWxlc1wiPnt7J1lvdSBuZWVkIHRvIGNob29zZSB0aGUgbG9jYXRpb24gZmlyc3QnIHwgdHJhbnNsYXRlfX0gPC9wPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcm93XCI+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS00IGNvbC1mb3JtLWxhYmVsXCI+e3snTWlzc2lvbiBTdGFydCBEYXRlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwIGNvbC1zbS04XCI+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBwbGFjZWhvbGRlcj1cImRkL21tL3l5eXlcIiBmb3JtQ29udHJvbE5hbWU9XCJzdGFydERhdGVcIiBuZ2JEYXRlcGlja2VyXHJcbiAgICAgICAgICAgICAgICAgICAgI2QxPVwibmdiRGF0ZXBpY2tlclwiIGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLXN0YXJ0RGF0ZVwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmVyaWZEYXRlKCk7b25WZXJpZkZvcm0oKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydpcy1pbnZhbGlkJyA6IHZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydzdGFydERhdGUnXSl8fCBpc0Zvcm1FcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1snc3RhcnREYXRlJ10pfSBcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cC1hcHBlbmRcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXNlY29uZGFyeSBjYWxlbmRhclwiIChjbGljayk9XCJkMS50b2dnbGUoKVwiIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLXN0YXJ0RGF0ZS1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiICpuZ0lmPVwiIHZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydzdGFydERhdGUnXSkgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHx8ICBpc0Zvcm1FcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1snc3RhcnREYXRlJ10pXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7dmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ3N0YXJ0RGF0ZSddKSB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxuZ2ItYWxlcnQgZGF0YS10ZXN0aWQ9XCJmb3JtLW1pc3Npb24tc3RhcnREYXRlLWludmFsaWQtdmVyaWZcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkYXRlRXJyb3JcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3snZXJyb3JGb3JtLmRhdGVfc3RhcnRfZW5kJyB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHJvd1wiPlxyXG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tNCBjb2wtZm9ybS1sYWJlbFwiPnt7J01pc3Npb24gU3RhcnQgVGltZScgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cCBjb2wtc20tOCB0aW1lWm9uZUNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgPG5nYi10aW1lcGlja2VyIFsobmdNb2RlbCldPVwibWlzc2lvblRpbWVTdGFydFwiIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIlxyXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmVyaWZEYXRlKCk7b25WZXJpZkZvcm0oKVwiPjwvbmdiLXRpbWVwaWNrZXI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCByb3dcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTQgY29sLWZvcm0tbGFiZWxcIj57eydNaXNzaW9uIEVuZCBEYXRlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwIGNvbC1zbS04XCI+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBwbGFjZWhvbGRlcj1cImRkL21tL3l5eXlcIiBuZ2JEYXRlcGlja2VyICNkMj1cIm5nYkRhdGVwaWNrZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImVuZERhdGVcIiBkYXRhLXRlc3RpZD1cImZvcm0tbWlzc2lvbi1lbmREYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJ2YWxpZGF0b3JzU2VydmljZS5pc0NvbnRyb2xFcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1snZW5kRGF0ZSddKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydpcy1pbnZhbGlkJyA6IHZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydlbmREYXRlJ10pfHwgaXNGb3JtRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ2VuZERhdGUnXSl9IFwiXHJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25WZXJpZkRhdGUoKTtvblZlcmlmRm9ybSgpXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAtYXBwZW5kXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1zZWNvbmRhcnkgY2FsZW5kYXJcIiAoY2xpY2spPVwiZDIudG9nZ2xlKClcIiB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cImZvcm0tbWlzc2lvbi1lbmREYXRlLWludmFsaWRcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCIgKm5nSWY9XCIgdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IobWlzc2lvbkZvcm0uY29udHJvbHNbJ2VuZERhdGUnXSkgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHx8ICBpc0Zvcm1FcnJvcihtaXNzaW9uRm9ybS5jb250cm9sc1snZW5kRGF0ZSddKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7e3ZhbGlkYXRvcnNTZXJ2aWNlLmdldEVycm9yKG1pc3Npb25Gb3JtLmNvbnRyb2xzWydlbmREYXRlJ10pIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX1cclxuICAgICAgICAgICAgICAgICAgICA8L25nYi1hbGVydD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cImZvcm0tbWlzc2lvbi1lbmREYXRlLWludmFsaWQtdmVyaWZcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkYXRlRXJyb3JcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3snZXJyb3JGb3JtLmRhdGVfZW5kX3N0YXJ0JyB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHJvd1wiPlxyXG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tNCBjb2wtZm9ybS1sYWJlbFwiPnt7J01pc3Npb24gRW5kIFRpbWUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAgY29sLXNtLTggdGltZVpvbmVDb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgIDxuZ2ItdGltZXBpY2tlciBbKG5nTW9kZWwpXT1cIm1pc3Npb25UaW1lRW5kXCIgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25WZXJpZkRhdGUoKTtvblZlcmlmRm9ybSgpXCI+PC9uZ2ItdGltZXBpY2tlcj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJidG4tY29udHJvbC1kaXYgYWN0aW9uLWJ1dHRvbi1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbXItMyBhY3Rpb24tYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLXN1Ym1pdC1idG5cIiBbbmdDbGFzc109XCJ7J2lzLWludmFsaWQnIDogZXJyb3JGb3JtIH1cIj57eydTYXZlJyB8XHJcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25DYW5jZWwoKVwiIGRhdGEtdGVzdGlkPVwiZm9ybS1taXNzaW9uLWNhbmNlbC1idG5cIlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgYWN0aW9uLWJ1dHRvblwiPnt7J0NhbmNlbCcgfFxyXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiICpuZ0lmPVwiZXJyb3JGb3JtXCI+XHJcbiAgICAgICAgICAgIDxuZ2ItYWxlcnQgZGF0YS10ZXN0aWQ9XCJmb3JtLW1pc3Npb24taW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIj5cclxuICAgICAgICAgICAgICAgIHt7J2Vycm9yRm9ybS5pbmZvQnRuJyB8dHJhbnNsYXRlfX1cclxuICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Zvcm0+XHJcbjwvZGl2PiJdfQ==