@rangertechnologies/ngnxt 2.1.254 → 2.1.255

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 (78) hide show
  1. package/fesm2022/rangertechnologies-ngnxt.mjs +138 -169
  2. package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
  3. package/lib/components/pick-location/pick-location.component.d.ts +0 -1
  4. package/package.json +4 -6
  5. package/rangertechnologies-ngnxt-2.1.255.tgz +0 -0
  6. package/esm2022/environments/version.mjs +0 -15
  7. package/esm2022/lib/components/button/nxt-button.component.mjs +0 -154
  8. package/esm2022/lib/components/custom-calendar/custom-calendar.component.mjs +0 -360
  9. package/esm2022/lib/components/custom-dropdown/custom-dropdown.component.mjs +0 -263
  10. package/esm2022/lib/components/custom-model/custom-model.component.mjs +0 -53
  11. package/esm2022/lib/components/custom-radio/custom-radio.component.mjs +0 -158
  12. package/esm2022/lib/components/datatable/datatable.component.mjs +0 -1744
  13. package/esm2022/lib/components/file-upload/file-upload.component.mjs +0 -292
  14. package/esm2022/lib/components/icon-selector/icon-selector.component.mjs +0 -106
  15. package/esm2022/lib/components/image-cropper/component/cropper.state.mjs +0 -208
  16. package/esm2022/lib/components/image-cropper/component/image-cropper.component.mjs +0 -562
  17. package/esm2022/lib/components/image-cropper/interfaces/basic-event.interface.mjs +0 -2
  18. package/esm2022/lib/components/image-cropper/interfaces/cropper-options.interface.mjs +0 -2
  19. package/esm2022/lib/components/image-cropper/interfaces/cropper-position.interface.mjs +0 -2
  20. package/esm2022/lib/components/image-cropper/interfaces/dimensions.interface.mjs +0 -2
  21. package/esm2022/lib/components/image-cropper/interfaces/exif-transform.interface.mjs +0 -2
  22. package/esm2022/lib/components/image-cropper/interfaces/image-cropped-event.interface.mjs +0 -2
  23. package/esm2022/lib/components/image-cropper/interfaces/image-transform.interface.mjs +0 -2
  24. package/esm2022/lib/components/image-cropper/interfaces/index.mjs +0 -2
  25. package/esm2022/lib/components/image-cropper/interfaces/loaded-image.interface.mjs +0 -2
  26. package/esm2022/lib/components/image-cropper/interfaces/move-start.interface.mjs +0 -8
  27. package/esm2022/lib/components/image-cropper/services/crop.service.mjs +0 -139
  28. package/esm2022/lib/components/image-cropper/services/load-image.service.mjs +0 -194
  29. package/esm2022/lib/components/image-cropper/utils/cropper-position.utils.mjs +0 -239
  30. package/esm2022/lib/components/image-cropper/utils/exif.utils.mjs +0 -79
  31. package/esm2022/lib/components/image-cropper/utils/keyboard.utils.mjs +0 -40
  32. package/esm2022/lib/components/image-cropper/utils/percentage.utils.mjs +0 -4
  33. package/esm2022/lib/components/image-cropper/utils/resize.utils.mjs +0 -75
  34. package/esm2022/lib/components/list-view-filter/list-view-filter.component.mjs +0 -392
  35. package/esm2022/lib/components/nxt-input/nxt-input.component.mjs +0 -2972
  36. package/esm2022/lib/components/pagination/pagination.component.mjs +0 -105
  37. package/esm2022/lib/components/pick-location/pick-location.component.mjs +0 -220
  38. package/esm2022/lib/components/search-box/search-box.component.mjs +0 -470
  39. package/esm2022/lib/country.json +0 -43237
  40. package/esm2022/lib/interfaces/actionMeta.mjs +0 -2
  41. package/esm2022/lib/interfaces/dependencyMeta.mjs +0 -2
  42. package/esm2022/lib/model/bookletWrapper.mjs +0 -7
  43. package/esm2022/lib/model/changeWrapper.mjs +0 -10
  44. package/esm2022/lib/model/errorWrapper.mjs +0 -6
  45. package/esm2022/lib/nxt-app.component.mjs +0 -22
  46. package/esm2022/lib/nxt-app.module.mjs +0 -115
  47. package/esm2022/lib/nxt-app.service.mjs +0 -14
  48. package/esm2022/lib/pages/booklet/booklet.component.mjs +0 -616
  49. package/esm2022/lib/pages/builder/element/element.component.mjs +0 -483
  50. package/esm2022/lib/pages/builder/form/form.component.mjs +0 -48
  51. package/esm2022/lib/pages/builder/properties/common-fields.constants.mjs +0 -97
  52. package/esm2022/lib/pages/builder/properties/properties.component.mjs +0 -1121
  53. package/esm2022/lib/pages/builder/templates/templates.component.mjs +0 -35
  54. package/esm2022/lib/pages/pdfDesigner/pdf-designer/pdf-designer.component.mjs +0 -639
  55. package/esm2022/lib/pages/pdfDesigner/pdf-properties/pdf-properties.component.mjs +0 -1114
  56. package/esm2022/lib/pages/questionbook/questionbook.component.mjs +0 -784
  57. package/esm2022/lib/pages/questionnaire/questionnaire.component.mjs +0 -2206
  58. package/esm2022/lib/pipe/button-styles.pipe.mjs +0 -26
  59. package/esm2022/lib/pipe/custom-translate.pipe.mjs +0 -37
  60. package/esm2022/lib/pipe/get-value.pipe.mjs +0 -54
  61. package/esm2022/lib/pipe/question-by-row.pipe.mjs +0 -51
  62. package/esm2022/lib/pipe/search-filter/search-filter.pipe.mjs +0 -40
  63. package/esm2022/lib/pipe/svg/svg.pipe.mjs +0 -26
  64. package/esm2022/lib/sample.mjs +0 -3715
  65. package/esm2022/lib/services/change/change.service.mjs +0 -46
  66. package/esm2022/lib/services/country/country.service.mjs +0 -135
  67. package/esm2022/lib/services/data/data.service.mjs +0 -100
  68. package/esm2022/lib/services/form-builder/form-builder.service.mjs +0 -474
  69. package/esm2022/lib/services/pdf-designer/pdf-designer.service.mjs +0 -395
  70. package/esm2022/lib/services/salesforce/salesforce.service.mjs +0 -41
  71. package/esm2022/lib/services/shared/shared.service.mjs +0 -100
  72. package/esm2022/lib/services/storage/storage.service.mjs +0 -59
  73. package/esm2022/lib/services/template/template.service.mjs +0 -335
  74. package/esm2022/lib/services/translation/translation.service.mjs +0 -121
  75. package/esm2022/lib/wrapper.mjs +0 -175
  76. package/esm2022/public-api.mjs +0 -22
  77. package/esm2022/rangertechnologies-ngnxt.mjs +0 -5
  78. package/rangertechnologies-ngnxt-2.1.254.tgz +0 -0
@@ -1,470 +0,0 @@
1
- import { Component, Input, Output, EventEmitter, ViewChild, signal, HostListener } from "@angular/core";
2
- import { ChangeWrapper } from "../../model/changeWrapper";
3
- import { CommonModule } from "@angular/common";
4
- import { FormsModule } from "@angular/forms";
5
- import { NxtInput } from "../nxt-input/nxt-input.component";
6
- import { Subject, debounceTime, distinctUntilChanged, takeUntil } from "rxjs";
7
- import { NxtCustomTranslatePipe } from "../../pipe/custom-translate.pipe";
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "../../services/storage/storage.service";
10
- import * as i2 from "../../services/change/change.service";
11
- import * as i3 from "../../services/data/data.service";
12
- import * as i4 from "../../services/country/country.service";
13
- import * as i5 from "@angular/common";
14
- export class NxtSearchBox {
15
- storageService;
16
- changeService;
17
- dataService;
18
- countryService;
19
- elementRef;
20
- placeHolderText = '';
21
- question;
22
- apiMeta;
23
- id = '';
24
- readOnly = false;
25
- mode = 'edit';
26
- from;
27
- searchValueChange = new EventEmitter();
28
- searchWrapper;
29
- SearchItem;
30
- finalResults = signal([]);
31
- searchKeyWord = '';
32
- newResult;
33
- showResult = false;
34
- noResult = false;
35
- showSuggestion = false;
36
- isLoading = false;
37
- viewFilterName = '';
38
- isSingleFieldChange = false;
39
- valueObj;
40
- inputFocused = false;
41
- lastSearchLength = 0;
42
- filterName = '';
43
- destroy$ = new Subject();
44
- searchSubject = new Subject();
45
- subscription;
46
- // TrackBy function for performance optimization
47
- trackByFn = (index, item) => {
48
- return item.id || item.name || index;
49
- };
50
- constructor(storageService, changeService, dataService, countryService, elementRef) {
51
- this.storageService = storageService;
52
- this.changeService = changeService;
53
- this.dataService = dataService;
54
- this.countryService = countryService;
55
- this.elementRef = elementRef;
56
- if (this.question?.input && typeof this.question?.input === 'object' && !Array.isArray(this.question?.input)) {
57
- this.clickItem(this.question?.input);
58
- }
59
- else {
60
- this.filterName = this.question?.input;
61
- }
62
- // Setup debounced search
63
- this.searchSubject
64
- .pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.destroy$))
65
- .subscribe(keyword => {
66
- if (this.lastSearchLength > 2)
67
- this.performSearch(keyword);
68
- });
69
- }
70
- ngOnInit() {
71
- if (this.question?.input && typeof this.question?.input === 'object' && !Array.isArray(this.question?.input)) {
72
- this.clickItem(this.question?.input);
73
- }
74
- else if (Array.isArray(this.question?.input)) {
75
- this.filterName = '';
76
- this.viewFilterName = '';
77
- }
78
- else {
79
- this.filterName = this.question?.input;
80
- this.viewFilterName = this.question?.input;
81
- }
82
- this.parseApiMeta();
83
- if (this.question?.subText != undefined) {
84
- let dependencyObj = this.question?.subText;
85
- // Subscribe for the changes
86
- this.subscription = this.changeService.changeAnnounced$.subscribe((changeValue) => {
87
- if (changeValue != undefined) {
88
- if (changeValue.fromQuestionId && changeValue.valueObj !== undefined && (Array.isArray(dependencyObj.sourceQuestionId) ? dependencyObj.sourceQuestionId.includes(changeValue.fromQuestionId) : changeValue.fromQuestionId === dependencyObj.sourceQuestionId)) {
89
- if (Array.isArray(dependencyObj.queryValue) ? dependencyObj.queryValue.includes(changeValue.referenceField) : changeValue.referenceField === dependencyObj.queryValue) {
90
- this.storageService.queryValueStore(this.question.id, changeValue.referenceField, changeValue.valueObj);
91
- }
92
- }
93
- this.changeService.confirmChange(changeValue.fromQuestionId);
94
- }
95
- });
96
- }
97
- }
98
- ngOnChanges(changes) {
99
- if (changes['question']) {
100
- // if(this.question?.input && typeof this.question?.input === 'object' && !Array.isArray(this.question?.input)){
101
- // this.clickItem(this.question?.input)
102
- // } else {
103
- // this.filterName = this.question?.input
104
- // }
105
- }
106
- if (changes['mode']) {
107
- this.mode = changes['mode'].currentValue;
108
- }
109
- if (changes['apiMeta'] && this.apiMeta) {
110
- this.parseApiMeta();
111
- }
112
- }
113
- ngOnDestroy() {
114
- this.destroy$.next();
115
- this.destroy$.complete();
116
- this.resetComponentState();
117
- }
118
- // Handle clicks outside the search component
119
- onDocumentClick(event) {
120
- if (!this.elementRef.nativeElement.contains(event.target)) {
121
- this.hideSuggestions();
122
- }
123
- }
124
- // Handle escape key to close suggestions
125
- onEscapeKey(event) {
126
- this.hideSuggestions();
127
- }
128
- parseApiMeta() {
129
- if (this.apiMeta) {
130
- this.apiMeta = typeof this.apiMeta === 'object' ? this.apiMeta : JSON.parse(this.apiMeta || '{}');
131
- this.SearchItem = this.apiMeta.field || [];
132
- }
133
- }
134
- resetComponentState() {
135
- this.finalResults.set([]);
136
- this.searchKeyWord = '';
137
- this.showSuggestion = false;
138
- this.noResult = false;
139
- this.isLoading = false;
140
- this.inputFocused = false;
141
- this.lastSearchLength = 0;
142
- }
143
- hideSuggestions() {
144
- this.showSuggestion = false;
145
- this.inputFocused = false;
146
- }
147
- onInputFocus() {
148
- this.inputFocused = true;
149
- // Trigger a search with an empty keyword to show all data
150
- if (!this.searchKeyWord) {
151
- // this.performSearch('');
152
- }
153
- else if (this.finalResults().length > 0) {
154
- this.showSuggestion = true;
155
- }
156
- }
157
- onInputBlur() {
158
- // Don't immediately hide suggestions to allow for clicking
159
- // The document click handler will handle hiding
160
- }
161
- clearList() {
162
- // Remove the setTimeout delay that was causing issues
163
- this.hideSuggestions();
164
- }
165
- getSourceDataLocal(event) {
166
- if (!event?.value?.valueObj) {
167
- this.resetComponentState();
168
- return;
169
- }
170
- const searchValue = event.value?.valueObj?.includes('|') ? event.value?.valueObj?.split('|')[0].trim() : event.value?.valueObj?.trim();
171
- const currentLength = searchValue.length;
172
- // Always update the search keyword
173
- this.searchKeyWord = searchValue;
174
- // Handle the case where user types 3+ characters
175
- if (currentLength > 2 && !this.isSingleFieldChange) {
176
- this.showSuggestion = !event.question?.singleFieldChange;
177
- this.showResult = false;
178
- this.noResult = false;
179
- // Always perform search when we have 3+ characters
180
- this.lastSearchLength = currentLength;
181
- this.searchSubject.next(searchValue);
182
- }
183
- else if (currentLength <= 2) {
184
- // When length is 2 or less, hide suggestions but keep the search keyword
185
- this.isSingleFieldChange = false;
186
- this.showSuggestion = false;
187
- this.noResult = false;
188
- this.lastSearchLength = currentLength;
189
- this.searchSubject.next(searchValue);
190
- this.finalResults.set([]);
191
- }
192
- }
193
- performSearch(keyword) {
194
- if (!this.apiMeta)
195
- return;
196
- this.parseApiMeta();
197
- if (!this.apiMeta.isStaticData) {
198
- this.searchFromApi(keyword);
199
- }
200
- else {
201
- this.searchFromStaticData(keyword);
202
- }
203
- }
204
- searchFromApi(keyword) {
205
- this.isLoading = true;
206
- this.finalResults.set([]);
207
- if (!this.apiMeta.endpoint && Array.isArray(this.question?.input)) {
208
- this.isLoading = false;
209
- this.processSearchResults(this.question?.input, keyword);
210
- }
211
- else {
212
- let finalGetCall = this.apiMeta.endpoint;
213
- // SKS18JUL25 query params creation
214
- if (this.apiMeta?.queryParameter) {
215
- const isFieldArray = Array.isArray(this.apiMeta?.queryParameter);
216
- const fields = isFieldArray ? this.apiMeta.queryParameter : [this.apiMeta.queryParameter]; // always an array now
217
- // Build query params string
218
- const queryParams = fields
219
- .map(field => `${field}=${this.searchKeyWord}`)
220
- .join('&');
221
- // Check if endpoint already has query params
222
- if (queryParams && queryParams !== '') {
223
- if (this.apiMeta.endpoint.includes('?')) {
224
- finalGetCall += `&${queryParams}`;
225
- }
226
- else {
227
- finalGetCall += `?${queryParams}`;
228
- }
229
- }
230
- }
231
- if (this.apiMeta?.queryField && this.apiMeta?.queryValue) {
232
- const queryFields = Array.isArray(this.apiMeta.queryField)
233
- ? this.apiMeta.queryField
234
- : [this.apiMeta.queryField];
235
- const queryValues = Array.isArray(this.apiMeta.queryValue)
236
- ? this.apiMeta.queryValue
237
- : [this.apiMeta.queryValue];
238
- const stored = this.storageService.getQueryValue(this.question.id); // single object
239
- const queryParamsArray = [];
240
- queryFields.forEach((field, index) => {
241
- const valueKey = queryValues[index] ?? queryValues[0];
242
- const value = stored[valueKey];
243
- if (value !== undefined && value !== null) {
244
- queryParamsArray.push(`${field}=${encodeURIComponent(value)}`);
245
- }
246
- });
247
- const queryParams = queryParamsArray.join('&');
248
- if (queryParams) {
249
- finalGetCall += this.apiMeta.endpoint.includes('?') ? `&${queryParams}` : `?${queryParams}`;
250
- }
251
- }
252
- this.dataService.apiResponse(finalGetCall)
253
- .pipe(takeUntil(this.destroy$))
254
- .subscribe({
255
- next: (apiResponse) => {
256
- this.isLoading = false;
257
- this.processSearchResults(apiResponse, keyword);
258
- },
259
- error: (error) => {
260
- this.isLoading = false;
261
- this.noResult = true;
262
- this.finalResults.set([]);
263
- }
264
- });
265
- }
266
- }
267
- searchFromStaticData(keyword) {
268
- const response = this.countryService.getCountryData(this.apiMeta.field);
269
- this.processSearchResults(response, keyword);
270
- }
271
- processSearchResults(apiResponse, keyword) {
272
- let response;
273
- if (this.apiMeta.variable) {
274
- response = this.dataService.getValue(apiResponse, this.apiMeta.variable);
275
- }
276
- else {
277
- response = apiResponse;
278
- }
279
- if (!Array.isArray(response)) {
280
- this.noResult = true;
281
- this.finalResults.set([]);
282
- return;
283
- }
284
- if (!keyword) {
285
- // If no keyword, show all results
286
- this.finalResults.set(response);
287
- this.noResult = response.length === 0;
288
- this.showSuggestion = true; // Ensure suggestions are visible
289
- }
290
- else {
291
- // Filter results based on the keyword
292
- const searchTerms = keyword.toLowerCase().split(" ").filter(term => term.length > 0);
293
- const results = response.filter(obj => {
294
- const combinedValues = this.getCombinedValuesFromColumns(obj, this.apiMeta.field);
295
- return searchTerms.every(term => combinedValues.includes(term));
296
- });
297
- this.noResult = results.length === 0;
298
- this.finalResults.set(results);
299
- this.showSuggestion = true; // Show suggestions only if there are results
300
- }
301
- }
302
- getNestedValue(obj, path) {
303
- if (!obj || !path)
304
- return '';
305
- const processedPath = path.replace(/\[(\d+)\]/g, '.$1');
306
- const parts = processedPath.split('.');
307
- let current = obj;
308
- for (const part of parts) {
309
- if (!current || typeof current !== 'object')
310
- return '';
311
- current = current[part];
312
- }
313
- return current !== null && current !== undefined
314
- ? String(current).toLowerCase().trim()
315
- : '';
316
- }
317
- getCombinedValuesFromColumns(obj, columns) {
318
- if (!obj || !columns)
319
- return '';
320
- const columnArray = Array.isArray(columns) ? columns : [columns];
321
- const values = [];
322
- for (const column of columnArray) {
323
- const value = this.getNestedValue(obj, column);
324
- if (value) {
325
- values.push(value);
326
- }
327
- }
328
- return values.join(' ');
329
- }
330
- getValues(element, columns) {
331
- const result = {};
332
- if (!element || !columns)
333
- return result;
334
- const columnArray = Array.isArray(columns) ? columns : [columns];
335
- columnArray.forEach((column) => {
336
- if (!column)
337
- return;
338
- let tempElement = element;
339
- const fields = column.split('.');
340
- for (const field of fields) {
341
- if (!tempElement)
342
- break;
343
- const splitFields = field.split('[');
344
- if (splitFields.length === 1) {
345
- tempElement = tempElement[field];
346
- }
347
- else {
348
- const indexMatch = splitFields[1]?.match(/(\d+)\]/);
349
- if (indexMatch) {
350
- const index = Number(indexMatch[1]);
351
- tempElement = tempElement[splitFields[0]]?.[index];
352
- }
353
- }
354
- }
355
- result[column] = tempElement || '';
356
- });
357
- return result;
358
- }
359
- getKeys(obj) {
360
- return obj ? Object.keys(obj) : [];
361
- }
362
- clickItem(event) {
363
- if (!this.apiMeta)
364
- return;
365
- this.parseApiMeta();
366
- const values = this.getValues(event, this.SearchItem);
367
- const displayValue = Object.values(values)
368
- .filter(val => val)
369
- .join(' | ');
370
- if (this.mode !== 'edit') {
371
- this.viewFilterName = displayValue;
372
- }
373
- this.filterName = displayValue;
374
- this.ngOnChanges({});
375
- const defaultField = this.apiMeta.defaultField ||
376
- (Array.isArray(this.apiMeta?.field) ? this.apiMeta?.field?.[0] : this.apiMeta.field);
377
- const change = new ChangeWrapper();
378
- change['isObject'] = this.apiMeta?.isObject;
379
- change['fromQuestionId'] = this.id;
380
- change['valueObj'] = event;
381
- change['field'] = defaultField;
382
- this.valueObj = event;
383
- this.hideSuggestions();
384
- this.searchValueChange.emit({
385
- question: this.question,
386
- value: change
387
- });
388
- }
389
- inputValue(event, ques) {
390
- this.filterName = event?.valueObj ? event?.valueObj?.trim() : this.filterName;
391
- if (!ques?.singleFieldChange || !this.apiMeta)
392
- return;
393
- this.isSingleFieldChange = true;
394
- this.parseApiMeta();
395
- const defaultField = this.apiMeta.defaultField ||
396
- (Array.isArray(this.apiMeta?.field) ? this.apiMeta?.field?.[0] : this.apiMeta.field);
397
- const change = new ChangeWrapper();
398
- change['isObject'] = this.apiMeta?.isObject;
399
- change['fromQuestionId'] = this.id;
400
- change['valueObj'] = this.valueObj;
401
- change['field'] = defaultField;
402
- change['referenceField'] = this.question.referenceField;
403
- this.filterName = this.viewFilterName;
404
- this.searchValueChange.emit({
405
- question: ques,
406
- value: change
407
- });
408
- }
409
- highlightText(text, searchTerm) {
410
- if (!text || !searchTerm)
411
- return text || '';
412
- // Sanitize the input text
413
- const sanitizedText = this.sanitizeHtml(text);
414
- const terms = searchTerm.toLowerCase().split(' ').filter(term => term.length > 0);
415
- if (terms.length === 0)
416
- return sanitizedText;
417
- // Escape special regex characters
418
- const escapedTerms = terms.map(term => term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
419
- const regex = new RegExp(`(${escapedTerms.join('|')})`, 'gi');
420
- return sanitizedText.replace(regex, '<span class="highlight">$1</span>');
421
- }
422
- sanitizeHtml(text) {
423
- return text
424
- .replace(/&/g, '&amp;')
425
- .replace(/</g, '&lt;')
426
- .replace(/>/g, '&gt;')
427
- .replace(/"/g, '&quot;')
428
- .replace(/'/g, '&#39;');
429
- }
430
- removeValueEmit() {
431
- this.clickItem(null);
432
- }
433
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NxtSearchBox, deps: [{ token: i1.StorageService }, { token: i2.ChangeService }, { token: i3.DataService }, { token: i4.CountryService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
434
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NxtSearchBox, isStandalone: true, selector: "nxt-search-box", inputs: { placeHolderText: "placeHolderText", question: "question", apiMeta: "apiMeta", id: "id", readOnly: "readOnly", mode: "mode", from: "from" }, outputs: { searchValueChange: "searchValueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscapeKey($event)" } }, viewQueries: [{ propertyName: "searchWrapper", first: true, predicate: ["searchWrapper"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- VD 12Jun24 - readonly change -->\n<div class=\"search-wrapper\" #searchWrapper>\n <nxt-input \n [type]=\"'list'\" \n [mode]=\"mode\" \n [from]=\"from\"\n [value]=\"mode === 'edit' ? filterName : viewFilterName\"\n [labelFont]=\"question?.font\" \n [label]=\"question?.questionText ? ((question?.id+'.questionText') | nxtCustomTranslate : question?.questionText): ''\" \n [labelColor]=\"question?.fontColor\"\n [labelSize]=\"question?.fontSize\" \n [inputValueSize]=\"question?.fontSize\" \n [labelWeight]=\"question?.fontWeight\"\n [inputWeight]=\"question?.fontWeight\" \n [showLabel]=\"question?.style?.showLabel\" \n inputBorder=\"none\" \n svgHeight=\"20px\"\n svgWidth=\"20px\" \n [placeholder]=\"placeHolderText\" \n [required]=\"question?.isOptional\" \n inputBgColor=\"#FAFAFA\"\n [inputId]=\"question?.trackingId\" \n [errorMessages]=\"{ required: 'This field is required' }\"\n [inputIconLeftSrc]=\"question?.iconLeftSrc\" \n (inputValue)=\"getSourceDataLocal($event); inputValue($event.value, $event.question)\" \n (onFocus)=\"onInputFocus()\"\n (onBlur)=\"onInputBlur()\"\n [showSuggestion]=\"showSuggestion\" \n ariaOwns=\"selectList\" \n ariaHasPopup=\"listbox\" \n [isLoading]=\"isLoading\" \n [question]=\"question\"\n (removeValueEmit)=\"removeValueEmit()\">\n </nxt-input>\n\n <div id=\"selectList\" class=\"suggestion-wrapper\" role=\"listbox\" *ngIf=\"showSuggestion\">\n <div *ngIf=\"finalResults().length > 0\" class=\"nxt-suggestions-container\">\n <div *ngFor=\"let item of finalResults(); trackBy: trackByFn\" \n (click)=\"clickItem(item)\" \n class=\"suggestion-item\" \n role=\"option\"\n tabindex=\"0\"\n (keydown.enter)=\"clickItem(item)\"\n (keydown.space)=\"clickItem(item)\">\n <div class=\"item-content\">\n <div class=\"item-details\">\n <div *ngIf=\"item.thumbnail\" class=\"thumbnail-wrapper\">\n <img [src]=\"item.thumbnail\" [alt]=\"item.name + ' avatar'\" />\n </div>\n <div class=\"item-text\">\n <!-- Primary text (first key) -->\n <ng-container *ngIf=\"getKeys(getValues(item, SearchItem)).length > 0\">\n <div class=\"item-name primary\" \n [innerHTML]=\"highlightText(getValues(item, SearchItem)[getKeys(getValues(item, SearchItem))[0]], searchKeyWord)\">\n </div>\n </ng-container>\n \n <!-- Secondary text (remaining keys) -->\n <div class=\"item-secondary\" *ngIf=\"getKeys(getValues(item, SearchItem)).length > 1\">\n <ng-container *ngFor=\"let key of getKeys(getValues(item, SearchItem)); let i = index\">\n <ng-container *ngIf=\"i > 0\">\n <span class=\"secondary-text\" \n [innerHTML]=\"highlightText(getValues(item, SearchItem)[key], searchKeyWord)\">\n </span>\n <span class=\"separator\" *ngIf=\"i < getKeys(getValues(item, SearchItem)).length - 1\"> | </span>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"noResult && searchKeyWord\" class=\"no-results\">\n <div class=\"no-results-content\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <path d=\"m21 21-4.35-4.35\"></path>\n </svg>\n <p>{{ 'NO_RESULTS_FOUND' | nxtCustomTranslate : 'No results found for' }} \"{{searchKeyWord}}\"</p>\n </div>\n </div>\n </div>\n</div>", styles: [".search-wrapper{position:relative;width:100%}.suggestion-wrapper{position:absolute;top:100%;left:0;right:0;background:#fff;border:1px solid #e0e0e0;border-top:none;border-radius:0 0 4px 4px;box-shadow:0 2px 8px #0000001a;z-index:1000;max-height:300px;overflow:hidden}.nxt-suggestions-container{max-height:300px;overflow-y:auto;min-width:100%}.suggestion-item{cursor:pointer;border-bottom:1px solid #f0f0f0;transition:background-color .2s ease;outline:none}.suggestion-item:hover,.suggestion-item:focus{background-color:#f5f5f5}.suggestion-item:last-child{border-bottom:none}.item-content{padding:5px}.item-details{display:flex;align-items:flex-start;gap:12px;text-align:left}.thumbnail-wrapper{flex-shrink:0}.thumbnail-wrapper img{width:40px;height:40px;border-radius:50%;object-fit:cover;border:1px solid #e0e0e0}.item-text{flex:1;min-width:0}.item-name{font-size:14px;font-weight:500;color:#333;line-height:1.4;margin-bottom:2px;word-wrap:break-word;overflow-wrap:break-word}.item-secondary{font-size:12px;color:#666;line-height:1.3;display:flex}.secondary-text{display:inline}.separator{color:#999;margin:0 3px}.no-results{padding:20px;text-align:center;color:#666}.no-results-content{display:flex;align-items:center;justify-content:center;gap:8px;flex-direction:column}.no-results-content svg{color:#d1d5db;margin-bottom:8px}.no-results-content p{color:#6b7280;margin:0;font-size:14px;font-weight:500}:host ::ng-deep .highlight{font-weight:700;display:inline}.nxt-suggestions-container::-webkit-scrollbar{width:6px}.nxt-suggestions-container::-webkit-scrollbar-track{background:#f1f1f1}.nxt-suggestions-container::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.nxt-suggestions-container::-webkit-scrollbar-thumb:hover{background:#a8a8a8}@media (max-width: 768px){.suggestion-wrapper,.nxt-suggestions-container{max-height:250px}.item-content{padding:10px 12px}.item-details{gap:8px}.thumbnail-wrapper img{width:32px;height:32px}.item-name{font-size:13px}.item-secondary{font-size:11px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: NxtInput, selector: "nxt-input", inputs: ["label", "labelFont", "labelWeight", "inputWeight", "labelSize", "inputValueSize", "labelColor", "showLabel", "svgHeight", "svgWidth", "type", "inputIconRightSrc", "inputIconLeftSrc", "required", "minLength", "pattern", "errorMessages", "maxLength", "placeholder", "inputBgColor", "inputBorder", "placeholderColor", "placeholderFont", "placeholderWeight", "placeholderSize", "inputTextColor", "inputHeight", "inputWidth", "inputId", "inputBorderSize", "inputConfig", "confPassVal", "confPass", "mode", "value", "question", "showSuggestion", "ariaOwns", "ariaHasPopup", "isLoading", "options", "minDate", "maxDate", "rows", "from", "hyperLink", "size"], outputs: ["valueChange", "inputValue", "onBlur", "onFocus", "toggleEmit", "nativeInputRef", "removeValueEmit", "hyperlinkEmit"] }, { kind: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }] });
435
- }
436
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NxtSearchBox, decorators: [{
437
- type: Component,
438
- args: [{ selector: 'nxt-search-box', standalone: true, imports: [
439
- CommonModule,
440
- FormsModule,
441
- NxtInput,
442
- NxtCustomTranslatePipe
443
- ], template: "<!-- VD 12Jun24 - readonly change -->\n<div class=\"search-wrapper\" #searchWrapper>\n <nxt-input \n [type]=\"'list'\" \n [mode]=\"mode\" \n [from]=\"from\"\n [value]=\"mode === 'edit' ? filterName : viewFilterName\"\n [labelFont]=\"question?.font\" \n [label]=\"question?.questionText ? ((question?.id+'.questionText') | nxtCustomTranslate : question?.questionText): ''\" \n [labelColor]=\"question?.fontColor\"\n [labelSize]=\"question?.fontSize\" \n [inputValueSize]=\"question?.fontSize\" \n [labelWeight]=\"question?.fontWeight\"\n [inputWeight]=\"question?.fontWeight\" \n [showLabel]=\"question?.style?.showLabel\" \n inputBorder=\"none\" \n svgHeight=\"20px\"\n svgWidth=\"20px\" \n [placeholder]=\"placeHolderText\" \n [required]=\"question?.isOptional\" \n inputBgColor=\"#FAFAFA\"\n [inputId]=\"question?.trackingId\" \n [errorMessages]=\"{ required: 'This field is required' }\"\n [inputIconLeftSrc]=\"question?.iconLeftSrc\" \n (inputValue)=\"getSourceDataLocal($event); inputValue($event.value, $event.question)\" \n (onFocus)=\"onInputFocus()\"\n (onBlur)=\"onInputBlur()\"\n [showSuggestion]=\"showSuggestion\" \n ariaOwns=\"selectList\" \n ariaHasPopup=\"listbox\" \n [isLoading]=\"isLoading\" \n [question]=\"question\"\n (removeValueEmit)=\"removeValueEmit()\">\n </nxt-input>\n\n <div id=\"selectList\" class=\"suggestion-wrapper\" role=\"listbox\" *ngIf=\"showSuggestion\">\n <div *ngIf=\"finalResults().length > 0\" class=\"nxt-suggestions-container\">\n <div *ngFor=\"let item of finalResults(); trackBy: trackByFn\" \n (click)=\"clickItem(item)\" \n class=\"suggestion-item\" \n role=\"option\"\n tabindex=\"0\"\n (keydown.enter)=\"clickItem(item)\"\n (keydown.space)=\"clickItem(item)\">\n <div class=\"item-content\">\n <div class=\"item-details\">\n <div *ngIf=\"item.thumbnail\" class=\"thumbnail-wrapper\">\n <img [src]=\"item.thumbnail\" [alt]=\"item.name + ' avatar'\" />\n </div>\n <div class=\"item-text\">\n <!-- Primary text (first key) -->\n <ng-container *ngIf=\"getKeys(getValues(item, SearchItem)).length > 0\">\n <div class=\"item-name primary\" \n [innerHTML]=\"highlightText(getValues(item, SearchItem)[getKeys(getValues(item, SearchItem))[0]], searchKeyWord)\">\n </div>\n </ng-container>\n \n <!-- Secondary text (remaining keys) -->\n <div class=\"item-secondary\" *ngIf=\"getKeys(getValues(item, SearchItem)).length > 1\">\n <ng-container *ngFor=\"let key of getKeys(getValues(item, SearchItem)); let i = index\">\n <ng-container *ngIf=\"i > 0\">\n <span class=\"secondary-text\" \n [innerHTML]=\"highlightText(getValues(item, SearchItem)[key], searchKeyWord)\">\n </span>\n <span class=\"separator\" *ngIf=\"i < getKeys(getValues(item, SearchItem)).length - 1\"> | </span>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"noResult && searchKeyWord\" class=\"no-results\">\n <div class=\"no-results-content\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <path d=\"m21 21-4.35-4.35\"></path>\n </svg>\n <p>{{ 'NO_RESULTS_FOUND' | nxtCustomTranslate : 'No results found for' }} \"{{searchKeyWord}}\"</p>\n </div>\n </div>\n </div>\n</div>", styles: [".search-wrapper{position:relative;width:100%}.suggestion-wrapper{position:absolute;top:100%;left:0;right:0;background:#fff;border:1px solid #e0e0e0;border-top:none;border-radius:0 0 4px 4px;box-shadow:0 2px 8px #0000001a;z-index:1000;max-height:300px;overflow:hidden}.nxt-suggestions-container{max-height:300px;overflow-y:auto;min-width:100%}.suggestion-item{cursor:pointer;border-bottom:1px solid #f0f0f0;transition:background-color .2s ease;outline:none}.suggestion-item:hover,.suggestion-item:focus{background-color:#f5f5f5}.suggestion-item:last-child{border-bottom:none}.item-content{padding:5px}.item-details{display:flex;align-items:flex-start;gap:12px;text-align:left}.thumbnail-wrapper{flex-shrink:0}.thumbnail-wrapper img{width:40px;height:40px;border-radius:50%;object-fit:cover;border:1px solid #e0e0e0}.item-text{flex:1;min-width:0}.item-name{font-size:14px;font-weight:500;color:#333;line-height:1.4;margin-bottom:2px;word-wrap:break-word;overflow-wrap:break-word}.item-secondary{font-size:12px;color:#666;line-height:1.3;display:flex}.secondary-text{display:inline}.separator{color:#999;margin:0 3px}.no-results{padding:20px;text-align:center;color:#666}.no-results-content{display:flex;align-items:center;justify-content:center;gap:8px;flex-direction:column}.no-results-content svg{color:#d1d5db;margin-bottom:8px}.no-results-content p{color:#6b7280;margin:0;font-size:14px;font-weight:500}:host ::ng-deep .highlight{font-weight:700;display:inline}.nxt-suggestions-container::-webkit-scrollbar{width:6px}.nxt-suggestions-container::-webkit-scrollbar-track{background:#f1f1f1}.nxt-suggestions-container::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.nxt-suggestions-container::-webkit-scrollbar-thumb:hover{background:#a8a8a8}@media (max-width: 768px){.suggestion-wrapper,.nxt-suggestions-container{max-height:250px}.item-content{padding:10px 12px}.item-details{gap:8px}.thumbnail-wrapper img{width:32px;height:32px}.item-name{font-size:13px}.item-secondary{font-size:11px}}\n"] }]
444
- }], ctorParameters: () => [{ type: i1.StorageService }, { type: i2.ChangeService }, { type: i3.DataService }, { type: i4.CountryService }, { type: i0.ElementRef }], propDecorators: { placeHolderText: [{
445
- type: Input
446
- }], question: [{
447
- type: Input
448
- }], apiMeta: [{
449
- type: Input
450
- }], id: [{
451
- type: Input
452
- }], readOnly: [{
453
- type: Input
454
- }], mode: [{
455
- type: Input
456
- }], from: [{
457
- type: Input
458
- }], searchValueChange: [{
459
- type: Output
460
- }], searchWrapper: [{
461
- type: ViewChild,
462
- args: ['searchWrapper', { static: true }]
463
- }], onDocumentClick: [{
464
- type: HostListener,
465
- args: ['document:click', ['$event']]
466
- }], onEscapeKey: [{
467
- type: HostListener,
468
- args: ['document:keydown.escape', ['$event']]
469
- }] } });
470
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWJveC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvY29tcG9uZW50cy9zZWFyY2gtYm94L3NlYXJjaC1ib3guY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvc2VhcmNoLWJveC9zZWFyY2gtYm94LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWdDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBNkIsTUFBTSxFQUFtQyxZQUFZLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDak0sT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQzVELE9BQU8sRUFBRSxPQUFPLEVBQWdCLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFLNUYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7Ozs7Ozs7QUFjMUUsTUFBTSxPQUFPLFlBQVk7SUFvQ0g7SUFBdUM7SUFBcUM7SUFBa0M7SUFBd0M7SUFuQ2pLLGVBQWUsR0FBVyxFQUFFLENBQUM7SUFDN0IsUUFBUSxDQUFNO0lBQ2QsT0FBTyxDQUFNO0lBQ2IsRUFBRSxHQUFXLEVBQUUsQ0FBQztJQUNoQixRQUFRLEdBQUcsS0FBSyxDQUFDO0lBQ2pCLElBQUksR0FBOEIsTUFBTSxDQUFDO0lBQ3pDLElBQUksQ0FBTTtJQUVULGlCQUFpQixHQUFz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d0JBQ1osV0FBVzt3QkFDWCxRQUFRO3dCQUNSLHNCQUFzQjtxQkFDdkI7K0xBS1EsZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUVJLGlCQUFpQjtzQkFBMUIsTUFBTTtnQkFDdUMsYUFBYTtzQkFBMUQsU0FBUzt1QkFBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQWlHNUMsZUFBZTtzQkFEZCxZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVMxQyxXQUFXO3NCQURWLFlBQVk7dUJBQUMseUJBQXlCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgVmlld0NoaWxkLCBFbGVtZW50UmVmLCBTaW1wbGVDaGFuZ2VzLCBzaWduYWwsIFdyaXRhYmxlU2lnbmFsLCBUcmFja0J5RnVuY3Rpb24sIEhvc3RMaXN0ZW5lcn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IENoYW5nZVdyYXBwZXIgfSBmcm9tIFwiLi4vLi4vbW9kZWwvY2hhbmdlV3JhcHBlclwiO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcbmltcG9ydCB7IE54dElucHV0IH0gZnJvbSBcIi4uL254dC1pbnB1dC9ueHQtaW5wdXQuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQsIHRha2VVbnRpbCB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBTdG9yYWdlU2VydmljZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9zdG9yYWdlL3N0b3JhZ2Uuc2VydmljZVwiO1xuaW1wb3J0IHsgQ2hhbmdlU2VydmljZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9jaGFuZ2UvY2hhbmdlLnNlcnZpY2VcIjtcbmltcG9ydCB7IERhdGFTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL2RhdGEvZGF0YS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBDb3VudHJ5U2VydmljZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9jb3VudHJ5L2NvdW50cnkuc2VydmljZVwiO1xuaW1wb3J0IHsgTnh0Q3VzdG9tVHJhbnNsYXRlUGlwZSB9IGZyb20gXCIuLi8uLi9waXBlL2N1c3RvbS10cmFuc2xhdGUucGlwZVwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdueHQtc2VhcmNoLWJveCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgTnh0SW5wdXQsXG4gICAgTnh0Q3VzdG9tVHJhbnNsYXRlUGlwZVxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc2VhcmNoLWJveC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NlYXJjaC1ib3guY29tcG9uZW50LmNzcyddXG59KVxuZXhwb3J0IGNsYXNzIE54dFNlYXJjaEJveCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBwbGFjZUhvbGRlclRleHQ6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBxdWVzdGlvbjogYW55O1xuICBASW5wdXQoKSBhcGlNZXRhOiBhbnk7XG4gIEBJbnB1dCgpIGlkOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgcmVhZE9ubHkgPSBmYWxzZTtcbiAgQElucHV0KCkgbW9kZTogJ3ZpZXcnIHwgJ2VkaXQnIHwgJ3ByaW50JyA9ICdlZGl0JztcbiAgQElucHV0KCkgZnJvbTogYW55O1xuICBcbiAgQE91dHB1dCgpIHNlYXJjaFZhbHVlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAVmlld0NoaWxkKCdzZWFyY2hXcmFwcGVyJywgeyBzdGF0aWM6IHRydWUgfSkgc2VhcmNoV3JhcHBlciE6IEVsZW1lbnRSZWY7XG5cbiAgU2VhcmNoSXRlbTogYW55O1xuICBwdWJsaWMgZmluYWxSZXN1bHRzOiBXcml0YWJsZVNpZ25hbDxhbnlbXT4gPSBzaWduYWwoW10pO1xuICBwdWJsaWMgc2VhcmNoS2V5V29yZDogc3RyaW5nID0gJyc7XG4gIHB1YmxpYyBuZXdSZXN1bHQ6IGFueTtcbiAgcHVibGljIHNob3dSZXN1bHQgPSBmYWxzZTtcbiAgcHVibGljIG5vUmVzdWx0ID0gZmFsc2U7XG4gIHB1YmxpYyBzaG93U3VnZ2VzdGlvbiA9IGZhbHNlO1xuICBwdWJsaWMgaXNMb2FkaW5nID0gZmFsc2U7XG4gIHB1YmxpYyB2aWV3RmlsdGVyTmFtZTogc3RyaW5nID0gJyc7XG4gIHB1YmxpYyBpc1NpbmdsZUZpZWxkQ2hhbmdlID0gZmFsc2U7XG4gIHB1YmxpYyB2YWx1ZU9iajogYW55O1xuICBwdWJsaWMgaW5wdXRGb2N1c2VkID0gZmFsc2U7XG4gIHB1YmxpYyBsYXN0U2VhcmNoTGVuZ3RoID0gMDtcbiAgcHVibGljIGZpbHRlck5hbWUgPScnXG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgc2VhcmNoU3ViamVjdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcbiAgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgLy8gVHJhY2tCeSBmdW5jdGlvbiBmb3IgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uXG4gIHRyYWNrQnlGbjogVHJhY2tCeUZ1bmN0aW9uPGFueT4gPSAoaW5kZXg6IG51bWJlciwgaXRlbTogYW55KSA9PiB7XG4gICAgcmV0dXJuIGl0ZW0uaWQgfHwgaXRlbS5uYW1lIHx8IGluZGV4O1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RvcmFnZVNlcnZpY2U6IFN0b3JhZ2VTZXJ2aWNlLHByaXZhdGUgY2hhbmdlU2VydmljZTogQ2hhbmdlU2VydmljZSxwcml2YXRlIGRhdGFTZXJ2aWNlOiBEYXRhU2VydmljZSwgcHJpdmF0ZSBjb3VudHJ5U2VydmljZTogQ291bnRyeVNlcnZpY2UsIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZikge1xuICAgIGlmKHRoaXMucXVlc3Rpb24/LmlucHV0ICYmIHR5cGVvZiB0aGlzLnF1ZXN0aW9uPy5pbnB1dCA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkodGhpcy5xdWVzdGlvbj8uaW5wdXQpKXtcbiAgICAgIHRoaXMuY2xpY2tJdGVtKHRoaXMucXVlc3Rpb24/LmlucHV0KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZpbHRlck5hbWUgPSB0aGlzLnF1ZXN0aW9uPy5pbnB1dFxuICAgIH0gICAgXG4gICAgLy8gU2V0dXAgZGVib3VuY2VkIHNlYXJjaFxuICAgIHRoaXMuc2VhcmNoU3ViamVjdFxuICAgICAgLnBpcGUoXG4gICAgICAgIGRlYm91bmNlVGltZSgzMDApLFxuICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoa2V5d29yZCA9PiB7XG4gICAgICAgIGlmKHRoaXMubGFzdFNlYXJjaExlbmd0aCA+IDIpIHRoaXMucGVyZm9ybVNlYXJjaChrZXl3b3JkKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYodGhpcy5xdWVzdGlvbj8uaW5wdXQgJiYgdHlwZW9mIHRoaXMucXVlc3Rpb24/LmlucHV0ID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheSh0aGlzLnF1ZXN0aW9uPy5pbnB1dCkpe1xuICAgICAgdGhpcy5jbGlja0l0ZW0odGhpcy5xdWVzdGlvbj8uaW5wdXQpXG4gICAgfSBlbHNlIGlmKEFycmF5LmlzQXJyYXkodGhpcy5xdWVzdGlvbj8uaW5wdXQpKXtcbiAgICAgIHRoaXMuZmlsdGVyTmFtZSA9ICcnXG4gICAgICB0aGlzLnZpZXdGaWx0ZXJOYW1lID0gJydcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5maWx0ZXJOYW1lID0gdGhpcy5xdWVzdGlvbj8uaW5wdXRcbiAgICAgIHRoaXMudmlld0ZpbHRlck5hbWUgPSB0aGlzLnF1ZXN0aW9uPy5pbnB1dFxuICAgIH1cbiAgICB0aGlzLnBhcnNlQXBpTWV0YSgpO1xuICAgIGlmKHRoaXMucXVlc3Rpb24/LnN1YlRleHQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICBsZXQgZGVwZW5kZW5jeU9iajogYW55ID0gdGhpcy5xdWVzdGlvbj8uc3ViVGV4dDtcbiAgICAgIC8vIFN1YnNjcmliZSBmb3IgdGhlIGNoYW5nZXNcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5jaGFuZ2VTZXJ2aWNlLmNoYW5nZUFubm91bmNlZCQuc3Vic2NyaWJlKFxuICAgICAgICAoY2hhbmdlVmFsdWUpID0+IHtcbiAgICAgICAgICBpZihjaGFuZ2VWYWx1ZSAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmKGNoYW5nZVZhbHVlLmZyb21RdWVzdGlvbklkICYmIGNoYW5nZVZhbHVlLnZhbHVlT2JqICE9PSB1bmRlZmluZWQgJiYgKCBBcnJheS5pc0FycmF5KGRlcGVuZGVuY3lPYmouc291cmNlUXVlc3Rpb25JZCk/IGRlcGVuZGVuY3lPYmouc291cmNlUXVlc3Rpb25JZC5pbmNsdWRlcyhjaGFuZ2VWYWx1ZS5mcm9tUXVlc3Rpb25JZCkgOiBjaGFuZ2VWYWx1ZS5mcm9tUXVlc3Rpb25JZCA9PT0gZGVwZW5kZW5jeU9iai5zb3VyY2VRdWVzdGlvbklkKSkge1xuICAgICAgICAgICAgICBpZihBcnJheS5pc0FycmF5KGRlcGVuZGVuY3lPYmoucXVlcnlWYWx1ZSk/IGRlcGVuZGVuY3lPYmoucXVlcnlWYWx1ZS5pbmNsdWRlcyhjaGFuZ2VWYWx1ZS5yZWZlcmVuY2VGaWVsZCkgOiBjaGFuZ2VWYWx1ZS5yZWZlcmVuY2VGaWVsZCA9PT0gZGVwZW5kZW5jeU9iai5xdWVyeVZhbHVlKXtcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2VTZXJ2aWNlLnF1ZXJ5VmFsdWVTdG9yZSh0aGlzLnF1ZXN0aW9uLmlkLGNoYW5nZVZhbHVlLnJlZmVyZW5jZUZpZWxkLGNoYW5nZVZhbHVlLnZhbHVlT2JqKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNoYW5nZVNlcnZpY2UuY29uZmlybUNoYW5nZShjaGFuZ2VWYWx1ZS5mcm9tUXVlc3Rpb25JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZihjaGFuZ2VzWydxdWVzdGlvbiddKXtcbiAgICAgIC8vIGlmKHRoaXMucXVlc3Rpb24/LmlucHV0ICYmIHR5cGVvZiB0aGlzLnF1ZXN0aW9uPy5pbnB1dCA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkodGhpcy5xdWVzdGlvbj8uaW5wdXQpKXtcbiAgICAgIC8vICAgdGhpcy5jbGlja0l0ZW0odGhpcy5xdWVzdGlvbj8uaW5wdXQpXG4gICAgICAvLyB9IGVsc2Uge1xuICAgICAgLy8gICB0aGlzLmZpbHRlck5hbWUgPSB0aGlzLnF1ZXN0aW9uPy5pbnB1dFxuICAgICAgLy8gfVxuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snbW9kZSddKSB7XG4gICAgICB0aGlzLm1vZGUgPSBjaGFuZ2VzWydtb2RlJ10uY3VycmVudFZhbHVlO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snYXBpTWV0YSddICYmIHRoaXMuYXBpTWV0YSkge1xuICAgICAgdGhpcy5wYXJzZUFwaU1ldGEoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5yZXNldENvbXBvbmVudFN0YXRlKCk7XG4gIH1cblxuICAvLyBIYW5kbGUgY2xpY2tzIG91dHNpZGUgdGhlIHNlYXJjaCBjb21wb25lbnRcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkRvY3VtZW50Q2xpY2soZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQgYXMgTm9kZSkpIHtcbiAgICAgIHRoaXMuaGlkZVN1Z2dlc3Rpb25zKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gSGFuZGxlIGVzY2FwZSBrZXkgdG8gY2xvc2Ugc3VnZ2VzdGlvbnNcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bi5lc2NhcGUnLCBbJyRldmVudCddKVxuICBvbkVzY2FwZUtleShldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuaGlkZVN1Z2dlc3Rpb25zKCk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQXBpTWV0YSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hcGlNZXRhKSB7XG4gICAgICB0aGlzLmFwaU1ldGEgPSB0eXBlb2YgdGhpcy5hcGlNZXRhID09PSAnb2JqZWN0JyA/IHRoaXMuYXBpTWV0YSA6IEpTT04ucGFyc2UodGhpcy5hcGlNZXRhIHx8ICd7fScpO1xuICAgICAgdGhpcy5TZWFyY2hJdGVtID0gdGhpcy5hcGlNZXRhLmZpZWxkIHx8IFtdO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRDb21wb25lbnRTdGF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmZpbmFsUmVzdWx0cy5zZXQoW10pO1xuICAgIHRoaXMuc2VhcmNoS2V5V29yZCA9ICcnO1xuICAgIHRoaXMuc2hvd1N1Z2dlc3Rpb24gPSBmYWxzZTtcbiAgICB0aGlzLm5vUmVzdWx0ID0gZmFsc2U7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmlucHV0Rm9jdXNlZCA9IGZhbHNlO1xuICAgIHRoaXMubGFzdFNlYXJjaExlbmd0aCA9IDA7XG4gIH1cblxuICBwcml2YXRlIGhpZGVTdWdnZXN0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLnNob3dTdWdnZXN0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5pbnB1dEZvY3VzZWQgPSBmYWxzZTtcbiAgfVxuXG4gIG9uSW5wdXRGb2N1cygpOiB2b2lkIHtcbiAgICB0aGlzLmlucHV0Rm9jdXNlZCA9IHRydWU7XG4gICAgLy8gVHJpZ2dlciBhIHNlYXJjaCB3aXRoIGFuIGVtcHR5IGtleXdvcmQgdG8gc2hvdyBhbGwgZGF0YVxuICAgIGlmICghdGhpcy5zZWFyY2hLZXlXb3JkKSB7XG4gICAgICAvLyB0aGlzLnBlcmZvcm1TZWFyY2goJycpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5maW5hbFJlc3VsdHMoKS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNob3dTdWdnZXN0aW9uID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBvbklucHV0Qmx1cigpOiB2b2lkIHtcbiAgICAvLyBEb24ndCBpbW1lZGlhdGVseSBoaWRlIHN1Z2dlc3Rpb25zIHRvIGFsbG93IGZvciBjbGlja2luZ1xuICAgIC8vIFRoZSBkb2N1bWVudCBjbGljayBoYW5kbGVyIHdpbGwgaGFuZGxlIGhpZGluZ1xuICB9XG5cbiAgY2xlYXJMaXN0KCk6IHZvaWQge1xuICAgIC8vIFJlbW92ZSB0aGUgc2V0VGltZW91dCBkZWxheSB0aGF0IHdhcyBjYXVzaW5nIGlzc3Vlc1xuICAgIHRoaXMuaGlkZVN1Z2dlc3Rpb25zKCk7XG4gIH1cblxuICBnZXRTb3VyY2VEYXRhTG9jYWwoZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGlmICghZXZlbnQ/LnZhbHVlPy52YWx1ZU9iaikge1xuICAgICAgdGhpcy5yZXNldENvbXBvbmVudFN0YXRlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2VhcmNoVmFsdWUgPSAgZXZlbnQudmFsdWU/LnZhbHVlT2JqPy5pbmNsdWRlcygnfCcpID8gZXZlbnQudmFsdWU/LnZhbHVlT2JqPy5zcGxpdCgnfCcpWzBdLnRyaW0oKSA6IGV2ZW50LnZhbHVlPy52YWx1ZU9iaj8udHJpbSgpO1xuICAgIGNvbnN0IGN1cnJlbnRMZW5ndGggPSBzZWFyY2hWYWx1ZS5sZW5ndGg7XG4gICAgXG4gICAgLy8gQWx3YXlzIHVwZGF0ZSB0aGUgc2VhcmNoIGtleXdvcmRcbiAgICB0aGlzLnNlYXJjaEtleVdvcmQgPSBzZWFyY2hWYWx1ZTtcbiAgICBcbiAgICAvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgdXNlciB0eXBlcyAzKyBjaGFyYWN0ZXJzXG4gICAgaWYgKGN1cnJlbnRMZW5ndGggPiAyICYmICF0aGlzLmlzU2luZ2xlRmllbGRDaGFuZ2UpIHtcbiAgICAgIHRoaXMuc2hvd1N1Z2dlc3Rpb24gPSAhZXZlbnQucXVlc3Rpb24/LnNpbmdsZUZpZWxkQ2hhbmdlO1xuICAgICAgdGhpcy5zaG93UmVzdWx0ID0gZmFsc2U7XG4gICAgICB0aGlzLm5vUmVzdWx0ID0gZmFsc2U7XG4gICAgICAvLyBBbHdheXMgcGVyZm9ybSBzZWFyY2ggd2hlbiB3ZSBoYXZlIDMrIGNoYXJhY3RlcnNcbiAgICAgIHRoaXMubGFzdFNlYXJjaExlbmd0aCA9IGN1cnJlbnRMZW5ndGg7XG4gICAgICB0aGlzLnNlYXJjaFN1YmplY3QubmV4dChzZWFyY2hWYWx1ZSk7XG4gICAgICBcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRMZW5ndGggPD0gMikge1xuICAgICAgLy8gV2hlbiBsZW5ndGggaXMgMiBvciBsZXNzLCBoaWRlIHN1Z2dlc3Rpb25zIGJ1dCBrZWVwIHRoZSBzZWFyY2gga2V5d29yZFxuICAgICAgdGhpcy5pc1NpbmdsZUZpZWxkQ2hhbmdlID0gZmFsc2U7XG4gICAgICB0aGlzLnNob3dTdWdnZXN0aW9uID0gZmFsc2U7XG4gICAgICB0aGlzLm5vUmVzdWx0ID0gZmFsc2U7XG4gICAgICB0aGlzLmxhc3RTZWFyY2hMZW5ndGggPSBjdXJyZW50TGVuZ3RoO1xuICAgICAgdGhpcy5zZWFyY2hTdWJqZWN0Lm5leHQoc2VhcmNoVmFsdWUpO1xuICAgICAgdGhpcy5maW5hbFJlc3VsdHMuc2V0KFtdKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBlcmZvcm1TZWFyY2goa2V5d29yZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmFwaU1ldGEpIHJldHVybjtcblxuICAgIHRoaXMucGFyc2VBcGlNZXRhKCk7XG4gICAgXG4gICAgaWYgKCF0aGlzLmFwaU1ldGEuaXNTdGF0aWNEYXRhKSB7XG4gICAgICB0aGlzLnNlYXJjaEZyb21BcGkoa2V5d29yZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VhcmNoRnJvbVN0YXRpY0RhdGEoa2V5d29yZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZWFyY2hGcm9tQXBpKGtleXdvcmQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmZpbmFsUmVzdWx0cy5zZXQoW10pO1xuICAgIGlmKCF0aGlzLmFwaU1ldGEuZW5kcG9pbnQgJiYgQXJyYXkuaXNBcnJheSh0aGlzLnF1ZXN0aW9uPy5pbnB1dCkgKXtcbiAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLnByb2Nlc3NTZWFyY2hSZXN1bHRzKHRoaXMucXVlc3Rpb24/LmlucHV0LCBrZXl3b3JkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGZpbmFsR2V0Q2FsbCA9IHRoaXMuYXBpTWV0YS5lbmRwb2ludDtcbiAgICAgIC8vIFNLUzE4SlVMMjUgcXVlcnkgcGFyYW1zIGNyZWF0aW9uXG4gICAgICBpZih0aGlzLmFwaU1ldGE/LnF1ZXJ5UGFyYW1ldGVyKXtcbiAgICAgICAgY29uc3QgaXNGaWVsZEFycmF5ID0gQXJyYXkuaXNBcnJheSh0aGlzLmFwaU1ldGE/LnF1ZXJ5UGFyYW1ldGVyKTtcbiAgICAgICAgY29uc3QgZmllbGRzID0gaXNGaWVsZEFycmF5ID8gdGhpcy5hcGlNZXRhLnF1ZXJ5UGFyYW1ldGVyIDogW3RoaXMuYXBpTWV0YS5xdWVyeVBhcmFtZXRlcl07IC8vIGFsd2F5cyBhbiBhcnJheSBub3dcbiAgICAgICAgLy8gQnVpbGQgcXVlcnkgcGFyYW1zIHN0cmluZ1xuICAgICAgICBjb25zdCBxdWVyeVBhcmFtcyA9IGZpZWxkc1xuICAgICAgICAgIC5tYXAoZmllbGQgPT4gYCR7ZmllbGR9PSR7dGhpcy5zZWFyY2hLZXlXb3JkfWApXG4gICAgICAgICAgLmpvaW4oJyYnKTtcbiAgICAgICAgLy8gQ2hlY2sgaWYgZW5kcG9pbnQgYWxyZWFkeSBoYXMgcXVlcnkgcGFyYW1zXG4gICAgICAgIGlmKHF1ZXJ5UGFyYW1zICYmIHF1ZXJ5UGFyYW1zICE9PSAnJyl7XG4gICAgICAgICAgaWYgKHRoaXMuYXBpTWV0YS5lbmRwb2ludC5pbmNsdWRlcygnPycpKSB7XG4gICAgICAgICAgICBmaW5hbEdldENhbGwgKz0gYCYke3F1ZXJ5UGFyYW1zfWA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZpbmFsR2V0Q2FsbCArPSBgPyR7cXVlcnlQYXJhbXN9YDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFwaU1ldGE/LnF1ZXJ5RmllbGQgJiYgdGhpcy5hcGlNZXRhPy5xdWVyeVZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5RmllbGRzID0gQXJyYXkuaXNBcnJheSh0aGlzLmFwaU1ldGEucXVlcnlGaWVsZClcbiAgICAgICAgICA/IHRoaXMuYXBpTWV0YS5xdWVyeUZpZWxkXG4gICAgICAgICAgOiBbdGhpcy5hcGlNZXRhLnF1ZXJ5RmllbGRdO1xuICAgICAgXG4gICAgICAgIGNvbnN0IHF1ZXJ5VmFsdWVzID0gQXJyYXkuaXNBcnJheSh0aGlzLmFwaU1ldGEucXVlcnlWYWx1ZSlcbiAgICAgICAgICA/IHRoaXMuYXBpTWV0YS5xdWVyeVZhbHVlXG4gICAgICAgICAgOiBbdGhpcy5hcGlNZXRhLnF1ZXJ5VmFsdWVdO1xuICAgICAgXG4gICAgICAgIGNvbnN0IHN0b3JlZCA9IHRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0UXVlcnlWYWx1ZSh0aGlzLnF1ZXN0aW9uLmlkKTsgLy8gc2luZ2xlIG9iamVjdFxuICAgICAgXG4gICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zQXJyYXk6IHN0cmluZ1tdID0gW107XG4gICAgICBcbiAgICAgICAgcXVlcnlGaWVsZHMuZm9yRWFjaCgoZmllbGQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgY29uc3QgdmFsdWVLZXkgPSBxdWVyeVZhbHVlc1tpbmRleF0gPz8gcXVlcnlWYWx1ZXNbMF07XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBzdG9yZWRbdmFsdWVLZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBxdWVyeVBhcmFtc0FycmF5LnB1c2goYCR7ZmllbGR9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgXG4gICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gcXVlcnlQYXJhbXNBcnJheS5qb2luKCcmJyk7XG4gICAgICBcbiAgICAgICAgaWYgKHF1ZXJ5UGFyYW1zKSB7XG4gICAgICAgICAgZmluYWxHZXRDYWxsICs9IHRoaXMuYXBpTWV0YS5lbmRwb2ludC5pbmNsdWRlcygnPycpID8gYCYke3F1ZXJ5UGFyYW1zfWAgOiBgPyR7cXVlcnlQYXJhbXN9YDtcbiAgICAgICAgfVxuICAgICAgfSAgICAgIFxuICAgICAgdGhpcy5kYXRhU2VydmljZS5hcGlSZXNwb25zZShmaW5hbEdldENhbGwpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKGFwaVJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnByb2Nlc3NTZWFyY2hSZXN1bHRzKGFwaVJlc3BvbnNlLCBrZXl3b3JkKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5ub1Jlc3VsdCA9IHRydWU7XG4gICAgICAgICAgdGhpcy5maW5hbFJlc3VsdHMuc2V0KFtdKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZWFyY2hGcm9tU3RhdGljRGF0YShrZXl3b3JkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuY291bnRyeVNlcnZpY2UuZ2V0Q291bnRyeURhdGEodGhpcy5hcGlNZXRhLmZpZWxkKTtcbiAgICB0aGlzLnByb2Nlc3NTZWFyY2hSZXN1bHRzKHJlc3BvbnNlLCBrZXl3b3JkKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc1NlYXJjaFJlc3VsdHMoYXBpUmVzcG9uc2U6IGFueSwga2V5d29yZDogc3RyaW5nKTogdm9pZCB7XG4gICAgbGV0IHJlc3BvbnNlO1xuICBcbiAgICBpZiAodGhpcy5hcGlNZXRhLnZhcmlhYmxlKSB7XG4gICAgICByZXNwb25zZSA9IHRoaXMuZGF0YVNlcnZpY2UuZ2V0VmFsdWUoYXBpUmVzcG9uc2UsIHRoaXMuYXBpTWV0YS52YXJpYWJsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3BvbnNlID0gYXBpUmVzcG9uc2U7XG4gICAgfVxuICBcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVzcG9uc2UpKSB7XG4gICAgICB0aGlzLm5vUmVzdWx0ID0gdHJ1ZTtcbiAgICAgIHRoaXMuZmluYWxSZXN1bHRzLnNldChbXSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICBcbiAgICBpZiAoIWtleXdvcmQpIHtcbiAgICAgIC8vIElmIG5vIGtleXdvcmQsIHNob3cgYWxsIHJlc3VsdHNcbiAgICAgIHRoaXMuZmluYWxSZXN1bHRzLnNldChyZXNwb25zZSk7XG4gICAgICB0aGlzLm5vUmVzdWx0ID0gcmVzcG9uc2UubGVuZ3RoID09PSAwO1xuICAgICAgdGhpcy5zaG93U3VnZ2VzdGlvbiA9IHRydWU7IC8vIEVuc3VyZSBzdWdnZXN0aW9ucyBhcmUgdmlzaWJsZVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGaWx0ZXIgcmVzdWx0cyBiYXNlZCBvbiB0aGUga2V5d29yZFxuICAgICAgY29uc3Qgc2VhcmNoVGVybXMgPSBrZXl3b3JkLnRvTG93ZXJDYXNlKCkuc3BsaXQoXCIgXCIpLmZpbHRlcih0ZXJtID0+IHRlcm0ubGVuZ3RoID4gMCk7XG4gICAgICBjb25zdCByZXN1bHRzID0gcmVzcG9uc2UuZmlsdGVyKG9iaiA9PiB7XG4gICAgICAgIGNvbnN0IGNvbWJpbmVkVmFsdWVzID0gdGhpcy5nZXRDb21iaW5lZFZhbHVlc0Zyb21Db2x1bW5zKG9iaiwgdGhpcy5hcGlNZXRhLmZpZWxkKTtcbiAgICAgICAgcmV0dXJuIHNlYXJjaFRlcm1zLmV2ZXJ5KHRlcm0gPT4gY29tYmluZWRWYWx1ZXMuaW5jbHVkZXModGVybSkpO1xuICAgICAgfSk7XG4gIFxuICAgICAgdGhpcy5ub1Jlc3VsdCA9IHJlc3VsdHMubGVuZ3RoID09PSAwO1xuICAgICAgdGhpcy5maW5hbFJlc3VsdHMuc2V0KHJlc3VsdHMpO1xuICAgICAgdGhpcy5zaG93U3VnZ2VzdGlvbiA9IHRydWU7IC8vIFNob3cgc3VnZ2VzdGlvbnMgb25seSBpZiB0aGVyZSBhcmUgcmVzdWx0c1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0TmVzdGVkVmFsdWUob2JqOiBhbnksIHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFvYmogfHwgIXBhdGgpIHJldHVybiAnJztcbiAgICBcbiAgICBjb25zdCBwcm9jZXNzZWRQYXRoID0gcGF0aC5yZXBsYWNlKC9cXFsoXFxkKylcXF0vZywgJy4kMScpO1xuICAgIGNvbnN0IHBhcnRzID0gcHJvY2Vzc2VkUGF0aC5zcGxpdCgnLicpO1xuICAgIGxldCBjdXJyZW50ID0gb2JqO1xuXG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICBpZiAoIWN1cnJlbnQgfHwgdHlwZW9mIGN1cnJlbnQgIT09ICdvYmplY3QnKSByZXR1cm4gJyc7XG4gICAgICBjdXJyZW50ID0gY3VycmVudFtwYXJ0XTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50ICE9PSB1bmRlZmluZWQgXG4gICAgICA/IFN0cmluZyhjdXJyZW50KS50b0xvd2VyQ2FzZSgpLnRyaW0oKSBcbiAgICAgIDogJyc7XG4gIH1cblxuICBwcml2YXRlIGdldENvbWJpbmVkVmFsdWVzRnJvbUNvbHVtbnMob2JqOiBhbnksIGNvbHVtbnM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICBpZiAoIW9iaiB8fCAhY29sdW1ucykgcmV0dXJuICcnO1xuICAgIFxuICAgIGNvbnN0IGNvbHVtbkFycmF5ID0gQXJyYXkuaXNBcnJheShjb2x1bW5zKSA/IGNvbHVtbnMgOiBbY29sdW1uc107XG4gICAgY29uc3QgdmFsdWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1uQXJyYXkpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXROZXN0ZWRWYWx1ZShvYmosIGNvbHVtbik7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXMuam9pbignICcpO1xuICB9XG5cbiAgcHVibGljIGdldFZhbHVlcyhlbGVtZW50OiBhbnksIGNvbHVtbnM6IGFueSk6IGFueSB7XG4gICAgY29uc3QgcmVzdWx0OiBhbnkgPSB7fTtcbiAgICBpZiAoIWVsZW1lbnQgfHwgIWNvbHVtbnMpIHJldHVybiByZXN1bHQ7XG5cbiAgICBjb25zdCBjb2x1bW5BcnJheSA9IEFycmF5LmlzQXJyYXkoY29sdW1ucykgPyBjb2x1bW5zIDogW2NvbHVtbnNdO1xuICAgIFxuICAgIGNvbHVtbkFycmF5LmZvckVhY2goKGNvbHVtbikgPT4ge1xuICAgICAgaWYgKCFjb2x1bW4pIHJldHVybjtcbiAgICAgIFxuICAgICAgbGV0IHRlbXBFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IGNvbHVtbi5zcGxpdCgnLicpO1xuICAgICAgXG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgICBpZiAoIXRlbXBFbGVtZW50KSBicmVhaztcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHNwbGl0RmllbGRzID0gZmllbGQuc3BsaXQoJ1snKTtcbiAgICAgICAgaWYgKHNwbGl0RmllbGRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRlbXBFbGVtZW50ID0gdGVtcEVsZW1lbnRbZmllbGRdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGluZGV4TWF0Y2ggPSBzcGxpdEZpZWxkc1sxXT8ubWF0Y2goLyhcXGQrKVxcXS8pO1xuICAgICAgICAgIGlmIChpbmRleE1hdGNoKSB7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpbmRleE1hdGNoWzFdKTtcbiAgICAgICAgICAgIHRlbXBFbGVtZW50ID0gdGVtcEVsZW1lbnRbc3BsaXRGaWVsZHNbMF1dPy5baW5kZXhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICByZXN1bHRbY29sdW1uXSA9IHRlbXBFbGVtZW50IHx8ICcnO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGdldEtleXMob2JqOiBhbnkpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIG9iaiA/IE9iamVjdC5rZXlzKG9iaikgOiBbXTtcbiAgfVxuXG4gIHB1YmxpYyBjbGlja0l0ZW0oZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5hcGlNZXRhKSByZXR1cm47XG4gIFxuICAgIHRoaXMucGFyc2VBcGlNZXRhKCk7XG4gICAgXG4gICAgY29uc3QgdmFsdWVzID0gdGhpcy5nZXRWYWx1ZXMoZXZlbnQsIHRoaXMuU2VhcmNoSXRlbSk7XG4gICAgY29uc3QgZGlzcGxheVZhbHVlID0gT2JqZWN0LnZhbHVlcyh2YWx1ZXMpXG4gICAgICAuZmlsdGVyKHZhbCA9PiB2YWwpXG4gICAgICAuam9pbignIHwgJyk7XG4gICAgXG4gICAgaWYgKHRoaXMubW9kZSAhPT0gJ2VkaXQnKSB7XG4gICAgICB0aGlzLnZpZXdGaWx0ZXJOYW1lID0gZGlzcGxheVZhbHVlO1xuICAgIH1cbiAgICB0aGlzLmZpbHRlck5hbWUgPSBkaXNwbGF5VmFsdWU7XG4gICAgdGhpcy5uZ09uQ2hhbmdlcyh7fSlcbiAgXG4gICAgY29uc3QgZGVmYXVsdEZpZWxkID0gdGhpcy5hcGlNZXRhLmRlZmF1bHRGaWVsZCB8fCBcbiAgICAgIChBcnJheS5pc0FycmF5KHRoaXMuYXBpTWV0YT8uZmllbGQpID8gdGhpcy5hcGlNZXRhPy5maWVsZD8uWzBdIDogdGhpcy5hcGlNZXRhLmZpZWxkKTtcbiAgICBcbiAgICBjb25zdCBjaGFuZ2UgPSBuZXcgQ2hhbmdlV3JhcHBlcigpO1xuICAgIGNoYW5nZVsnaXNPYmplY3QnXSA9IHRoaXMuYXBpTWV0YT8uaXNPYmplY3RcbiAgICBjaGFuZ2VbJ2Zyb21RdWVzdGlvbklkJ10gPSB0aGlzLmlkO1xuICAgIGNoYW5nZVsndmFsdWVPYmonXSA9IGV2ZW50O1xuICAgIGNoYW5nZVsnZmllbGQnXSA9IGRlZmF1bHRGaWVsZDtcbiAgICBcbiAgICB0aGlzLnZhbHVlT2JqID0gZXZlbnQ7XG4gICAgXG4gICAgdGhpcy5oaWRlU3VnZ2VzdGlvbnMoKTtcbiAgICBcbiAgICB0aGlzLnNlYXJjaFZhbHVlQ2hhbmdlLmVtaXQoe1xuICAgICAgcXVlc3Rpb246IHRoaXMucXVlc3Rpb24sXG4gICAgICB2YWx1ZTogY2hhbmdlXG4gICAgfSk7XG4gIH1cblxuICBpbnB1dFZhbHVlKGV2ZW50OiBhbnksIHF1ZXM6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyTmFtZSA9IGV2ZW50Py52YWx1ZU9iaiA/IGV2ZW50Py52YWx1ZU9iaj8udHJpbSgpIDogdGhpcy5maWx0ZXJOYW1lXG4gICAgaWYgKCFxdWVzPy5zaW5nbGVGaWVsZENoYW5nZSB8fCAhdGhpcy5hcGlNZXRhKSByZXR1cm47XG5cbiAgICB0aGlzLmlzU2luZ2xlRmllbGRDaGFuZ2UgPSB0cnVlO1xuICAgIHRoaXMucGFyc2VBcGlNZXRhKCk7XG5cbiAgICBjb25zdCBkZWZhdWx0RmllbGQgPSB0aGlzLmFwaU1ldGEuZGVmYXVsdEZpZWxkIHx8IFxuICAgICAgKEFycmF5LmlzQXJyYXkodGhpcy5hcGlNZXRhPy5maWVsZCkgPyB0aGlzLmFwaU1ldGE/LmZpZWxkPy5bMF0gOiB0aGlzLmFwaU1ldGEuZmllbGQpO1xuXG4gICAgY29uc3QgY2hhbmdlID0gbmV3IENoYW5nZVdyYXBwZXIoKTtcbiAgICBjaGFuZ2VbJ2lzT2JqZWN0J10gPSB0aGlzLmFwaU1ldGE/LmlzT2JqZWN0XG4gICAgY2hhbmdlWydmcm9tUXVlc3Rpb25JZCddID0gdGhpcy5pZDtcbiAgICBjaGFuZ2VbJ3ZhbHVlT2JqJ10gPSB0aGlzLnZhbHVlT2JqO1xuICAgIGNoYW5nZVsnZmllbGQnXSA9IGRlZmF1bHRGaWVsZDtcbiAgICBjaGFuZ2VbJ3JlZmVyZW5jZUZpZWxkJ10gPSB0aGlzLnF1ZXN0aW9uLnJlZmVyZW5jZUZpZWxkO1xuICAgIFxuICAgIHRoaXMuZmlsdGVyTmFtZSA9IHRoaXMudmlld0ZpbHRlck5hbWU7XG4gICAgXG4gICAgdGhpcy5zZWFyY2hWYWx1ZUNoYW5nZS5lbWl0KHtcbiAgICAgIHF1ZXN0aW9uOiBxdWVzLFxuICAgICAgdmFsdWU6IGNoYW5nZVxuICAgIH0pO1xuICB9XG5cbiAgaGlnaGxpZ2h0VGV4dCh0ZXh0OiBzdHJpbmcsIHNlYXJjaFRlcm06IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0ZXh0IHx8ICFzZWFyY2hUZXJtKSByZXR1cm4gdGV4dCB8fCAnJztcblxuICAgIC8vIFNhbml0aXplIHRoZSBpbnB1dCB0ZXh0XG4gICAgY29uc3Qgc2FuaXRpemVkVGV4dCA9IHRoaXMuc2FuaXRpemVIdG1sKHRleHQpO1xuICAgIGNvbnN0IHRlcm1zID0gc2VhcmNoVGVybS50b0xvd2VyQ2FzZSgpLnNwbGl0KCcgJykuZmlsdGVyKHRlcm0gPT4gdGVybS5sZW5ndGggPiAwKTtcbiAgICBcbiAgICBpZiAodGVybXMubGVuZ3RoID09PSAwKSByZXR1cm4gc2FuaXRpemVkVGV4dDtcblxuICAgIC8vIEVzY2FwZSBzcGVjaWFsIHJlZ2V4IGNoYXJhY3RlcnNcbiAgICBjb25zdCBlc2NhcGVkVGVybXMgPSB0ZXJtcy5tYXAodGVybSA9PiBcbiAgICAgIHRlcm0ucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKVxuICAgICk7XG5cbiAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoYCgke2VzY2FwZWRUZXJtcy5qb2luKCd8Jyl9KWAsICdnaScpO1xuICAgIHJldHVybiBzYW5pdGl6ZWRUZXh0LnJlcGxhY2UocmVnZXgsICc8c3BhbiBjbGFzcz1cImhpZ2hsaWdodFwiPiQxPC9zcGFuPicpO1xuICB9XG5cbiAgcHJpdmF0ZSBzYW5pdGl6ZUh0bWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGV4dFxuICAgICAgLnJlcGxhY2UoLyYvZywgJyZhbXA7JylcbiAgICAgIC5yZXBsYWNlKC88L2csICcmbHQ7JylcbiAgICAgIC5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAgIC5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7JylcbiAgICAgIC5yZXBsYWNlKC8nL2csICcmIzM5OycpO1xuICB9XG4gIHJlbW92ZVZhbHVlRW1pdCgpe1xuICAgIHRoaXMuY2xpY2tJdGVtKG51bGwpXG4gIH1cbn0iLCI8IS0tIFZEIDEySnVuMjQgLSByZWFkb25seSBjaGFuZ2UgLS0+XG48ZGl2IGNsYXNzPVwic2VhcmNoLXdyYXBwZXJcIiAjc2VhcmNoV3JhcHBlcj5cbiAgPG54dC1pbnB1dCBcbiAgICBbdHlwZV09XCInbGlzdCdcIiBcbiAgICBbbW9kZV09XCJtb2RlXCIgXG4gICAgW2Zyb21dPVwiZnJvbVwiXG4gICAgW3ZhbHVlXT1cIm1vZGUgPT09ICdlZGl0JyA/IGZpbHRlck5hbWUgOiB2aWV3RmlsdGVyTmFtZVwiXG4gICAgW2xhYmVsRm9udF09XCJxdWVzdGlvbj8uZm9udFwiIFxuICAgIFtsYWJlbF09XCJxdWVzdGlvbj8ucXVlc3Rpb25UZXh0ID8gKChxdWVzdGlvbj8uaWQrJy5xdWVzdGlvblRleHQnKSB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6IHF1ZXN0aW9uPy5xdWVzdGlvblRleHQpOiAnJ1wiIFxuICAgIFtsYWJlbENvbG9yXT1cInF1ZXN0aW9uPy5mb250Q29sb3JcIlxuICAgIFtsYWJlbFNpemVdPVwicXVlc3Rpb24/LmZvbnRTaXplXCIgXG4gICAgW2lucHV0VmFsdWVTaXplXT1cInF1ZXN0aW9uPy5mb250U2l6ZVwiIFxuICAgIFtsYWJlbFdlaWdodF09XCJxdWVzdGlvbj8uZm9udFdlaWdodFwiXG4gICAgW2lucHV0V2VpZ2h0XT1cInF1ZXN0aW9uPy5mb250V2VpZ2h0XCIgXG4gICAgW3Nob3dMYWJlbF09XCJxdWVzdGlvbj8uc3R5bGU/LnNob3dMYWJlbFwiIFxuICAgIGlucHV0Qm9yZGVyPVwibm9uZVwiIFxuICAgIHN2Z0hlaWdodD1cIjIwcHhcIlxuICAgIHN2Z1dpZHRoPVwiMjBweFwiIFxuICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZUhvbGRlclRleHRcIiBcbiAgICBbcmVxdWlyZWRdPVwicXVlc3Rpb24/LmlzT3B0aW9uYWxcIiBcbiAgICBpbnB1dEJnQ29sb3I9XCIjRkFGQUZBXCJcbiAgICBbaW5wdXRJZF09XCJxdWVzdGlvbj8udHJhY2tpbmdJZFwiIFxuICAgIFtlcnJvck1lc3NhZ2VzXT1cInsgcmVxdWlyZWQ6ICdUaGlzIGZpZWxkIGlzIHJlcXVpcmVkJyB9XCJcbiAgICBbaW5wdXRJY29uTGVmdFNyY109XCJxdWVzdGlvbj8uaWNvbkxlZnRTcmNcIiBcbiAgICAoaW5wdXRWYWx1ZSk9XCJnZXRTb3VyY2VEYXRhTG9jYWwoJGV2ZW50KTsgaW5wdXRWYWx1ZSgkZXZlbnQudmFsdWUsICRldmVudC5xdWVzdGlvbilcIiBcbiAgICAob25Gb2N1cyk9XCJvbklucHV0Rm9jdXMoKVwiXG4gICAgKG9uQmx1cik9XCJvbklucHV0Qmx1cigpXCJcbiAgICBbc2hvd1N1Z2dlc3Rpb25dPVwic2hvd1N1Z2dlc3Rpb25cIiBcbiAgICBhcmlhT3ducz1cInNlbGVjdExpc3RcIiBcbiAgICBhcmlhSGFzUG9wdXA9XCJsaXN0Ym94XCIgXG4gICAgW2lzTG9hZGluZ109XCJpc0xvYWRpbmdcIiBcbiAgICBbcXVlc3Rpb25dPVwicXVlc3Rpb25cIlxuICAgIChyZW1vdmVWYWx1ZUVtaXQpPVwicmVtb3ZlVmFsdWVFbWl0KClcIj5cbiAgPC9ueHQtaW5wdXQ+XG5cbiAgPGRpdiBpZD1cInNlbGVjdExpc3RcIiBjbGFzcz1cInN1Z2dlc3Rpb24td3JhcHBlclwiIHJvbGU9XCJsaXN0Ym94XCIgKm5nSWY9XCJzaG93U3VnZ2VzdGlvblwiPlxuICAgIDxkaXYgKm5nSWY9XCJmaW5hbFJlc3VsdHMoKS5sZW5ndGggPiAwXCIgY2xhc3M9XCJueHQtc3VnZ2VzdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBpdGVtIG9mIGZpbmFsUmVzdWx0cygpOyB0cmFja0J5OiB0cmFja0J5Rm5cIiBcbiAgICAgICAgICAgKGNsaWNrKT1cImNsaWNrSXRlbShpdGVtKVwiIFxuICAgICAgICAgICBjbGFzcz1cInN1Z2dlc3Rpb24taXRlbVwiIFxuICAgICAgICAgICByb2xlPVwib3B0aW9uXCJcbiAgICAgICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiY2xpY2tJdGVtKGl0ZW0pXCJcbiAgICAgICAgICAgKGtleWRvd24uc3BhY2UpPVwiY2xpY2tJdGVtKGl0ZW0pXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbnRlbnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1kZXRhaWxzXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXRlbS50aHVtYm5haWxcIiBjbGFzcz1cInRodW1ibmFpbC13cmFwcGVyXCI+XG4gICAgICAgICAgICAgIDxpbWcgW3NyY109XCJpdGVtLnRodW1ibmFpbFwiIFthbHRdPVwiaXRlbS5uYW1lICsgJyBhdmF0YXInXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tdGV4dFwiPlxuICAgICAgICAgICAgICA8IS0tIFByaW1hcnkgdGV4dCAoZmlyc3Qga2V5KSAtLT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldEtleXMoZ2V0VmFsdWVzKGl0ZW0sIFNlYXJjaEl0ZW0pKS5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW0tbmFtZSBwcmltYXJ5XCIgXG4gICAgICAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cImhpZ2hsaWdodFRleHQoZ2V0VmFsdWVzKGl0ZW0sIFNlYXJjaEl0ZW0pW2dldEtleXMoZ2V0VmFsdWVzKGl0ZW0sIFNlYXJjaEl0ZW0pKVswXV0sIHNlYXJjaEtleVdvcmQpXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgPCEtLSBTZWNvbmRhcnkgdGV4dCAocmVtYWluaW5nIGtleXMpIC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1zZWNvbmRhcnlcIiAqbmdJZj1cImdldEtleXMoZ2V0VmFsdWVzKGl0ZW0sIFNlYXJjaEl0ZW0pKS5sZW5ndGggPiAxXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQga2V5IG9mIGdldEtleXMoZ2V0VmFsdWVzKGl0ZW0sIFNlYXJjaEl0ZW0pKTsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImkgPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2Vjb25kYXJ5LXRleHRcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJoaWdobGlnaHRUZXh0KGdldFZhbHVlcyhpdGVtLCBTZWFyY2hJdGVtKVtrZXldLCBzZWFyY2hLZXlXb3JkKVwiPlxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2VwYXJhdG9yXCIgKm5nSWY9XCJpIDwgZ2V0S2V5cyhnZXRWYWx1ZXMoaXRlbSwgU2VhcmNoSXRlbSkpLmxlbmd0aCAtIDFcIj4gfCA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nSWY9XCJub1Jlc3VsdCAmJiBzZWFyY2hLZXlXb3JkXCIgY2xhc3M9XCJuby1yZXN1bHRzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibm8tcmVzdWx0cy1jb250ZW50XCI+XG4gICAgICAgIDxzdmcgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMVwiPlxuICAgICAgICAgIDxjaXJjbGUgY3g9XCIxMVwiIGN5PVwiMTFcIiByPVwiOFwiPjwvY2lyY2xlPlxuICAgICAgICAgIDxwYXRoIGQ9XCJtMjEgMjEtNC4zNS00LjM1XCI+PC9wYXRoPlxuICAgICAgICA8L3N2Zz5cbiAgICAgICAgPHA+e3sgJ05PX1JFU1VMVFNfRk9VTkQnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ05vIHJlc3VsdHMgZm91bmQgZm9yJyB9fSBcInt7c2VhcmNoS2V5V29yZH19XCI8L3A+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj4iXX0=