@mediusinc/mng-commons 5.3.0-rc.1 → 5.3.0-rc.3

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 (106) hide show
  1. package/core/data-list/filter-metadata.model.d.ts +20 -0
  2. package/core/helpers/number.d.ts +5 -0
  3. package/core/helpers/type-helpers.d.ts +1 -0
  4. package/core/index.d.ts +2 -0
  5. package/core/provide.d.ts +3 -2
  6. package/core/services/tokens/module-config.token.d.ts +7 -6
  7. package/esm2022/core/data-list/data-list-params-helpers.mjs +3 -1
  8. package/esm2022/core/data-list/filter-metadata.model.mjs +2 -0
  9. package/esm2022/core/helpers/date.mjs +2 -2
  10. package/esm2022/core/helpers/number.mjs +19 -0
  11. package/esm2022/core/helpers/type-helpers.mjs +1 -1
  12. package/esm2022/core/index.mjs +3 -1
  13. package/esm2022/core/pipes/boolean.pipe.mjs +7 -1
  14. package/esm2022/core/provide.mjs +4 -3
  15. package/esm2022/core/services/tokens/module-config.token.mjs +1 -1
  16. package/esm2022/filter/descriptors/filter-lookup.descriptor.mjs +2 -3
  17. package/esm2022/filter/descriptors/filter.descriptor.mjs +76 -31
  18. package/esm2022/filter/models/filter.model.mjs +6 -1
  19. package/esm2022/form/components/date-range/date-range.component.mjs +45 -14
  20. package/esm2022/form/components/dropdown/dropdown.component.mjs +77 -93
  21. package/esm2022/form/components/number-range/number-range.component.mjs +29 -12
  22. package/esm2022/table/api/descriptors/column.descriptor.mjs +2 -1
  23. package/esm2022/table/api/descriptors/table.descriptor.mjs +22 -21
  24. package/esm2022/table/api/index.mjs +2 -1
  25. package/esm2022/table/api/models/row-expandable-component.model.mjs +2 -0
  26. package/esm2022/table/api/models/table-columns.model.mjs +1 -1
  27. package/esm2022/table/api/models/table.model.mjs +1 -1
  28. package/esm2022/table/components/column-filter/column-filter.component.mjs +396 -0
  29. package/esm2022/table/components/column-value/column-value.component.mjs +3 -3
  30. package/esm2022/table/components/filter/filter-active-tag/filter-active-tag.component.mjs +52 -0
  31. package/esm2022/table/components/filter/filter-form/filter-form.component.mjs +197 -0
  32. package/esm2022/table/components/filter/filter-overlay-with-tag/filter-overlay-with-tag.component.mjs +135 -0
  33. package/esm2022/table/components/table/table.component.mjs +34 -25
  34. package/esm2022/table/helpers/filters.mjs +297 -0
  35. package/esm2022/table/index.mjs +13 -2
  36. package/esm2022/table/models/filter.model.mjs +2 -0
  37. package/esm2022/table/pipes/filter-value.pipe.mjs +77 -0
  38. package/esm2022/table/provide.mjs +19 -0
  39. package/esm2022/table/services/data-list.service.mjs +1 -1
  40. package/esm2022/table/services/table-feature-config.token.mjs +3 -0
  41. package/esm2022/tableview/action/components/action/action.component.mjs +3 -3
  42. package/esm2022/tableview/action/components/editor/injector-context/action-editor-injector-context.component.mjs +2 -2
  43. package/esm2022/tableview/action/components/localization/data-language-dropdown.component.mjs +2 -2
  44. package/esm2022/tableview/action/components/table/action-table.component.mjs +3 -3
  45. package/esm2022/tableview/api/editor/descriptors/field-base.descriptor.mjs +1 -3
  46. package/esm2022/tableview/api/editor/descriptors/field.descriptor.mjs +14 -1
  47. package/esm2022/tableview/api/editor/models/editor-fields.model.mjs +1 -1
  48. package/esm2022/tableview/api/editor/models/field-image-preview.model.mjs +2 -0
  49. package/esm2022/tableview/api/index.mjs +2 -1
  50. package/esm2022/tableview/api/tableview/descriptors/tableview.descriptor.mjs +11 -13
  51. package/esm2022/tableview/editor/components/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.mjs +3 -3
  52. package/esm2022/tableview/editor/components/formly/fields/formly-field-datepicker/formly-field-datepicker.component.mjs +3 -3
  53. package/esm2022/tableview/editor/components/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +3 -3
  54. package/esm2022/tableview/editor/components/formly/fields/formly-field-input/formly-field-input.component.mjs +9 -3
  55. package/esm2022/tableview/editor/components/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.mjs +3 -3
  56. package/esm2022/tableview/editor/components/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +3 -3
  57. package/esm2022/tableview/editor/components/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +3 -3
  58. package/esm2022/tableview/tableview/components/tableview/tableview.component.mjs +3 -4
  59. package/fesm2022/mediusinc-mng-commons-core.mjs +32 -4
  60. package/fesm2022/mediusinc-mng-commons-core.mjs.map +1 -1
  61. package/fesm2022/mediusinc-mng-commons-filter.mjs +81 -32
  62. package/fesm2022/mediusinc-mng-commons-filter.mjs.map +1 -1
  63. package/fesm2022/mediusinc-mng-commons-form.mjs +149 -117
  64. package/fesm2022/mediusinc-mng-commons-form.mjs.map +1 -1
  65. package/fesm2022/mediusinc-mng-commons-table-api.mjs +22 -20
  66. package/fesm2022/mediusinc-mng-commons-table-api.mjs.map +1 -1
  67. package/fesm2022/mediusinc-mng-commons-table.mjs +833 -360
  68. package/fesm2022/mediusinc-mng-commons-table.mjs.map +1 -1
  69. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs +23 -14
  70. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs.map +1 -1
  71. package/fesm2022/mediusinc-mng-commons-tableview.mjs +27 -22
  72. package/fesm2022/mediusinc-mng-commons-tableview.mjs.map +1 -1
  73. package/filter/descriptors/filter.descriptor.d.ts +60 -16
  74. package/filter/models/filter.model.d.ts +4 -0
  75. package/form/components/date-range/date-range.component.d.ts +9 -3
  76. package/form/components/dropdown/dropdown.component.d.ts +6 -7
  77. package/form/components/number-range/number-range.component.d.ts +8 -4
  78. package/i18n/en.json +32 -0
  79. package/i18n/sl.json +32 -0
  80. package/package.json +1 -1
  81. package/table/api/descriptors/table.descriptor.d.ts +15 -8
  82. package/table/api/index.d.ts +1 -0
  83. package/table/api/models/row-expandable-component.model.d.ts +4 -0
  84. package/table/api/models/table-columns.model.d.ts +3 -3
  85. package/table/api/models/table.model.d.ts +0 -12
  86. package/table/components/{column-filter-full/column-filter-full.component.d.ts → column-filter/column-filter.component.d.ts} +23 -38
  87. package/table/components/filter/filter-active-tag/filter-active-tag.component.d.ts +20 -0
  88. package/table/components/filter/filter-form/filter-form.component.d.ts +53 -0
  89. package/table/components/filter/filter-overlay-with-tag/filter-overlay-with-tag.component.d.ts +35 -0
  90. package/table/components/table/table.component.d.ts +10 -7
  91. package/table/helpers/filters.d.ts +31 -0
  92. package/table/index.d.ts +10 -1
  93. package/table/models/filter.model.d.ts +24 -0
  94. package/table/pipes/filter-value.pipe.d.ts +19 -0
  95. package/table/provide.d.ts +8 -0
  96. package/table/services/data-list.service.d.ts +3 -2
  97. package/table/services/table-feature-config.token.d.ts +6 -0
  98. package/tableview/api/editor/descriptors/field-base.descriptor.d.ts +4 -4
  99. package/tableview/api/editor/descriptors/field.descriptor.d.ts +13 -3
  100. package/tableview/api/editor/models/editor-fields.model.d.ts +4 -4
  101. package/tableview/api/editor/models/field-image-preview.model.d.ts +4 -0
  102. package/tableview/api/index.d.ts +1 -0
  103. package/tableview/api/tableview/descriptors/tableview.descriptor.d.ts +8 -6
  104. package/tableview/editor/components/formly/fields/formly-field-input/formly-field-input.component.d.ts +1 -0
  105. package/version-info.json +5 -5
  106. package/esm2022/table/components/column-filter-full/column-filter-full.component.mjs +0 -655
@@ -1,655 +0,0 @@
1
- import { animate, style, transition, trigger } from '@angular/animations';
2
- import { NgClass } from '@angular/common';
3
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, Input, Renderer2, ViewChild, ViewEncapsulation, computed, effect, inject, signal } from '@angular/core';
4
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
- import { FormsModule } from '@angular/forms';
6
- import { TranslateModule } from '@ngx-translate/core';
7
- import { OverlayService, PrimeNGConfig, TranslationKeys } from 'primeng/api';
8
- import { CalendarModule } from 'primeng/calendar';
9
- import { ConnectedOverlayScrollHandler, DomHandler } from 'primeng/dom';
10
- import { FilterIcon } from 'primeng/icons/filter';
11
- import { FilterSlashIcon } from 'primeng/icons/filterslash';
12
- import { InputNumberModule } from 'primeng/inputnumber';
13
- import { InputTextModule } from 'primeng/inputtext';
14
- import { Table, TableModule } from 'primeng/table';
15
- import { TriStateCheckboxModule } from 'primeng/tristatecheckbox';
16
- import { ZIndexUtils } from 'primeng/utils';
17
- import { Subject, debounceTime, distinctUntilChanged } from 'rxjs';
18
- import { COMMONS_MODULE_CONFIG_IT, FilterMatchMode, dateToIsoString } from '@mediusinc/mng-commons/core';
19
- import { FilterDescriptor, FilterLookupTypeEnum, FilterTypeEnum } from '@mediusinc/mng-commons/filter';
20
- import { AutocompleteComponent, DateRangeComponent, DropdownComponent, InputTrimDirective, NumberRangeComponent } from '@mediusinc/mng-commons/form';
21
- import { DataListService } from '../../services/data-list.service';
22
- import * as i0 from "@angular/core";
23
- import * as i1 from "@ngx-translate/core";
24
- import * as i2 from "primeng/calendar";
25
- import * as i3 from "@angular/forms";
26
- import * as i4 from "primeng/tristatecheckbox";
27
- import * as i5 from "primeng/inputnumber";
28
- import * as i6 from "primeng/inputtext";
29
- /**
30
- * Cannot be on push change detection strategy because of filter updates triggered from route which causes to force update values in force metadata
31
- * and these must be propagated through to this component and beyond to primeNG.
32
- */
33
- export class TableColumnFilterFullComponent {
34
- constructor() {
35
- this.lookupTypeDropdown = FilterLookupTypeEnum.Dropdown;
36
- this.lookupTypeAutocomplete = FilterLookupTypeEnum.Autocomplete;
37
- this.el = inject(ElementRef);
38
- this.primeTable = inject(Table);
39
- this.dataListService = inject((DataListService));
40
- this.moduleConfig = inject(COMMONS_MODULE_CONFIG_IT, { optional: true });
41
- this.renderer = inject(Renderer2);
42
- this.primeConfig = inject(PrimeNGConfig);
43
- this.overlayService = inject(OverlayService);
44
- this.cd = inject(ChangeDetectorRef);
45
- this.destroyRef = inject(DestroyRef);
46
- this.document = window.document;
47
- this.primeType = 'text';
48
- // public matchModes: SelectItem[] = [];
49
- this.matchModes = signal([]);
50
- this.filterConstraint = signal(undefined);
51
- this.isFilterSet = computed(() => this.filterConstraint()?.matchMode === FilterMatchMode.Exists ||
52
- this.filterConstraint()?.matchMode === FilterMatchMode.DoesNotExist ||
53
- !this.primeTable.isFilterBlank(this.filterConstraint()?.value));
54
- this.isInputDisabled = computed(() => this.filterConstraint()?.matchMode === FilterMatchMode.Exists || this.filterConstraint()?.matchMode === FilterMatchMode.DoesNotExist);
55
- this.overlayVisible = signal(false);
56
- this.window = this.document.defaultView;
57
- this.numericValueFromModelChange = null;
58
- this.dateDebounceSubject = new Subject();
59
- this.dateTimeInUtc = false;
60
- this.dateTimeWithTimezone = true;
61
- this.dateTimeWithMillis = true;
62
- this.dateOnlyDisabled = false;
63
- this.dateDebounceSubject.pipe(debounceTime(500), distinctUntilChanged(), takeUntilDestroyed()).subscribe(v => {
64
- if (this.filterConstraint()?.displayMatchMode === FilterMatchMode.Equals && this.filterConstraint()?.matchMode === FilterMatchMode.Between && v !== null) {
65
- const dateValue = Array.isArray(v) ? v[0] : v; // could have empty array
66
- if (dateValue) {
67
- const fromDate = new Date(dateValue);
68
- const toDate = new Date(dateValue);
69
- if (this.descriptor.datePickerShowTime) {
70
- if (this.descriptor.datePickerShowSeconds) {
71
- fromDate.setMilliseconds(0);
72
- toDate.setMilliseconds(999);
73
- }
74
- else {
75
- fromDate.setSeconds(0, 0);
76
- toDate.setSeconds(59, 0);
77
- }
78
- }
79
- else {
80
- fromDate.setHours(0, 0, 0, 0);
81
- toDate.setHours(23, 59, 59, 999);
82
- }
83
- // adjust to settings
84
- v = [fromDate, toDate];
85
- }
86
- else {
87
- v = null;
88
- }
89
- }
90
- const convertDateType = this.descriptor.datePickerValueNoTime || (!this.dateOnlyDisabled && !this.descriptor.datePickerShowTime) ? 'date' : 'date-time';
91
- const convertDateTimeOpts = {
92
- utc: this.descriptor.datePickerValueUtc ?? this.dateTimeInUtc,
93
- noMillis: !this.dateTimeWithMillis,
94
- noTimezone: this.descriptor.datePickerValueNoTimezone ?? !this.dateTimeWithTimezone
95
- };
96
- this.updateFilterValue(v == null
97
- ? v
98
- : Array.isArray(v)
99
- ? v.filter(i => i != null).map(i => dateToIsoString(i, convertDateType, convertDateTimeOpts))
100
- : dateToIsoString(v, convertDateType, convertDateTimeOpts));
101
- });
102
- effect(() => {
103
- const fieldFilterMeta = this.dataListService.filterMeta()[this.primeField];
104
- if (fieldFilterMeta &&
105
- (!this.filterConstraint() || this.filterConstraint().value !== fieldFilterMeta.value || this.filterConstraint().matchMode !== fieldFilterMeta.matchMode)) {
106
- this.setFilterConstraint(fieldFilterMeta);
107
- }
108
- }, { allowSignalWrites: true });
109
- }
110
- ngOnInit() {
111
- if (this.moduleConfig?.serialization) {
112
- if (this.moduleConfig.serialization.dateTimeInUtc !== undefined)
113
- this.dateTimeInUtc = this.moduleConfig.serialization.dateTimeInUtc;
114
- if (this.moduleConfig.serialization.dateTimeWithTimezone !== undefined)
115
- this.dateTimeWithTimezone = this.moduleConfig.serialization.dateTimeWithTimezone;
116
- if (this.moduleConfig.serialization.dateTimeWithMillis !== undefined)
117
- this.dateTimeWithMillis = this.moduleConfig.serialization.dateTimeWithMillis;
118
- if (this.moduleConfig.serialization.filtersDateOnlyDisabled !== undefined)
119
- this.dateOnlyDisabled = this.moduleConfig.serialization.filtersDateOnlyDisabled;
120
- }
121
- this.primeField = this.descriptor.property;
122
- switch (this.descriptor.filterType) {
123
- case FilterTypeEnum.Boolean:
124
- this.primeType = 'boolean';
125
- break;
126
- case FilterTypeEnum.Number:
127
- this.primeType = 'numeric';
128
- break;
129
- case FilterTypeEnum.Date:
130
- this.primeType = 'date';
131
- break;
132
- case FilterTypeEnum.Lookup:
133
- case FilterTypeEnum.LookupEnum:
134
- this.primeType = 'lookup';
135
- this.lookupDescriptor = this.descriptor;
136
- break;
137
- case FilterTypeEnum.String:
138
- this.primeType = 'text';
139
- break;
140
- }
141
- // generate match mode options
142
- this.translationSubscription = this.primeConfig.translationObserver.subscribe(() => {
143
- this.generateMatchModeOptions();
144
- });
145
- this.generateMatchModeOptions();
146
- this.initFilterConstraint();
147
- }
148
- ngOnDestroy() {
149
- if (this.overlay) {
150
- this.renderer.appendChild(this.el.nativeElement, this.overlay);
151
- ZIndexUtils.clear(this.overlay);
152
- this.onOverlayHide();
153
- }
154
- this.translationSubscription?.unsubscribe();
155
- this.resetSubscription?.unsubscribe();
156
- this.overlaySubscription?.unsubscribe();
157
- this.tableFilterMetadataSubscription?.unsubscribe();
158
- }
159
- // eslint-disable-next-line @typescript-eslint/ban-types
160
- onTextModelChange(event) {
161
- const value = event.target.value;
162
- if (value === '') {
163
- this.updateFilterValue(value);
164
- }
165
- }
166
- // eslint-disable-next-line @typescript-eslint/ban-types
167
- onTextInputEnterKeyDown(event) {
168
- const value = event.target.value;
169
- this.updateFilterValue(value);
170
- event.preventDefault();
171
- }
172
- // eslint-disable-next-line @typescript-eslint/ban-types
173
- onNumericModelChange(value) {
174
- this.numericValueFromModelChange = value;
175
- if (value === null) {
176
- this.updateFilterValue(value);
177
- }
178
- }
179
- // eslint-disable-next-line @typescript-eslint/ban-types
180
- onNumericInputKeyDown(event) {
181
- if (event.key === 'Enter') {
182
- if (this.filterConstraint()?.displayMatchMode === FilterMatchMode.Between && Array.isArray(this.numericValueFromModelChange)) {
183
- const numberValues = this.numericValueFromModelChange.filter(v => typeof v === 'number');
184
- if (numberValues.length !== 2) {
185
- return;
186
- }
187
- }
188
- this.updateFilterValue(this.numericValueFromModelChange);
189
- event.preventDefault();
190
- }
191
- }
192
- // eslint-disable-next-line @typescript-eslint/ban-types
193
- onTristateModelChange(value) {
194
- this.updateFilterValue(value);
195
- }
196
- // eslint-disable-next-line @typescript-eslint/ban-types
197
- onDateFilterModelChange(value) {
198
- if (this.filterConstraint()?.displayMatchMode === FilterMatchMode.Between && Array.isArray(value)) {
199
- const dateValues = value.filter(v => v instanceof Date);
200
- if (dateValues.length !== 2) {
201
- return;
202
- }
203
- }
204
- this.dateDebounceSubject.next(value);
205
- }
206
- // eslint-disable-next-line @typescript-eslint/ban-types
207
- autocompleteFilter(value) {
208
- this.updateFilterValue(value);
209
- }
210
- // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any
211
- dropdownFilter(value) {
212
- if (Array.isArray(value) && value.length === 0) {
213
- value = undefined;
214
- }
215
- this.updateFilterValue(value);
216
- }
217
- onMatchModeChange(displayMatchMode) {
218
- const previousDisplayMatchMode = this.filterConstraint()?.displayMatchMode;
219
- let value = this.filterConstraint()?.displayValue;
220
- if (Array.isArray(value) && value.length === 0) {
221
- value = null;
222
- }
223
- if (value != null && previousDisplayMatchMode && displayMatchMode !== previousDisplayMatchMode) {
224
- // handle values on match mode changes
225
- const matchModesWithArrayValues = [FilterMatchMode.Between, FilterMatchMode.In, FilterMatchMode.NotIn];
226
- if (matchModesWithArrayValues.indexOf(previousDisplayMatchMode) >= 0 && matchModesWithArrayValues.indexOf(displayMatchMode) === -1) {
227
- // from array values to non-array values
228
- if (Array.isArray(value)) {
229
- value = value?.[0];
230
- }
231
- }
232
- else if (matchModesWithArrayValues.indexOf(previousDisplayMatchMode) === -1 && displayMatchMode === FilterMatchMode.Between) {
233
- // from non-array values to between
234
- // it can already be an array because of "fake" equals for dates with timestamps (that is actually between)
235
- const fromValue = Array.isArray(value) ? value[0] : value;
236
- // for to value, add 1 day (if date) or 1 (if number)
237
- const toValue = fromValue instanceof Date ? new Date(fromValue.getTime() + 24 * 3600 * 1000) : typeof fromValue === 'number' ? fromValue + 1 : fromValue;
238
- value = [fromValue, toValue];
239
- }
240
- else if (matchModesWithArrayValues.indexOf(previousDisplayMatchMode) >= 0 && displayMatchMode === FilterMatchMode.Between) {
241
- // from array values to between
242
- if (Array.isArray(value)) {
243
- if (value.length > 2) {
244
- value = [value[0], value[1]];
245
- }
246
- else if (value.length === 1) {
247
- value = [value[0], value[0]];
248
- }
249
- else if (value.length === 0) {
250
- value = null;
251
- }
252
- }
253
- }
254
- // filters with equals on dates with timezones are extra, because double value needs to be added and match mode changed
255
- if (displayMatchMode === FilterMatchMode.Equals &&
256
- this.descriptor.filterType === FilterTypeEnum.Date &&
257
- (this.descriptor.datePickerShowTime || this.descriptor.datePickerValueNoTime || this.dateOnlyDisabled)) {
258
- value = [value, value];
259
- displayMatchMode = FilterMatchMode.Between;
260
- }
261
- }
262
- this.setFilterConstraint({ ...this.filterConstraint(), matchMode: displayMatchMode, value: value });
263
- this.updateDtFilter();
264
- this.hideOverlay();
265
- }
266
- onMatchModeKeyDown(event) {
267
- const item = event.target;
268
- switch (event.key) {
269
- case 'ArrowDown':
270
- // eslint-disable-next-line no-case-declarations
271
- const nextItem = this.findNextMenuModeItem(item);
272
- if (nextItem) {
273
- item.removeAttribute('tabindex');
274
- nextItem.tabIndex = '0';
275
- nextItem.focus();
276
- }
277
- event.preventDefault();
278
- break;
279
- case 'ArrowUp':
280
- // eslint-disable-next-line no-case-declarations
281
- const prevItem = this.findPrevMenuModeItem(item);
282
- if (prevItem) {
283
- item.removeAttribute('tabindex');
284
- prevItem.tabIndex = '0';
285
- prevItem.focus();
286
- }
287
- event.preventDefault();
288
- break;
289
- }
290
- }
291
- onRowClearItemClick() {
292
- this.clearFilter();
293
- this.hideOverlay();
294
- }
295
- toggleMenu(event) {
296
- this.overlayVisible.set(!this.overlayVisible());
297
- event.stopPropagation();
298
- }
299
- onToggleButtonKeyDown(event) {
300
- switch (event.key) {
301
- case 'Escape':
302
- case 'Tab':
303
- this.overlayVisible.set(false);
304
- break;
305
- case 'ArrowDown':
306
- if (this.overlayVisible()) {
307
- const focusable = DomHandler.getFocusableElements(this.overlay);
308
- if (focusable) {
309
- focusable[0].focus();
310
- }
311
- event.preventDefault();
312
- }
313
- else if (event.altKey) {
314
- this.overlayVisible.set(true);
315
- event.preventDefault();
316
- }
317
- break;
318
- }
319
- }
320
- onEscape() {
321
- this.overlayVisible.set(false);
322
- }
323
- onContentClick() {
324
- this.selfClick = true;
325
- }
326
- // onOverlayAnimationStart(event: AnimationEvent) {
327
- onOverlayAnimationStart(event) {
328
- switch (event.toState) {
329
- case 'visible':
330
- this.overlay = event.element;
331
- this.renderer.appendChild(this.document.body, this.overlay);
332
- ZIndexUtils.set('overlay', this.overlay, this.primeConfig.zIndex.overlay);
333
- DomHandler.absolutePosition(this.overlay, this.icon?.nativeElement);
334
- this.bindDocumentClickListener();
335
- this.bindDocumentResizeListener();
336
- this.bindScrollListener();
337
- this.overlayEventListener = (e) => {
338
- if (this.overlay && this.overlay.contains(e.target)) {
339
- this.selfClick = true;
340
- }
341
- };
342
- this.overlaySubscription = this.overlayService.clickObservable.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.overlayEventListener);
343
- break;
344
- case 'void':
345
- this.onOverlayHide();
346
- this.overlaySubscription?.unsubscribe();
347
- break;
348
- }
349
- }
350
- // onOverlayAnimationEnd(event: AnimationEvent) {
351
- onOverlayAnimationEnd(event) {
352
- switch (event.toState) {
353
- case 'void':
354
- ZIndexUtils.clear(event.element);
355
- break;
356
- }
357
- }
358
- get noFilterLabel() {
359
- return this.primeConfig.getTranslation(TranslationKeys.NO_FILTER);
360
- }
361
- clearFilter() {
362
- this.initFilterConstraint(true);
363
- this.primeTable._filter();
364
- this.hideOverlay();
365
- }
366
- generateMatchModeOptions() {
367
- let options = undefined;
368
- if (this.descriptor.filterType === FilterTypeEnum.String) {
369
- options = [
370
- { value: FilterMatchMode.Contains, label: this.primeConfig.getTranslation(FilterMatchMode.Contains) },
371
- { value: FilterMatchMode.NotContains, label: this.primeConfig.getTranslation(FilterMatchMode.NotContains) },
372
- { value: FilterMatchMode.Equals, label: this.primeConfig.getTranslation(FilterMatchMode.Equals) },
373
- { value: FilterMatchMode.NotEquals, label: this.primeConfig.getTranslation(FilterMatchMode.NotEquals) },
374
- { value: FilterMatchMode.StartsWith, label: this.primeConfig.getTranslation(FilterMatchMode.StartsWith) },
375
- { value: FilterMatchMode.EndsWith, label: this.primeConfig.getTranslation(FilterMatchMode.EndsWith) },
376
- { value: FilterMatchMode.Exists, label: this.primeConfig.getTranslation(FilterMatchMode.Exists) },
377
- { value: FilterMatchMode.DoesNotExist, label: this.primeConfig.getTranslation(FilterMatchMode.DoesNotExist) }
378
- ];
379
- }
380
- else if (this.descriptor.filterType === FilterTypeEnum.Boolean) {
381
- options = [{ value: FilterMatchMode.Equals, label: this.primeConfig.getTranslation(FilterMatchMode.Equals) }];
382
- }
383
- else if (this.descriptor.filterType === FilterTypeEnum.Number) {
384
- options = [
385
- { value: FilterMatchMode.Equals, label: this.primeConfig.getTranslation(FilterMatchMode.Equals) },
386
- { value: FilterMatchMode.NotEquals, label: this.primeConfig.getTranslation(FilterMatchMode.NotEquals) },
387
- { value: FilterMatchMode.LessThan, label: this.primeConfig.getTranslation(FilterMatchMode.LessThan) },
388
- { value: FilterMatchMode.LessThanOrEqualTo, label: this.primeConfig.getTranslation(FilterMatchMode.LessThanOrEqualTo) },
389
- { value: FilterMatchMode.GreaterThan, label: this.primeConfig.getTranslation(FilterMatchMode.GreaterThan) },
390
- { value: FilterMatchMode.GreaterThanOrEqualTo, label: this.primeConfig.getTranslation(FilterMatchMode.GreaterThanOrEqualTo) },
391
- { value: FilterMatchMode.Between, label: this.primeConfig.getTranslation(FilterMatchMode.Between) },
392
- { value: FilterMatchMode.Exists, label: this.primeConfig.getTranslation(FilterMatchMode.Exists) },
393
- { value: FilterMatchMode.DoesNotExist, label: this.primeConfig.getTranslation(FilterMatchMode.DoesNotExist) }
394
- ];
395
- }
396
- else if (this.descriptor.filterType === FilterTypeEnum.Lookup || this.descriptor.filterType === FilterTypeEnum.LookupEnum) {
397
- options = [
398
- { value: FilterMatchMode.Equals, label: this.primeConfig.getTranslation(FilterMatchMode.Equals) },
399
- { value: FilterMatchMode.NotEquals, label: this.primeConfig.getTranslation(FilterMatchMode.NotEquals) },
400
- { value: FilterMatchMode.Exists, label: this.primeConfig.getTranslation(FilterMatchMode.Exists) },
401
- { value: FilterMatchMode.DoesNotExist, label: this.primeConfig.getTranslation(FilterMatchMode.DoesNotExist) }
402
- ];
403
- if (this.lookupDescriptor?.multiselect) {
404
- options = [
405
- { value: FilterMatchMode.In, label: this.primeConfig.getTranslation(FilterMatchMode.In) },
406
- { value: FilterMatchMode.NotIn, label: this.primeConfig.getTranslation(FilterMatchMode.NotIn) }
407
- ];
408
- }
409
- }
410
- else if (this.descriptor.filterType === FilterTypeEnum.Date) {
411
- if (!this.descriptor.datePickerShowTime && !this.descriptor.datePickerValueNoTime && !this.dateOnlyDisabled) {
412
- options = [
413
- { value: FilterMatchMode.Equals, label: this.primeConfig.getTranslation(FilterMatchMode.Equals) },
414
- { value: FilterMatchMode.NotEquals, label: this.primeConfig.getTranslation(FilterMatchMode.NotEquals) },
415
- { value: FilterMatchMode.LessThanOrEqualTo, label: this.primeConfig.getTranslation(FilterMatchMode.LessThanOrEqualTo) },
416
- { value: FilterMatchMode.GreaterThanOrEqualTo, label: this.primeConfig.getTranslation(FilterMatchMode.GreaterThanOrEqualTo) },
417
- { value: FilterMatchMode.Between, label: this.primeConfig.getTranslation(FilterMatchMode.Between) },
418
- { value: FilterMatchMode.Exists, label: this.primeConfig.getTranslation(FilterMatchMode.Exists) },
419
- { value: FilterMatchMode.DoesNotExist, label: this.primeConfig.getTranslation(FilterMatchMode.DoesNotExist) }
420
- ];
421
- }
422
- else {
423
- options = [
424
- { value: FilterMatchMode.Equals, label: this.primeConfig.getTranslation(FilterMatchMode.Equals) },
425
- { value: FilterMatchMode.LessThanOrEqualTo, label: this.primeConfig.getTranslation(FilterMatchMode.LessThanOrEqualTo) },
426
- { value: FilterMatchMode.GreaterThanOrEqualTo, label: this.primeConfig.getTranslation(FilterMatchMode.GreaterThanOrEqualTo) },
427
- { value: FilterMatchMode.Between, label: this.primeConfig.getTranslation(FilterMatchMode.Between) },
428
- { value: FilterMatchMode.Exists, label: this.primeConfig.getTranslation(FilterMatchMode.Exists) },
429
- { value: FilterMatchMode.DoesNotExist, label: this.primeConfig.getTranslation(FilterMatchMode.DoesNotExist) }
430
- ];
431
- }
432
- }
433
- if (this.descriptor.matchModes) {
434
- options = this.descriptor.matchModes.map(mm => ({ value: mm, label: this.primeConfig.getTranslation(mm) }));
435
- }
436
- if (!options) {
437
- let primeMathcModeOptionByType = undefined;
438
- if (this.primeType === 'text') {
439
- primeMathcModeOptionByType = this.primeConfig.filterMatchModeOptions.text;
440
- }
441
- else if (this.primeType === 'numeric') {
442
- primeMathcModeOptionByType = this.primeConfig.filterMatchModeOptions.numeric;
443
- }
444
- else if (this.primeType === 'date') {
445
- primeMathcModeOptionByType = this.primeConfig.filterMatchModeOptions.date;
446
- }
447
- if (primeMathcModeOptionByType) {
448
- options = primeMathcModeOptionByType.map(key => ({ label: this.primeConfig.getTranslation(key), value: key }));
449
- }
450
- }
451
- this.matchModes.set(options || []);
452
- }
453
- getDefaultMatchMode() {
454
- let defaultMatchMode = FilterMatchMode.Contains;
455
- if (this.primeType === 'text')
456
- defaultMatchMode = FilterMatchMode.StartsWith;
457
- else if (this.primeType === 'numeric')
458
- defaultMatchMode = FilterMatchMode.Equals;
459
- else if (this.primeType === 'date')
460
- defaultMatchMode = FilterMatchMode.Equals;
461
- else if (this.primeType === 'lookup')
462
- defaultMatchMode = this.lookupDescriptor?.multiselect ? FilterMatchMode.In : FilterMatchMode.Equals;
463
- // overwrite type default set in descriptor
464
- if (this.descriptor.defaultMatchMode) {
465
- defaultMatchMode = this.descriptor.defaultMatchMode;
466
- }
467
- // check if default mode exists!
468
- if (this.matchModes().length > 0 && !this.matchModes().some(m => m.value === defaultMatchMode)) {
469
- defaultMatchMode = this.matchModes()[0].value;
470
- }
471
- return defaultMatchMode;
472
- }
473
- findNextMenuModeItem(item) {
474
- const nextItem = item.nextElementSibling;
475
- if (nextItem)
476
- return DomHandler.hasClass(nextItem, 'p-column-filter-separator') ? this.findNextMenuModeItem(nextItem) : nextItem;
477
- else
478
- return item.parentElement?.firstElementChild;
479
- }
480
- findPrevMenuModeItem(item) {
481
- const prevItem = item.previousElementSibling;
482
- if (prevItem)
483
- return DomHandler.hasClass(prevItem, 'p-column-filter-separator') ? this.findPrevMenuModeItem(prevItem) : prevItem;
484
- else
485
- return item.parentElement?.lastElementChild;
486
- }
487
- isOutsideClicked(event) {
488
- return !(this.overlay?.isSameNode(event.target) ||
489
- this.overlay?.contains(event.target) ||
490
- this.icon?.nativeElement.isSameNode(event.target) ||
491
- this.icon?.nativeElement.contains(event.target) ||
492
- DomHandler.hasClass(event.target, 'p-column-filter-add-button') ||
493
- DomHandler.hasClass(event.target.parentElement, 'p-column-filter-add-button') ||
494
- DomHandler.hasClass(event.target, 'p-column-filter-remove-button') ||
495
- DomHandler.hasClass(event.target.parentElement, 'p-column-filter-remove-button'));
496
- }
497
- bindDocumentClickListener() {
498
- if (!this.documentClickListener) {
499
- const documentTarget = this.el ? this.el.nativeElement.ownerDocument : 'document';
500
- this.documentClickListener = this.renderer.listen(documentTarget, 'click', event => {
501
- if (this.overlayVisible() && !this.selfClick && this.isOutsideClicked(event)) {
502
- this.hideOverlay();
503
- }
504
- this.selfClick = false;
505
- });
506
- }
507
- }
508
- unbindDocumentClickListener() {
509
- if (this.documentClickListener) {
510
- this.documentClickListener();
511
- this.documentClickListener = null;
512
- this.selfClick = false;
513
- }
514
- }
515
- bindDocumentResizeListener() {
516
- if (!this.documentResizeListener) {
517
- this.documentResizeListener = this.renderer.listen(this.window, 'resize', () => {
518
- if (this.overlayVisible() && !DomHandler.isTouchDevice()) {
519
- this.hideOverlay();
520
- }
521
- });
522
- }
523
- }
524
- unbindDocumentResizeListener() {
525
- if (this.documentResizeListener) {
526
- this.documentResizeListener();
527
- this.documentResizeListener = null;
528
- }
529
- }
530
- bindScrollListener() {
531
- if (!this.scrollHandler) {
532
- this.scrollHandler = new ConnectedOverlayScrollHandler(this.icon?.nativeElement, () => {
533
- if (this.overlayVisible()) {
534
- this.hideOverlay();
535
- }
536
- });
537
- }
538
- this.scrollHandler.bindScrollListener();
539
- }
540
- unbindScrollListener() {
541
- if (this.scrollHandler) {
542
- this.scrollHandler.unbindScrollListener();
543
- }
544
- }
545
- hideOverlay() {
546
- this.overlayVisible.set(false);
547
- this.cd.markForCheck();
548
- }
549
- onOverlayHide() {
550
- this.unbindDocumentClickListener();
551
- this.unbindDocumentResizeListener();
552
- this.unbindScrollListener();
553
- this.overlay = null;
554
- }
555
- updateFilterValue(value) {
556
- this.filterConstraint.set({ ...this.filterConstraint(), value: value });
557
- this.updateDtFilter();
558
- }
559
- updateDtFilter() {
560
- this.primeTable.filters[this.primeField] = this.filterConstraint();
561
- this.primeTable._filter();
562
- }
563
- initFilterConstraint(reset = false) {
564
- if (reset) {
565
- const defaultMatchMode = this.getDefaultMatchMode();
566
- this.primeTable.filters[this.primeField] = { value: null, matchMode: defaultMatchMode };
567
- }
568
- // set internal filter constraint
569
- const metadata = this.primeTable.filters[this.primeField];
570
- if (Array.isArray(metadata)) {
571
- this.setFilterConstraint(metadata[0]);
572
- }
573
- else {
574
- this.setFilterConstraint(metadata);
575
- }
576
- }
577
- setFilterConstraint(metadata) {
578
- let matchMode = metadata?.matchMode ?? this.getDefaultMatchMode();
579
- let displayValue = metadata?.value;
580
- let displayMatchMode = matchMode;
581
- // when equals is used on dates with time, the actual filter will be between, but displayed as equals
582
- if (this.descriptor.filterType === FilterTypeEnum.Date && (this.descriptor.datePickerShowTime || this.descriptor.datePickerValueNoTime || this.dateOnlyDisabled)) {
583
- if (matchMode === FilterMatchMode.Between &&
584
- Array.isArray(metadata?.value) &&
585
- metadata?.value.length === 2 &&
586
- metadata?.value.every(v => v instanceof Date || typeof v === 'string' || typeof v === 'number')) {
587
- const startDate = dateToIsoString(metadata.value[0]);
588
- const endDate = dateToIsoString(metadata.value[1]);
589
- // 2020-11-02T11:12:12.000
590
- const cmpLength = this.descriptor.datePickerShowTime ? (this.descriptor.datePickerShowSeconds ? 19 : 16) : 10;
591
- if (startDate.substring(0, cmpLength) === endDate.substring(0, cmpLength)) {
592
- displayMatchMode = FilterMatchMode.Equals;
593
- displayValue = new Date(metadata.value[0]);
594
- }
595
- }
596
- else if (matchMode === FilterMatchMode.Equals && !metadata?.value) {
597
- matchMode = FilterMatchMode.Between;
598
- }
599
- }
600
- if (this.descriptor.filterType === FilterTypeEnum.Date && displayValue) {
601
- // display value for calendar cannot be string, convert to date
602
- displayValue = Array.isArray(displayValue)
603
- ? displayValue.map(v => (!(v instanceof Date) ? new Date(v) : v))
604
- : displayValue instanceof Date
605
- ? displayValue
606
- : new Date(displayValue);
607
- }
608
- this.filterConstraint.set({
609
- matchMode,
610
- value: metadata?.value,
611
- displayMatchMode,
612
- displayValue: displayValue ?? null
613
- });
614
- this.primeTable.filters[this.primeField] = this.filterConstraint();
615
- }
616
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TableColumnFilterFullComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
617
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TableColumnFilterFullComponent, isStandalone: true, selector: "mng-table-column-filter-full", inputs: { descriptor: "descriptor" }, viewQueries: [{ propertyName: "icon", first: true, predicate: ["icon"], descendants: true }], ngImport: i0, template: "<div class=\"p-column-filter p-column-filter-row\">\n @switch (primeType) {\n @case ('text') {\n <input\n type=\"text\"\n pInputText\n class=\"mng-column-filter-string-input\"\n [value]=\"filterConstraint()?.displayValue\"\n [disabled]=\"isInputDisabled()\"\n (input)=\"onTextModelChange($event)\"\n (keydown.enter)=\"onTextInputEnterKeyDown($event)\"\n [attr.placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [mngInputTrim]=\"descriptor.trimOption\" />\n }\n @case ('numeric') {\n @if (filterConstraint()?.displayMatchMode === 'between') {\n <mng-number-range\n className=\"mng-column-filter-number-input\"\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (keyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [useGrouping]=\"descriptor.numberUseGrouping\"\n [minFractionDigits]=\"descriptor.numberMinFractionDigits\"\n [maxFractionDigits]=\"descriptor.numberMaxFractionDigits\"\n [disabled]=\"isInputDisabled()\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-column-filter-number-input\"\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (onKeyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [useGrouping]=\"descriptor.numberUseGrouping\"\n [minFractionDigits]=\"descriptor.numberMinFractionDigits\"\n [maxFractionDigits]=\"descriptor.numberMaxFractionDigits\"\n [disabled]=\"isInputDisabled()\" />\n }\n }\n\n @case ('boolean') {\n <p-triStateCheckbox [ngModel]=\"filterConstraint()?.displayValue\" (ngModelChange)=\"onTristateModelChange($event)\"></p-triStateCheckbox>\n }\n @case ('date') {\n @if (filterConstraint()?.displayMatchMode === 'between') {\n <mng-date-range\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [showTime]=\"descriptor.datePickerShowTime\"\n [dateFormat]=\"descriptor.datePickerFormat\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [disabled]=\"isInputDisabled()\"></mng-date-range>\n } @else {\n <p-calendar\n appendTo=\"body\"\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [showIcon]=\"true\"\n [dateFormat]=\"descriptor.datePickerFormat ?? 'dd.mm.yy'\"\n [showTime]=\"descriptor.datePickerShowTime\"\n [firstDayOfWeek]=\"1\">\n </p-calendar>\n }\n }\n @case ('lookup') {\n @if (lookupDescriptor) {\n @switch (lookupDescriptor.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n [ngModel]=\"filterConstraint()?.displayValue\"\n [dataProvider]=\"lookupDescriptor.dataProvider\"\n [optionsTrackProperty]=\"lookupDescriptor.optionsValueProperty\"\n [optionsValueProperty]=\"lookupDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupDescriptor.multiselect\"\n [autoClear]=\"lookupDescriptor.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookupDescriptor.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookupDescriptor.autocompleteInlineSearch ?? false\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.searchToFilter' | translate\"\n [className]=\"lookupDescriptor.className\"\n [dropdownClassName]=\"lookupDescriptor.dropdownClassName\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"autocompleteFilter($event)\"\n [searchTrim]=\"descriptor.trimOption\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n [ngModel]=\"filterConstraint()?.displayValue\"\n [dataProvider]=\"lookupDescriptor.dataProvider\"\n [optionsValueProperty]=\"lookupDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupDescriptor.multiselect\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.selectToFilter' | translate\"\n [className]=\"lookupDescriptor.className\"\n [dropdownClassName]=\"lookupDescriptor.dropdownClassName\"\n [showClear]=\"false\"\n [changeValueOnBlur]=\"lookupDescriptor.multiselect\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"dropdownFilter($event)\">\n </mng-dropdown>\n }\n }\n }\n }\n }\n\n @if (matchModes().length > 1) {\n <button\n #icon\n type=\"button\"\n class=\"p-column-filter-menu-button p-link\"\n aria-haspopup=\"true\"\n [attr.aria-expanded]=\"overlayVisible()\"\n [ngClass]=\"{'p-column-filter-menu-button-open': overlayVisible(), 'p-column-filter-menu-button-active': isFilterSet()}\"\n (click)=\"toggleMenu($event)\"\n (keydown)=\"onToggleButtonKeyDown($event)\">\n <FilterIcon [styleClass]=\"'pi-filter-icon'\" />\n </button>\n }\n <button #icon [ngClass]=\"{'p-hidden-space': !isFilterSet()}\" type=\"button\" class=\"p-column-filter-clear-button p-link\" (click)=\"clearFilter()\">\n <FilterSlashIcon />\n </button>\n @if (overlayVisible()) {\n <div\n class=\"p-column-filter-overlay p-component p-fluid\"\n (click)=\"onContentClick()\"\n [@overlayAnimation]=\"'visible'\"\n (@overlayAnimation.start)=\"onOverlayAnimationStart($event)\"\n (@overlayAnimation.done)=\"onOverlayAnimationEnd($event)\"\n (keydown.escape)=\"onEscape()\">\n <ul class=\"p-column-filter-row-items\">\n @for (matchMode of matchModes(); track matchMode; let i = $index) {\n <li\n class=\"p-column-filter-row-item\"\n (click)=\"onMatchModeChange(matchMode.value)\"\n (keydown)=\"onMatchModeKeyDown($event)\"\n (keydown.enter)=\"this.onMatchModeChange(matchMode.value)\"\n [ngClass]=\"{'p-highlight': matchMode.value === filterConstraint()?.displayMatchMode}\"\n [attr.tabindex]=\"i === 0 ? '0' : null\">\n {{ matchMode.label }}\n </li>\n }\n <li class=\"p-column-filter-separator\"></li>\n <li class=\"p-column-filter-row-item\" (click)=\"onRowClearItemClick()\" (keydown)=\"onMatchModeKeyDown($event)\" (keydown.enter)=\"onRowClearItemClick()\">\n {{ noFilterLabel }}\n </li>\n </ul>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "component", type: DateRangeComponent, selector: "mng-date-range", inputs: ["placeholder", "showTime", "showSeconds", "dateFormat", "className", "disabled"] }, { kind: "ngmodule", type: CalendarModule }, { kind: "component", type: i2.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AutocompleteComponent, selector: "mng-autocomplete", inputs: ["dataProvider", "optionsTrackProperty", "optionsValueProperty", "optionsLabelProperty", "optionsLabelTranslate", "inlineSearch", "openOnFocus", "multiselect", "placeholder", "className", "dropdownClassName", "showClear", "autoClear", "selectFirst", "searchTrim", "disabled"], outputs: ["valueChange", "blur"] }, { kind: "component", type: DropdownComponent, selector: "mng-dropdown", inputs: ["dataProvider", "options", "optionsTrackProperty", "optionsLabelProperty", "optionsLabelTranslate", "optionsValueProperty", "optionsDisabledProperty", "multiselect", "placeholder", "showClear", "selectFirstItem", "className", "dropdownClassName", "changeValueOnBlur", "loading", "disabled"], outputs: ["valueChange", "blur"] }, { kind: "ngmodule", type: TriStateCheckboxModule }, { kind: "component", type: i4.TriStateCheckbox, selector: "p-triStateCheckbox", inputs: ["disabled", "name", "ariaLabel", "ariaLabelledBy", "variant", "tabindex", "inputId", "style", "styleClass", "label", "readonly", "checkboxTrueIcon", "checkboxFalseIcon", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i5.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "component", type: FilterIcon, selector: "FilterIcon" }, { kind: "component", type: FilterSlashIcon, selector: "FilterSlashIcon" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: InputTrimDirective, selector: "[mngInputTrim]", inputs: ["mngInputTrim"] }, { kind: "component", type: NumberRangeComponent, selector: "mng-number-range", inputs: ["placeholder", "useGrouping", "minFractionDigits", "maxFractionDigits", "disabled", "className"], outputs: ["keyDown"] }], animations: [
618
- trigger('overlayAnimation', [
619
- transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('.12s cubic-bezier(0, 0, 0.2, 1)')]),
620
- transition(':leave', [animate('.1s linear', style({ opacity: 0 }))])
621
- ])
622
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
623
- }
624
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TableColumnFilterFullComponent, decorators: [{
625
- type: Component,
626
- args: [{ standalone: true, selector: 'mng-table-column-filter-full', imports: [
627
- TableModule,
628
- TranslateModule,
629
- DateRangeComponent,
630
- CalendarModule,
631
- FormsModule,
632
- AutocompleteComponent,
633
- DropdownComponent,
634
- TriStateCheckboxModule,
635
- InputNumberModule,
636
- InputTextModule,
637
- FilterIcon,
638
- FilterSlashIcon,
639
- NgClass,
640
- InputTrimDirective,
641
- NumberRangeComponent
642
- ], animations: [
643
- trigger('overlayAnimation', [
644
- transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('.12s cubic-bezier(0, 0, 0.2, 1)')]),
645
- transition(':leave', [animate('.1s linear', style({ opacity: 0 }))])
646
- ])
647
- ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"p-column-filter p-column-filter-row\">\n @switch (primeType) {\n @case ('text') {\n <input\n type=\"text\"\n pInputText\n class=\"mng-column-filter-string-input\"\n [value]=\"filterConstraint()?.displayValue\"\n [disabled]=\"isInputDisabled()\"\n (input)=\"onTextModelChange($event)\"\n (keydown.enter)=\"onTextInputEnterKeyDown($event)\"\n [attr.placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [mngInputTrim]=\"descriptor.trimOption\" />\n }\n @case ('numeric') {\n @if (filterConstraint()?.displayMatchMode === 'between') {\n <mng-number-range\n className=\"mng-column-filter-number-input\"\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (keyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [useGrouping]=\"descriptor.numberUseGrouping\"\n [minFractionDigits]=\"descriptor.numberMinFractionDigits\"\n [maxFractionDigits]=\"descriptor.numberMaxFractionDigits\"\n [disabled]=\"isInputDisabled()\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-column-filter-number-input\"\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (onKeyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [useGrouping]=\"descriptor.numberUseGrouping\"\n [minFractionDigits]=\"descriptor.numberMinFractionDigits\"\n [maxFractionDigits]=\"descriptor.numberMaxFractionDigits\"\n [disabled]=\"isInputDisabled()\" />\n }\n }\n\n @case ('boolean') {\n <p-triStateCheckbox [ngModel]=\"filterConstraint()?.displayValue\" (ngModelChange)=\"onTristateModelChange($event)\"></p-triStateCheckbox>\n }\n @case ('date') {\n @if (filterConstraint()?.displayMatchMode === 'between') {\n <mng-date-range\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [showTime]=\"descriptor.datePickerShowTime\"\n [dateFormat]=\"descriptor.datePickerFormat\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [disabled]=\"isInputDisabled()\"></mng-date-range>\n } @else {\n <p-calendar\n appendTo=\"body\"\n [ngModel]=\"filterConstraint()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.typeToFilter' | translate\"\n [showIcon]=\"true\"\n [dateFormat]=\"descriptor.datePickerFormat ?? 'dd.mm.yy'\"\n [showTime]=\"descriptor.datePickerShowTime\"\n [firstDayOfWeek]=\"1\">\n </p-calendar>\n }\n }\n @case ('lookup') {\n @if (lookupDescriptor) {\n @switch (lookupDescriptor.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n [ngModel]=\"filterConstraint()?.displayValue\"\n [dataProvider]=\"lookupDescriptor.dataProvider\"\n [optionsTrackProperty]=\"lookupDescriptor.optionsValueProperty\"\n [optionsValueProperty]=\"lookupDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupDescriptor.multiselect\"\n [autoClear]=\"lookupDescriptor.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookupDescriptor.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookupDescriptor.autocompleteInlineSearch ?? false\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.searchToFilter' | translate\"\n [className]=\"lookupDescriptor.className\"\n [dropdownClassName]=\"lookupDescriptor.dropdownClassName\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"autocompleteFilter($event)\"\n [searchTrim]=\"descriptor.trimOption\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n [ngModel]=\"filterConstraint()?.displayValue\"\n [dataProvider]=\"lookupDescriptor.dataProvider\"\n [optionsValueProperty]=\"lookupDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupDescriptor.multiselect\"\n [placeholder]=\"descriptor.placeholder ?? 'mngTable.selectToFilter' | translate\"\n [className]=\"lookupDescriptor.className\"\n [dropdownClassName]=\"lookupDescriptor.dropdownClassName\"\n [showClear]=\"false\"\n [changeValueOnBlur]=\"lookupDescriptor.multiselect\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"dropdownFilter($event)\">\n </mng-dropdown>\n }\n }\n }\n }\n }\n\n @if (matchModes().length > 1) {\n <button\n #icon\n type=\"button\"\n class=\"p-column-filter-menu-button p-link\"\n aria-haspopup=\"true\"\n [attr.aria-expanded]=\"overlayVisible()\"\n [ngClass]=\"{'p-column-filter-menu-button-open': overlayVisible(), 'p-column-filter-menu-button-active': isFilterSet()}\"\n (click)=\"toggleMenu($event)\"\n (keydown)=\"onToggleButtonKeyDown($event)\">\n <FilterIcon [styleClass]=\"'pi-filter-icon'\" />\n </button>\n }\n <button #icon [ngClass]=\"{'p-hidden-space': !isFilterSet()}\" type=\"button\" class=\"p-column-filter-clear-button p-link\" (click)=\"clearFilter()\">\n <FilterSlashIcon />\n </button>\n @if (overlayVisible()) {\n <div\n class=\"p-column-filter-overlay p-component p-fluid\"\n (click)=\"onContentClick()\"\n [@overlayAnimation]=\"'visible'\"\n (@overlayAnimation.start)=\"onOverlayAnimationStart($event)\"\n (@overlayAnimation.done)=\"onOverlayAnimationEnd($event)\"\n (keydown.escape)=\"onEscape()\">\n <ul class=\"p-column-filter-row-items\">\n @for (matchMode of matchModes(); track matchMode; let i = $index) {\n <li\n class=\"p-column-filter-row-item\"\n (click)=\"onMatchModeChange(matchMode.value)\"\n (keydown)=\"onMatchModeKeyDown($event)\"\n (keydown.enter)=\"this.onMatchModeChange(matchMode.value)\"\n [ngClass]=\"{'p-highlight': matchMode.value === filterConstraint()?.displayMatchMode}\"\n [attr.tabindex]=\"i === 0 ? '0' : null\">\n {{ matchMode.label }}\n </li>\n }\n <li class=\"p-column-filter-separator\"></li>\n <li class=\"p-column-filter-row-item\" (click)=\"onRowClearItemClick()\" (keydown)=\"onMatchModeKeyDown($event)\" (keydown.enter)=\"onRowClearItemClick()\">\n {{ noFilterLabel }}\n </li>\n </ul>\n </div>\n }\n</div>\n" }]
648
- }], ctorParameters: () => [], propDecorators: { descriptor: [{
649
- type: Input,
650
- args: [{ required: true }]
651
- }], icon: [{
652
- type: ViewChild,
653
- args: ['icon']
654
- }] } });
655
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sdW1uLWZpbHRlci1mdWxsLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3RhYmxlL3NyYy9jb21wb25lbnRzL2NvbHVtbi1maWx0ZXItZnVsbC9jb2x1bW4tZmlsdGVyLWZ1bGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvY29sdW1uLWZpbHRlci1mdWxsL2NvbHVtbi1maWx0ZXItZnVsbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDeEUsT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3hDLE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsVUFBVSxFQUNWLEtBQUssRUFHTCxTQUFTLEVBQ1QsU0FBUyxFQUNULGlCQUFpQixFQUNqQixRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUMsY0FBYyxFQUF5QyxhQUFhLEVBQWMsZUFBZSxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQzlILE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUMsNkJBQTZCLEVBQUUsVUFBVSxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ3RFLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxLQUFLLEVBQUUsV0FBVyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ2pELE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBRWhFLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDMUMsT0FBTyxFQUFDLE9BQU8sRUFBZ0IsWUFBWSxFQUFFLG9CQUFvQixFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRS9FLE9BQU8sRUFBQyx3QkFBd0IsRUFBRSxlQUFlLEVBQStCLGVBQWUsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBQ3BJLE9BQU8sRUFBQyxnQkFBZ0IsRUFBMEIsb0JBQW9CLEVBQUUsY0FBYyxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFDN0gsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLGtCQUFrQixFQUFFLG9CQUFvQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFFbkosT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGtDQUFrQyxDQUFDOzs7Ozs7OztBQUVqRTs7O0dBR0c7QUErQkgsTUFBTSxPQUFPLDhCQUE4QjtJQXdEdkM7UUF2RGdCLHVCQUFrQixHQUF5QixvQkFBb0IsQ0FBQyxRQUFRLENBQUM7UUFDekUsMkJBQXNCLEdBQXlCLG9CQUFvQixDQUFDLFlBQVksQ0FBQztRQUNoRixPQUFFLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hCLGVBQVUsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0Isb0JBQWUsR0FBRyxNQUFNLENBQUMsQ0FBQSxlQUFvQixDQUFBLENBQUMsQ0FBQztRQUMvQyxpQkFBWSxHQUFHLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRSxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDO1FBQ2xFLGFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0IsZ0JBQVcsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDcEMsbUJBQWMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDeEMsT0FBRSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9CLGVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEMsYUFBUSxHQUFhLE1BQU0sQ0FBQyxRQUFRLENBQUM7UUFRL0MsY0FBUyxHQUFHLE1BQU0sQ0FBQztRQUcxQix3Q0FBd0M7UUFDakMsZUFBVSxHQUFHLE1BQU0sQ0FBZSxFQUFFLENBQUMsQ0FBQztRQUN0QyxxQkFBZ0IsR0FBRyxNQUFNLENBQTZCLFNBQVMsQ0FBQyxDQUFDO1FBQ2pFLGdCQUFXLEdBQUcsUUFBUSxDQUN6QixHQUFHLEVBQUUsQ0FDRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxTQUFTLEtBQUssZUFBZSxDQUFDLE1BQU07WUFDN0QsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsU0FBUyxLQUFLLGVBQWUsQ0FBQyxZQUFZO1lBQ25FLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxDQUFDLENBQ3JFLENBQUM7UUFDSyxvQkFBZSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxTQUFTLEtBQUssZUFBZSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxTQUFTLEtBQUssZUFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3ZLLG1CQUFjLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBYXJCLFdBQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQXFCLENBQUM7UUFFdEQsZ0NBQTJCLEdBQTZCLElBQUksQ0FBQztRQUU3RCx3QkFBbUIsR0FBRyxJQUFJLE9BQU8sRUFBd0IsQ0FBQztRQUMxRCxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUN0Qix5QkFBb0IsR0FBRyxJQUFJLENBQUM7UUFDNUIsdUJBQWtCLEdBQUcsSUFBSSxDQUFDO1FBQzFCLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUc3QixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDekcsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxnQkFBZ0IsS0FBSyxlQUFlLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFNBQVMsS0FBSyxlQUFlLENBQUMsT0FBTyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDdkosTUFBTSxTQUFTLEdBQXFCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMseUJBQXlCO2dCQUUxRixJQUFJLFNBQVMsRUFBRSxDQUFDO29CQUNaLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUNyQyxNQUFNLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFFbkMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixFQUFFLENBQUM7d0JBQ3JDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDOzRCQUN4QyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUM1QixNQUFNLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO3dCQUNoQyxDQUFDOzZCQUFNLENBQUM7NEJBQ0osUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7NEJBQzFCLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUM3QixDQUFDO29CQUNMLENBQUM7eUJBQU0sQ0FBQzt3QkFDSixRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUM5QixNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUNyQyxDQUFDO29CQUNELHFCQUFxQjtvQkFDckIsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUMzQixDQUFDO3FCQUFNLENBQUM7b0JBQ0osQ0FBQyxHQUFHLElBQUksQ0FBQztnQkFDYixDQUFDO1lBQ0wsQ0FBQztZQUNELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMscUJBQXFCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7WUFDeEosTUFBTSxtQkFBbUIsR0FBRztnQkFDeEIsR0FBRyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLElBQUksSUFBSSxDQUFDLGFBQWE7Z0JBQzdELFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0I7Z0JBQ2xDLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLHlCQUF5QixJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQjthQUN0RixDQUFDO1lBQ0YsSUFBSSxDQUFDLGlCQUFpQixDQUNsQixDQUFDLElBQUksSUFBSTtnQkFDTCxDQUFDLENBQUMsQ0FBQztnQkFDSCxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7b0JBQ2hCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLG1CQUFtQixDQUFDLENBQUM7b0JBQzdGLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxFQUFFLGVBQWUsRUFBRSxtQkFBbUIsQ0FBQyxDQUNuRSxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQ0YsR0FBRyxFQUFFO1lBQ0QsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDM0UsSUFDSSxlQUFlO2dCQUNmLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUcsQ0FBQyxLQUFLLEtBQUssZUFBZSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUcsQ0FBQyxTQUFTLEtBQUssZUFBZSxDQUFDLFNBQVMsQ0FBQyxFQUM1SixDQUFDO2dCQUNDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5QyxDQUFDO1FBQ0wsQ0FBQyxFQUNELEVBQUMsaUJBQWlCLEVBQUUsSUFBSSxFQUFDLENBQzVCLENBQUM7SUFDTixDQUFDO0lBRUQsUUFBUTtRQUNKLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxhQUFhLEVBQUUsQ0FBQztZQUNuQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLGFBQWEsS0FBSyxTQUFTO2dCQUFFLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDO1lBQ3BJLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsb0JBQW9CLEtBQUssU0FBUztnQkFBRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUM7WUFDekosSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsS0FBSyxTQUFTO2dCQUFFLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQztZQUNuSixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLHVCQUF1QixLQUFLLFNBQVM7Z0JBQUUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLHVCQUF1QixDQUFDO1FBQy9KLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO1FBRTNDLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNqQyxLQUFLLGNBQWMsQ0FBQyxPQUFPO2dCQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztnQkFDM0IsTUFBTTtZQUNWLEtBQUssY0FBYyxDQUFDLE1BQU07Z0JBQ3RCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO2dCQUMzQixNQUFNO1lBQ1YsS0FBSyxjQUFjLENBQUMsSUFBSTtnQkFDcEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUM7Z0JBQ3hCLE1BQU07WUFDVixLQUFLLGNBQWMsQ0FBQyxNQUFNLENBQUM7WUFDM0IsS0FBSyxjQUFjLENBQUMsVUFBVTtnQkFDMUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsVUFBOEMsQ0FBQztnQkFDNUUsTUFBTTtZQUNWLEtBQUssY0FBYyxDQUFDLE1BQU07Z0JBQ3RCLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO2dCQUN4QixNQUFNO1FBQ2QsQ0FBQztRQUVELDhCQUE4QjtRQUM5QixJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQy9FLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ3BDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFFaEMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7SUFDaEMsQ0FBQztJQUVELFdBQVc7UUFDUCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvRCxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNoQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekIsQ0FBQztRQUVELElBQUksQ0FBQyx1QkFBdUIsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUM1QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQywrQkFBK0IsRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUN4RCxDQUFDO0lBRUQsd0RBQXdEO0lBQ3hELGlCQUFpQixDQUFDLEtBQVk7UUFDMUIsTUFBTSxLQUFLLEdBQUksS0FBSyxDQUFDLE1BQTJCLENBQUMsS0FBSyxDQUFDO1FBQ3ZELElBQUksS0FBSyxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLENBQUM7SUFDTCxDQUFDO0lBRUQsd0RBQXdEO0lBQ3hELHVCQUF1QixDQUFDLEtBQVk7UUFDaEMsTUFBTSxLQUFLLEdBQUksS0FBSyxDQUFDLE1BQTJCLENBQUMsS0FBSyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELHdEQUF3RDtJQUN4RCxvQkFBb0IsQ0FBQyxLQUFvQjtRQUNyQyxJQUFJLENBQUMsMkJBQTJCLEdBQUcsS0FBSyxDQUFDO1FBQ3pDLElBQUksS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHdEQUF3RDtJQUN4RCxxQkFBcUIsQ0FBQyxLQUFvQjtRQUN0QyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDeEIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxnQkFBZ0IsS0FBSyxlQUFlLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLEVBQUUsQ0FBQztnQkFDM0gsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDO2dCQUN6RixJQUFJLFlBQVksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQzVCLE9BQU87Z0JBQ1gsQ0FBQztZQUNMLENBQUM7WUFDRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7WUFDekQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzNCLENBQUM7SUFDTCxDQUFDO0lBRUQsd0RBQXdEO0lBQ3hELHFCQUFxQixDQUFDLEtBQXFCO1FBQ3ZDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsd0RBQXdEO0lBQ3hELHVCQUF1QixDQUFDLEtBQTJCO1FBQy9DLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsZ0JBQWdCLEtBQUssZUFBZSxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEcsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQztZQUN4RCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQzFCLE9BQU87WUFDWCxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVELHdEQUF3RDtJQUN4RCxrQkFBa0IsQ0FBQyxLQUFVO1FBQ3pCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsNEZBQTRGO0lBQzVGLGNBQWMsQ0FBQyxLQUFVO1FBQ3JCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzdDLEtBQUssR0FBRyxTQUFTLENBQUM7UUFDdEIsQ0FBQztRQUNELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsaUJBQWlCLENBQUMsZ0JBQXdCO1FBQ3RDLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsZ0JBQWdCLENBQUM7UUFDM0UsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsWUFBWSxDQUFDO1FBQ2xELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzdDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDakIsQ0FBQztRQUNELElBQUksS0FBSyxJQUFJLElBQUksSUFBSSx3QkFBd0IsSUFBSSxnQkFBZ0IsS0FBSyx3QkFBd0IsRUFBRSxDQUFDO1lBQzdGLHNDQUFzQztZQUN0QyxNQUFNLHlCQUF5QixHQUFhLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxlQUFlLENBQUMsRUFBRSxFQUFFLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVqSCxJQUFJLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsSUFBSSx5QkFBeUIsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNqSSx3Q0FBd0M7Z0JBQ3hDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUN2QixLQUFLLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZCLENBQUM7WUFDTCxDQUFDO2lCQUFNLElBQUkseUJBQXlCLENBQUMsT0FBTyxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksZ0JBQWdCLEtBQUssZUFBZSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUM1SCxtQ0FBbUM7Z0JBQ25DLDJHQUEyRztnQkFDM0csTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBQzFELHFEQUFxRDtnQkFDckQsTUFBTSxPQUFPLEdBQUcsU0FBUyxZQUFZLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sU0FBUyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUN6SixLQUFLLEdBQUcsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDakMsQ0FBQztpQkFBTSxJQUFJLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxnQkFBZ0IsS0FBSyxlQUFlLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzFILCtCQUErQjtnQkFDL0IsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ3ZCLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDbkIsS0FBSyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNqQyxDQUFDO3lCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQzt3QkFDNUIsS0FBSyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNqQyxDQUFDO3lCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQzt3QkFDNUIsS0FBSyxHQUFHLElBQUksQ0FBQztvQkFDakIsQ0FBQztnQkFDTCxDQUFDO1lBQ0wsQ0FBQztZQUVELHVIQUF1SDtZQUN2SCxJQUNJLGdCQUFnQixLQUFLLGVBQWUsQ0FBQyxNQUFNO2dCQUMzQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsS0FBSyxjQUFjLENBQUMsSUFBSTtnQkFDbEQsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMscUJBQXFCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQ3hHLENBQUM7Z0JBQ0MsS0FBSyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUN2QixnQkFBZ0IsR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDO1lBQy9DLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7UUFDbEcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsa0JBQWtCLENBQUMsS0FBb0I7UUFDbkMsTUFBTSxJQUFJLEdBQWtCLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFekMsUUFBUSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDaEIsS0FBSyxXQUFXO2dCQUNaLGdEQUFnRDtnQkFDaEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLFFBQVEsRUFBRSxDQUFDO29CQUNYLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ2pDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO29CQUN4QixRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3JCLENBQUM7Z0JBRUQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixNQUFNO1lBRVYsS0FBSyxTQUFTO2dCQUNWLGdEQUFnRDtnQkFDaEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLFFBQVEsRUFBRSxDQUFDO29CQUNYLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ2pDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO29CQUN4QixRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3JCLENBQUM7Z0JBRUQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixNQUFNO1FBQ2QsQ0FBQztJQUNMLENBQUM7SUFFRCxtQkFBbUI7UUFDZixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxVQUFVLENBQUMsS0FBWTtRQUNuQixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQscUJBQXFCLENBQUMsS0FBb0I7UUFDdEMsUUFBUSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDaEIsS0FBSyxRQUFRLENBQUM7WUFDZCxLQUFLLEtBQUs7Z0JBQ04sSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQy9CLE1BQU07WUFFVixLQUFLLFdBQVc7Z0JBQ1osSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztvQkFDeEIsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLG9CQUFvQixDQUFjLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDN0UsSUFBSSxTQUFTLEVBQUUsQ0FBQzt3QkFDWixTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ3pCLENBQUM7b0JBQ0QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUMzQixDQUFDO3FCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUN0QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDOUIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUMzQixDQUFDO2dCQUNELE1BQU07UUFDZCxDQUFDO0lBQ0wsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsY0FBYztRQUNWLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO0lBQzFCLENBQUM7SUFFRCxtREFBbUQ7SUFDbkQsdUJBQXVCLENBQUMsS0FBVTtRQUM5QixRQUFRLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQixLQUFLLFNBQVM7Z0JBQ1YsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUM3QixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzVELFdBQVcsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzFFLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7Z0JBQ3BFLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztnQkFDbEMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBRTFCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFO29CQUNuQyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7d0JBQ2xELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO29CQUMxQixDQUFDO2dCQUNMLENBQUMsQ0FBQztnQkFFRixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztnQkFDOUksTUFBTTtZQUVWLEtBQUssTUFBTTtnQkFDUCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsQ0FBQztnQkFDeEMsTUFBTTtRQUNkLENBQUM7SUFDTCxDQUFDO0lBRUQsaURBQWlEO0lBQ2pELHFCQUFxQixDQUFDLEtBQVU7UUFDNUIsUUFBUSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDcEIsS0FBSyxNQUFNO2dCQUNQLFdBQVcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNqQyxNQUFNO1FBQ2QsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFJLGFBQWE7UUFDYixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRU8sd0JBQXdCO1FBQzVCLElBQUksT0FBTyxHQUE2QixTQUFTLENBQUM7UUFDbEQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsS0FBSyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdkQsT0FBTyxHQUFHO2dCQUNOLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsRUFBQztnQkFDbkcsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxFQUFDO2dCQUN6RyxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUM7Z0JBQy9GLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsRUFBQztnQkFDckcsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxFQUFDO2dCQUN2RyxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLEVBQUM7Z0JBQ25HLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBQztnQkFDL0YsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxFQUFDO2FBQzlHLENBQUM7UUFDTixDQUFDO2FBQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsS0FBSyxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDL0QsT0FBTyxHQUFHLENBQUMsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUNoSCxDQUFDO2FBQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsS0FBSyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDOUQsT0FBTyxHQUFHO2dCQUNOLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBQztnQkFDL0YsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxFQUFDO2dCQUNyRyxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLEVBQUM7Z0JBQ25HLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLEVBQUM7Z0JBQ3JILEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsRUFBQztnQkFDekcsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLG9CQUFvQixFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsRUFBQztnQkFDM0gsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFDO2dCQUNqRyxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUM7Z0JBQy9GLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsRUFBQzthQUM5RyxDQUFDO1FBQ04sQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEtBQUssY0FBYyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsS0FBSyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDMUgsT0FBTyxHQUFHO2dCQUNOLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBQztnQkFDL0YsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxFQUFDO2dCQUNyRyxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUM7Z0JBQy9GLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsRUFBQzthQUM5RyxDQUFDO1lBRUYsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLENBQUM7Z0JBQ3JDLE9BQU8sR0FBRztvQkFDTixFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLEVBQUM7b0JBQ3ZGLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBQztpQkFDaEcsQ0FBQztZQUNOLENBQUM7UUFDTCxDQUFDO2FBQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsS0FBSyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDNUQsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLHFCQUFxQixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQzFHLE9BQU8sR0FBRztvQkFDTixFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUM7b0JBQy9GLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsRUFBQztvQkFDckcsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLGlCQUFpQixFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsaUJBQWlCLENBQUMsRUFBQztvQkFDckgsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLG9CQUFvQixFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsRUFBQztvQkFDM0gsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFDO29CQUNqRyxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUM7b0JBQy9GLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsRUFBQztpQkFDOUcsQ0FBQztZQUNOLENBQUM7aUJBQU0sQ0FBQztnQkFDSixPQUFPLEdBQUc7b0JBQ04sRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFDO29CQUMvRixFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFDO29CQUNySCxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsb0JBQW9CLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFDO29CQUMzSCxFQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLEVBQUM7b0JBQ2pHLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBQztvQkFDL0YsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxFQUFDO2lCQUM5RyxDQUFDO1lBQ04sQ0FBQztRQUNMLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDN0IsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQVksRUFBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFBLENBQUMsQ0FBQztRQUN4SCxDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ1gsSUFBSSwwQkFBMEIsR0FBeUIsU0FBUyxDQUFDO1lBQ2pFLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDNUIsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUM7WUFDOUUsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLDBCQUEwQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDO1lBQ2pGLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUNuQywwQkFBMEIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQztZQUM5RSxDQUFDO1lBRUQsSUFBSSwwQkFBMEIsRUFBRSxDQUFDO2dCQUM3QixPQUFPLEdBQUcsMEJBQTBCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pILENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFTyxtQkFBbUI7UUFDdkIsSUFBSSxnQkFBZ0IsR0FBZ0MsZUFBZSxDQUFDLFFBQVEsQ0FBQztRQUM3RSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssTUFBTTtZQUFFLGdCQUFnQixHQUFHLGVBQWUsQ0FBQyxVQUFVLENBQUM7YUFDeEUsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVM7WUFBRSxnQkFBZ0IsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDO2FBQzVFLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxNQUFNO1lBQUUsZ0JBQWdCLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQzthQUN6RSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssUUFBUTtZQUFFLGdCQUFnQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUM7UUFFMUksMkNBQTJDO1FBQzNDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ25DLGdCQUFnQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUM7UUFDeEQsQ0FBQztRQUVELGdDQUFnQztRQUNoQyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssZ0JBQWdCLENBQUMsRUFBRSxDQUFDO1lBQzdGLGdCQUFnQixHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDbEQsQ0FBQztRQUVELE9BQU8sZ0JBQWdCLENBQUM7SUFDNUIsQ0FBQztJQUVPLG9CQUFvQixDQUFDLElBQW1CO1FBQzVDLE1BQU0sUUFBUSxHQUFrQixJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFFeEQsSUFBSSxRQUFRO1lBQUUsT0FBTyxVQUFVLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQzs7WUFDNUgsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDO0lBQ3RELENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxJQUFtQjtRQUM1QyxNQUFNLFFBQVEsR0FBa0IsSUFBSSxDQUFDLHNCQUFzQixDQUFDO1FBRTVELElBQUksUUFBUTtZQUFFLE9BQU8sVUFBVSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsMkJBQTJCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7O1lBQzVILE9BQU8sSUFBSSxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQztJQUNyRCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsS0FBVTtRQUMvQixPQUFPLENBQUMsQ0FDSixJQUFJLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDcEMsSUFBSSxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDakQsSUFBSSxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDL0MsVUFBVSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLDRCQUE0QixDQUFDO1lBQy9ELFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsNEJBQTRCLENBQUM7WUFDN0UsVUFBVSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLCtCQUErQixDQUFDO1lBQ2xFLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsK0JBQStCLENBQUMsQ0FDbkYsQ0FBQztJQUNOLENBQUM7SUFFTyx5QkFBeUI7UUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQzlCLE1BQU0sY0FBYyxHQUFRLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO1lBRXZGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFO2dCQUMvRSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQzNFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDdkIsQ0FBQztnQkFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUMzQixDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7SUFDTCxDQUFDO0lBRU8sMkJBQTJCO1FBQy9CLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQztZQUNsQyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUMzQixDQUFDO0lBQ0wsQ0FBQztJQUVPLDBCQUEwQjtRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRTtnQkFDM0UsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQztvQkFDdkQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUN2QixDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDO0lBQ0wsQ0FBQztJQUVPLDRCQUE0QjtRQUNoQyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7UUFDdkMsQ0FBQztJQUNMLENBQUM7SUFFTyxrQkFBa0I7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksNkJBQTZCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsR0FBRyxFQUFFO2dCQUNsRixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDO29CQUN4QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3ZCLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7UUFFRCxJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDNUMsQ0FBQztJQUVPLG9CQUFvQjtRQUN4QixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDOUMsQ0FBQztJQUNMLENBQUM7SUFFTyxXQUFXO1FBQ2YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8sYUFBYTtRQUNqQixJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztRQUNwQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztJQUN4QixDQUFDO0lBRU8saUJBQWlCLENBQUMsS0FBVTtRQUNoQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEVBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVPLGNBQWM7UUFDbEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVPLG9CQUFvQixDQUFDLEtBQUssR0FBRyxLQUFLO1FBQ3RDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDUixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ3BELElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFDLENBQUM7UUFDMUYsQ0FBQztRQUVELGlDQUFpQztRQUNqQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUQsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFDLENBQUM7YUFBTSxDQUFDO1lBQ0osSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7SUFDTCxDQUFDO0lBRU8sbUJBQW1CLENBQUMsUUFBOEI7UUFDdEQsSUFBSSxTQUFTLEdBQUcsUUFBUSxFQUFFLFNBQVMsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUNsRSxJQUFJLFlBQVksR0FBRyxRQUFRLEVBQUUsS0FBSyxDQUFDO1FBQ25DLElBQUksZ0JBQWdCLEdBQUcsU0FBUyxDQUFDO1FBRWpDLHFHQUFxRztRQUNyRyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxLQUFLLGNBQWMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMscUJBQXFCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUMvSixJQUNJLFNBQVMsS0FBSyxlQUFlLENBQUMsT0FBTztnQkFDckMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDO2dCQUM5QixRQUFRLEVBQUUsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO2dCQUM1QixRQUFRLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsWUFBWSxJQUFJLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxFQUNqRyxDQUFDO2dCQUNDLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBMkIsQ0FBQyxDQUFDO2dCQUMvRSxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQTJCLENBQUMsQ0FBQztnQkFFN0UsMEJBQTBCO2dCQUMxQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFFOUcsSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsS0FBSyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO29CQUN4RSxnQkFBZ0IsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDO29CQUMxQyxZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMvQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxJQUFJLFNBQVMsS0FBSyxlQUFlLENBQUMsTUFBTSxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDO2dCQUNsRSxTQUFTLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQztZQUN4QyxDQUFDO1FBQ0wsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEtBQUssY0FBYyxDQUFDLElBQUksSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNyRSwrREFBK0Q7WUFDL0QsWUFBWSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO2dCQUN0QyxDQUFDLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqRSxDQUFDLENBQUMsWUFBWSxZQUFZLElBQUk7b0JBQzVCLENBQUMsQ0FBQyxZQUFZO29CQUNkLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBRUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQztZQUN0QixTQUFTO1lBQ1QsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLO1lBQ3RCLGdCQUFnQjtZQUNoQixZQUFZLEVBQUUsWUFBWSxJQUFJLElBQUk7U0FDckMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRyxDQUFDO0lBQ3hFLENBQUM7OEdBN3BCUSw4QkFBOEI7a0dBQTlCLDhCQUE4Qiw0TkM1RTNDLG9pUkEwSkEsMkNEeEdRLFdBQVcsOEJBQ1gsZUFBZSw0RkFDZixrQkFBa0IscUpBQ2xCLGNBQWMsMHpDQUNkLFdBQVcsK1ZBQ1gscUJBQXFCLDRYQUNyQixpQkFBaUIsdVlBQ2pCLHNCQUFzQix3VUFDdEIsaUJBQWlCLHl2QkFDakIsZUFBZSx5SEFDZixVQUFVLHVEQUNWLGVBQWUsNERBQ2YsT0FBTyxvRkFDUCxrQkFBa0IscUZBQ2xCLG9CQUFvQixnTEFHWjtZQUNSLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRTtnQkFDeEIsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLGlDQUFpQyxDQUFDLENBQUMsQ0FBQztnQkFDakgsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLEVBQUMsT0FBTyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3JFLENBQUM7U0FDTDs7MkZBSVEsOEJBQThCO2tCQTlCMUMsU0FBUztpQ0FDTSxJQUFJLFlBQ04sOEJBQThCLFdBQy9CO3dCQUNMLFdBQVc7d0JBQ1gsZUFBZTt3QkFDZixrQkFBa0I7d0JBQ2xCLGNBQWM7d0JBQ2QsV0FBVzt3QkFDWCxxQkFBcUI7d0JBQ3JCLGlCQUFpQjt3QkFDakIsc0JBQXNCO3dCQUN0QixpQkFBaUI7d0JBQ2pCLGVBQWU7d0JBQ2YsVUFBVTt3QkFDVixlQUFlO3dCQUNmLE9BQU87d0JBQ1Asa0JBQWtCO3dCQUNsQixvQkFBb0I7cUJBQ3ZCLGNBRVc7d0JBQ1IsT0FBTyxDQUFDLGtCQUFrQixFQUFFOzRCQUN4QixVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsaUNBQWlDLENBQUMsQ0FBQyxDQUFDOzRCQUNqSCxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7eUJBQ3JFLENBQUM7cUJBQ0wsaUJBQ2MsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTTt3REFnQnRCLFVBQVU7c0JBQWxDLEtBQUs7dUJBQUMsRUFBQyxRQUFRLEVBQUUsSUFBSSxFQUFDO2dCQUVKLElBQUk7c0JBQXRCLFNBQVM7dUJBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YW5pbWF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXJ9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHtOZ0NsYXNzfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgRGVzdHJveVJlZixcbiAgICBFbGVtZW50UmVmLFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgUmVuZGVyZXIyLFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgICBjb21wdXRlZCxcbiAgICBlZmZlY3QsXG4gICAgaW5qZWN0LFxuICAgIHNpZ25hbFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7dGFrZVVudGlsRGVzdHJveWVkfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge0Zvcm1zTW9kdWxlfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7VHJhbnNsYXRlTW9kdWxlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7T3ZlcmxheVNlcnZpY2UsIEZpbHRlck1ldGFkYXRhIGFzIFByaW1lRmlsdGVyTWV0YWRhdGEsIFByaW1lTkdDb25maWcsIFNlbGVjdEl0ZW0sIFRyYW5zbGF0aW9uS2V5c30gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHtDYWxlbmRhck1vZHVsZX0gZnJvbSAncHJpbWVuZy9jYWxlbmRhcic7XG5pbXBvcnQge0Nvbm5lY3RlZE92ZXJsYXlTY3JvbGxIYW5kbGVyLCBEb21IYW5kbGVyfSBmcm9tICdwcmltZW5nL2RvbSc7XG5pbXBvcnQge0ZpbHRlckljb259IGZyb20gJ3ByaW1lbmcvaWNvbnMvZmlsdGVyJztcbmltcG9ydCB7RmlsdGVyU2xhc2hJY29ufSBmcm9tICdwcmltZW5nL2ljb25zL2ZpbHRlcnNsYXNoJztcbmltcG9ydCB7SW5wdXROdW1iZXJNb2R1bGV9IGZyb20gJ3ByaW1lbmcvaW5wdXRudW1iZXInO1xuaW1wb3J0IHtJbnB1dFRleHRNb2R1bGV9IGZyb20gJ3ByaW1lbmcvaW5wdXR0ZXh0JztcbmltcG9ydCB7VGFibGUsIFRhYmxlTW9kdWxlfSBmcm9tICdwcmltZW5nL3RhYmxlJztcbmltcG9ydCB7VHJpU3RhdGVDaGVja2JveE1vZHVsZX0gZnJvbSAncHJpbWVuZy90cmlzdGF0ZWNoZWNrYm94JztcbmltcG9ydCB7TnVsbGFibGUsIFZvaWRMaXN0ZW5lcn0gZnJvbSAncHJpbWVuZy90cy1oZWxwZXJzJztcbmltcG9ydCB7WkluZGV4VXRpbHN9IGZyb20gJ3ByaW1lbmcvdXRpbHMnO1xuaW1wb3J0IHtTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWR9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge0NPTU1PTlNfTU9EVUxFX0NPTkZJR19JVCwgRmlsdGVyTWF0Y2hNb2RlLCBGaWx0ZXJNYXRjaE1vZGVFeHRlbmRlZFR5cGUsIGRhdGVUb0lzb1N0cmluZ30gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy9jb3JlJztcbmltcG9ydCB7RmlsdGVyRGVzY3JpcHRvciwgRmlsdGVyTG9va3VwRGVzY3JpcHRvciwgRmlsdGVyTG9va3VwVHlwZUVudW0sIEZpbHRlclR5cGVFbnVtfSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL2ZpbHRlcic7XG5pbXBvcnQge0F1dG9jb21wbGV0ZUNvbXBvbmVudCwgRGF0ZVJhbmdlQ29tcG9uZW50LCBEcm9wZG93bkNvbXBvbmVudCwgSW5wdXRUcmltRGlyZWN0aXZlLCBOdW1iZXJSYW5nZUNvbXBvbmVudH0gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy9mb3JtJztcblxuaW1wb3J0IHtEYXRhTGlzdFNlcnZpY2V9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2RhdGEtbGlzdC5zZXJ2aWNlJztcblxuLyoqXG4gKiBDYW5ub3QgYmUgb24gcHVzaCBjaGFuZ2UgZGV0ZWN0aW9uIHN0cmF0ZWd5IGJlY2F1c2Ugb2YgZmlsdGVyIHVwZGF0ZXMgdHJpZ2dlcmVkIGZyb20gcm91dGUgd2hpY2ggY2F1c2VzIHRvIGZvcmNlIHVwZGF0ZSB2YWx1ZXMgaW4gZm9yY2UgbWV0YWRhdGFcbiAqIGFuZCB0aGVzZSBtdXN0IGJlIHByb3BhZ2F0ZWQgdGhyb3VnaCB0byB0aGlzIGNvbXBvbmVudCBhbmQgYmV5b25kIHRvIHByaW1lTkcuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdtbmctdGFibGUtY29sdW1uLWZpbHRlci1mdWxsJyxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIFRhYmxlTW9kdWxlLFxuICAgICAgICBUcmFuc2xhdGVNb2R1bGUsXG4gICAgICAgIERhdGVSYW5nZUNvbXBvbmVudCxcbiAgICAgICAgQ2FsZW5kYXJNb2R1bGUsXG4gICAgICAgIEZvcm1zTW9kdWxlLFxuICAgICAgICBBdXRvY29tcGxldGVDb21wb25lbnQsXG4gICAgICAgIERyb3Bkb3duQ29tcG9uZW50LFxuICAgICAgICBUcmlTdGF0ZUNoZWNrYm94TW9kdWxlLFxuICAgICAgICBJbnB1dE51bWJlck1vZHVsZSxcbiAgICAgICAgSW5wdXRUZXh0TW9kdWxlLFxuICAgICAgICBGaWx0ZXJJY29uLFxuICAgICAgICBGaWx0ZXJTbGFzaEljb24sXG4gICAgICAgIE5nQ2xhc3MsXG4gICAgICAgIElucHV0VHJpbURpcmVjdGl2ZSxcbiAgICAgICAgTnVtYmVyUmFuZ2VDb21wb25lbnRcbiAgICBdLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jb2x1bW4tZmlsdGVyLWZ1bGwuY29tcG9uZW50Lmh0bWwnLFxuICAgIGFuaW1hdGlvbnM6IFtcbiAgICAgICAgdHJpZ2dlcignb3ZlcmxheUFuaW1hdGlvbicsIFtcbiAgICAgICAgICAgIHRyYW5zaXRpb24oJzplbnRlcicsIFtzdHlsZSh7b3BhY2l0eTogMCwgdHJhbnNmb3JtOiAnc2NhbGVZKDAuOCknfSksIGFuaW1hdGUoJy4xMnMgY3ViaWMtYmV6aWVyKDAsIDAsIDAuMiwgMSknKV0pLFxuICAgICAgICAgICAgdHJhbnNpdGlvbignOmxlYXZlJywgW2FuaW1hdGUoJy4xcyBsaW5lYXInLCBzdHlsZSh7b3BhY2l0eTogMH0pKV0pXG4gICAgICAgIF0pXG4gICAgXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFRhYmxlQ29sdW1uRmlsdGVyRnVsbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgbG9va3VwVHlwZURyb3Bkb3duOiBGaWx0ZXJMb29rdXBUeXBlRW51bSA9IEZpbHRlckxvb2t1cFR5cGVFbnVtLkRyb3Bkb3duO1xuICAgIHB1YmxpYyByZWFkb25seSBsb29rdXBUeXBlQXV0b2NvbXBsZXRlOiBGaWx0ZXJMb29rdXBUeXBlRW51bSA9IEZpbHRlckxvb2t1cFR5cGVFbnVtLkF1dG9jb21wbGV0ZTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVsID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJpbWVUYWJsZSA9IGluamVjdChUYWJsZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkYXRhTGlzdFNlcnZpY2UgPSBpbmplY3QoRGF0YUxpc3RTZXJ2aWNlPGFueT4pO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbW9kdWxlQ29uZmlnID0gaW5qZWN0KENPTU1PTlNfTU9EVUxFX0NPTkZJR19JVCwge29wdGlvbmFsOiB0cnVlfSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSByZW5kZXJlciA9IGluamVjdChSZW5kZXJlcjIpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJpbWVDb25maWcgPSBpbmplY3QoUHJpbWVOR0NvbmZpZyk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBvdmVybGF5U2VydmljZSA9IGluamVjdChPdmVybGF5U2VydmljZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBjZCA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQ6IERvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuXG4gICAgQElucHV0KHtyZXF1aXJlZDogdHJ1ZX0pIGRlc2NyaXB0b3IhOiBGaWx0ZXJEZXNjcmlwdG9yPGFueSwgYW55PjtcblxuICAgIEBWaWV3Q2hpbGQoJ2ljb24nKSBpY29uOiBOdWxsYWJsZTxFbGVtZW50UmVmPjtcblxuICAgIC8vIGNoYW5nZSBvbmx5IG9uIGluaXQhXG4gICAgcHVibGljIHByaW1lRmllbGQhOiBzdHJpbmc7XG4gICAgcHVibGljIHByaW1lVHlwZSA9ICd0ZXh0JztcbiAgICBwdWJsaWMgbG9va3VwRGVzY3JpcHRvcj86IEZpbHRlckxvb2t1cERlc2NyaXB0b3I8YW55LCBhbnk+O1xuXG4gICAgLy8gcHVibGljIG1hdGNoTW9kZXM6IFNlbGVjdEl0ZW1bXSA9IFtdO1xuICAgIHB1YmxpYyBtYXRjaE1vZGVzID0gc2lnbmFsPFNlbGVjdEl0ZW1bXT4oW10pO1xuICAgIHB1YmxpYyBmaWx0ZXJDb25zdHJhaW50ID0gc2lnbmFsPEZpbHRlck1ldGFkYXRhIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICAgIHB1YmxpYyBpc0ZpbHRlclNldCA9IGNvbXB1dGVkKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgICAgdGhpcy5maWx0ZXJDb25zdHJhaW50KCk/Lm1hdGNoTW9kZSA9PT0gRmlsdGVyTWF0Y2hNb2RlLkV4aXN0cyB8fFxuICAgICAgICAgICAgdGhpcy5maWx0ZXJDb25zdHJhaW50KCk/Lm1hdGNoTW9kZSA9PT0gRmlsdGVyTWF0Y2hNb2RlLkRvZXNOb3RFeGlzdCB8fFxuICAgICAgICAgICAgIXRoaXMucHJpbWVUYWJsZS5pc0ZpbHRlckJsYW5rKHRoaXMuZmlsdGVyQ29uc3RyYWludCgpPy52YWx1ZSlcbiAgICApO1xuICAgIHB1YmxpYyBpc0lucHV0RGlzYWJsZWQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmZpbHRlckNvbnN0cmFpbnQoKT8ubWF0Y2hNb2RlID09PSBGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzIHx8IHRoaXMuZmlsdGVyQ29uc3RyYWludCgpPy5tYXRjaE1vZGUgPT09IEZpbHRlck1hdGNoTW9kZS5Eb2VzTm90RXhpc3QpO1xuICAgIHB1YmxpYyBvdmVybGF5VmlzaWJsZSA9IHNpZ25hbChmYWxzZSk7XG5cbiAgICBwcml2YXRlIG92ZXJsYXlTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBvdmVybGF5OiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCB8IG51bGw7XG4gICAgcHJpdmF0ZSBzY3JvbGxIYW5kbGVyPzogQ29ubmVjdGVkT3ZlcmxheVNjcm9sbEhhbmRsZXIgfCBudWxsO1xuICAgIHByaXZhdGUgZG9jdW1lbnRDbGlja0xpc3RlbmVyOiBWb2lkTGlzdGVuZXI7XG4gICAgcHJpdmF0ZSBkb2N1bWVudFJlc2l6ZUxpc3RlbmVyOiBWb2lkTGlzdGVuZXI7XG4gICAgcHJpdmF0ZSB0cmFuc2xhdGlvblN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcbiAgICBwcml2YXRlIHJlc2V0U3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgc2VsZkNsaWNrPzogYm9vbGVhbjtcbiAgICBwcml2YXRlIG92ZXJsYXlFdmVudExpc3RlbmVyOiBhbnk7XG4gICAgcHJpdmF0ZSB0YWJsZUZpbHRlck1ldGFkYXRhU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSB3aW5kb3cgPSB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3IGFzIFdpbmRvdztcblxuICAgIHByaXZhdGUgbnVtZXJpY1ZhbHVlRnJvbU1vZGVsQ2hhbmdlOiBudW1iZXIgfCBudW1iZXJbXSB8IG51bGwgPSBudWxsO1xuXG4gICAgcHJpdmF0ZSBkYXRlRGVib3VuY2VTdWJqZWN0ID0gbmV3IFN1YmplY3Q8RGF0ZSB8IERhdGVbXSB8IG51bGw+KCk7XG4gICAgcHJpdmF0ZSBkYXRlVGltZUluVXRjID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBkYXRlVGltZVdpdGhUaW1lem9uZSA9IHRydWU7XG4gICAgcHJpdmF0ZSBkYXRlVGltZVdpdGhNaWxsaXMgPSB0cnVlO1xuICAgIHByaXZhdGUgZGF0ZU9ubHlEaXNhYmxlZCA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZGF0ZURlYm91bmNlU3ViamVjdC5waXBlKGRlYm91bmNlVGltZSg1MDApLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLCB0YWtlVW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKHYgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZmlsdGVyQ29uc3RyYWludCgpPy5kaXNwbGF5TWF0Y2hNb2RlID09PSBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzICYmIHRoaXMuZmlsdGVyQ29uc3RyYWludCgpPy5tYXRjaE1vZGUgPT09IEZpbHRlck1hdGNoTW9kZS5CZXR3ZWVuICYmIHYgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRlVmFsdWU6IERhdGUgfCB1bmRlZmluZWQgPSBBcnJheS5pc0FycmF5KHYpID8gdlswXSA6IHY7IC8vIGNvdWxkIGhhdmUgZW1wdHkgYXJyYXlcblxuICAgICAgICAgICAgICAgIGlmIChkYXRlVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnJvbURhdGUgPSBuZXcgRGF0ZShkYXRlVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0b0RhdGUgPSBuZXcgRGF0ZShkYXRlVmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3IuZGF0ZVBpY2tlclNob3dUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZXNjcmlwdG9yLmRhdGVQaWNrZXJTaG93U2Vjb25kcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21EYXRlLnNldE1pbGxpc2Vjb25kcygwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b0RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21EYXRlLnNldFNlY29uZHMoMCwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9EYXRlLnNldFNlY29uZHMoNTksIDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZnJvbURhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b0RhdGUuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBhZGp1c3QgdG8gc2V0dGluZ3NcbiAgICAgICAgICAgICAgICAgICAgdiA9IFtmcm9tRGF0ZSwgdG9EYXRlXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb252ZXJ0RGF0ZVR5cGUgPSB0aGlzLmRlc2NyaXB0b3IuZGF0ZVBpY2tlclZhbHVlTm9UaW1lIHx8ICghdGhpcy5kYXRlT25seURpc2FibGVkICYmICF0aGlzLmRlc2NyaXB0b3IuZGF0ZVBpY2tlclNob3dUaW1lKSA/ICdkYXRlJyA6ICdkYXRlLXRpbWUnO1xuICAgICAgICAgICAgY29uc3QgY29udmVydERhdGVUaW1lT3B0cyA9IHtcbiAgICAgICAgICAgICAgICB1dGM6IHRoaXMuZGVzY3JpcHRvci5kYXRlUGlja2VyVmFsdWVVdGMgPz8gdGhpcy5kYXRlVGltZUluVXRjLFxuICAgICAgICAgICAgICAgIG5vTWlsbGlzOiAhdGhpcy5kYXRlVGltZVdpdGhNaWxsaXMsXG4gICAgICAgICAgICAgICAgbm9UaW1lem9uZTogdGhpcy5kZXNjcmlwdG9yLmRhdGVQaWNrZXJWYWx1ZU5vVGltZXpvbmUgPz8gIXRoaXMuZGF0ZVRpbWVXaXRoVGltZXpvbmVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUZpbHRlclZhbHVlKFxuICAgICAgICAgICAgICAgIHYgPT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHZcbiAgICAgICAgICAgICAgICAgICAgOiBBcnJheS5pc0FycmF5KHYpXG4gICAgICAgICAgICAgICAgICAgICAgPyB2LmZpbHRlcihpID0+IGkgIT0gbnVsbCkubWFwKGkgPT4gZGF0ZVRvSXNvU3RyaW5nKGksIGNvbnZlcnREYXRlVHlwZSwgY29udmVydERhdGVUaW1lT3B0cykpXG4gICAgICAgICAgICAgICAgICAgICAgOiBkYXRlVG9Jc29TdHJpbmcodiwgY29udmVydERhdGVUeXBlLCBjb252ZXJ0RGF0ZVRpbWVPcHRzKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkRmlsdGVyTWV0YSA9IHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmZpbHRlck1ldGEoKVt0aGlzLnByaW1lRmllbGRdO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgZmllbGRGaWx0ZXJNZXRhICYmXG4gICAgICAgICAgICAgICAgICAgICghdGhpcy5maWx0ZXJDb25zdHJhaW50KCkgfHwgdGhpcy5maWx0ZXJDb25zdHJhaW50KCkhLnZhbHVlICE9PSBmaWVsZEZpbHRlck1ldGEudmFsdWUgfHwgdGhpcy5maWx0ZXJDb25zdHJhaW50KCkhLm1hdGNoTW9kZSAhPT0gZmllbGRGaWx0ZXJNZXRhLm1hdGNoTW9kZSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRGaWx0ZXJDb25zdHJhaW50KGZpZWxkRmlsdGVyTWV0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMubW9kdWxlQ29uZmlnPy5zZXJpYWxpemF0aW9uKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5tb2R1bGVDb25maWcuc2VyaWFsaXphdGlvbi5kYXRlVGltZUluVXRjICE9PSB1bmRlZmluZWQpIHRoaXMuZGF0ZVRpbWVJblV0YyA9IHRoaXMubW9kdWxlQ29uZmlnLnNlcmlhbGl6YXRpb24uZGF0ZVRpbWVJblV0YztcbiAgICAgICAgICAgIGlmICh0aGlzLm1vZHVsZUNvbmZpZy5zZXJpYWxpemF0aW9uLmRhdGVUaW1lV2l0aFRpbWV6b25lICE9PSB1bmRlZmluZWQpIHRoaXMuZGF0ZVRpbWVXaXRoVGltZXpvbmUgPSB0aGlzLm1vZHVsZUNvbmZpZy5zZXJpYWxpemF0aW9uLmRhdGVUaW1lV2l0aFRpbWV6b25lO1xuICAgICAgICAgICAgaWYgKHRoaXMubW9kdWxlQ29uZmlnLnNlcmlhbGl6YXRpb24uZGF0ZVRpbWVXaXRoTWlsbGlzICE9PSB1bmRlZmluZWQpIHRoaXMuZGF0ZVRpbWVXaXRoTWlsbGlzID0gdGhpcy5tb2R1bGVDb25maWcuc2VyaWFsaXphdGlvbi5kYXRlVGltZVdpdGhNaWxsaXM7XG4gICAgICAgICAgICBpZiAodGhpcy5tb2R1bGVDb25maWcuc2VyaWFsaXphdGlvbi5maWx0ZXJzRGF0ZU9ubHlEaXNhYmxlZCAhPT0gdW5kZWZpbmVkKSB0aGlzLmRhdGVPbmx5RGlzYWJsZWQgPSB0aGlzLm1vZHVsZUNvbmZpZy5zZXJpYWxpemF0aW9uLmZpbHRlcnNEYXRlT25seURpc2FibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wcmltZUZpZWxkID0gdGhpcy5kZXNjcmlwdG9yLnByb3BlcnR5O1xuXG4gICAgICAgIHN3aXRjaCAodGhpcy5kZXNjcmlwdG9yLmZpbHRlclR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgRmlsdGVyVHlwZUVudW0uQm9vbGVhbjpcbiAgICAgICAgICAgICAgICB0aGlzLnByaW1lVHlwZSA9ICdib29sZWFuJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRmlsdGVyVHlwZUVudW0uTnVtYmVyOlxuICAgICAgICAgICAgICAgIHRoaXMucHJpbWVUeXBlID0gJ251bWVyaWMnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGaWx0ZXJUeXBlRW51bS5EYXRlOlxuICAgICAgICAgICAgICAgIHRoaXMucHJpbWVUeXBlID0gJ2RhdGUnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGaWx0ZXJUeXBlRW51bS5Mb29rdXA6XG4gICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLkxvb2t1cEVudW06XG4gICAgICAgICAgICAgICAgdGhpcy5wcmltZVR5cGUgPSAnbG9va3VwJztcbiAgICAgICAgICAgICAgICB0aGlzLmxvb2t1cERlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3IgYXMgRmlsdGVyTG9va3VwRGVzY3JpcHRvcjxhbnksIGFueT47XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLlN0cmluZzpcbiAgICAgICAgICAgICAgICB0aGlzLnByaW1lVHlwZSA9ICd0ZXh0JztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGdlbmVyYXRlIG1hdGNoIG1vZGUgb3B0aW9uc1xuICAgICAgICB0aGlzLnRyYW5zbGF0aW9uU3Vic2NyaXB0aW9uID0gdGhpcy5wcmltZUNvbmZpZy50cmFuc2xhdGlvbk9ic2VydmVyLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlTWF0Y2hNb2RlT3B0aW9ucygpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZU1hdGNoTW9kZU9wdGlvbnMoKTtcblxuICAgICAgICB0aGlzLmluaXRGaWx0ZXJDb25zdHJhaW50KCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIGlmICh0aGlzLm92ZXJsYXkpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5lbC5uYXRpdmVFbGVtZW50LCB0aGlzLm92ZXJsYXkpO1xuICAgICAgICAgICAgWkluZGV4VXRpbHMuY2xlYXIodGhpcy5vdmVybGF5KTtcbiAgICAgICAgICAgIHRoaXMub25PdmVybGF5SGlkZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50cmFuc2xhdGlvblN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5yZXNldFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5vdmVybGF5U3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLnRhYmxlRmlsdGVyTWV0YWRhdGFTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbiAgICBvblRleHRNb2RlbENoYW5nZShldmVudDogRXZlbnQpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlO1xuICAgICAgICBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUZpbHRlclZhbHVlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXR5cGVzXG4gICAgb25UZXh0SW5wdXRFbnRlcktleURvd24oZXZlbnQ6IEV2ZW50KSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVGaWx0ZXJWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbiAgICBvbk51bWVyaWNNb2RlbENoYW5nZSh2YWx1ZTogbnVtYmVyIHwgbnVsbCkge1xuICAgICAgICB0aGlzLm51bWVyaWNWYWx1ZUZyb21Nb2RlbENoYW5nZSA9IHZhbHVlO1xuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRmlsdGVyVmFsdWUodmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbiAgICBvbk51bWVyaWNJbnB1dEtleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuZmlsdGVyQ29uc3RyYWludCgpPy5kaXNwbGF5TWF0Y2hNb2RlID09PSBGaWx0ZXJNYXRjaE1vZGUuQmV0d2VlbiAmJiBBcnJheS5pc0FycmF5KHRoaXMubnVtZXJpY1ZhbHVlRnJvbU1vZGVsQ2hhbmdlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlclZhbHVlcyA9IHRoaXMubnVtZXJpY1ZhbHVlRnJvbU1vZGVsQ2hhbmdlLmZpbHRlcih2ID0+IHR5cGVvZiB2ID09PSAnbnVtYmVyJyk7XG4gICAgICAgICAgICAgICAgaWYgKG51bWJlclZhbHVlcy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudXBkYXRlRmlsdGVyVmFsdWUodGhpcy5udW1lcmljVmFsdWVGcm9tTW9kZWxDaGFuZ2UpO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXR5cGVzXG4gICAgb25UcmlzdGF0ZU1vZGVsQ2hhbmdlKHZhbHVlOiBib29sZWFuIHwgbnVsbCkge1xuICAgICAgICB0aGlzLnVwZGF0ZUZpbHRlclZhbHVlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10eXBlc1xuICAgIG9uRGF0ZUZpbHRlck1vZGVsQ2hhbmdlKHZhbHVlOiBEYXRlIHwgRGF0ZVtdIHwgbnVsbCkge1xuICAgICAgICBpZiAodGhpcy5maWx0ZXJDb25zdHJhaW50KCk/LmRpc3BsYXlNYXRjaE1vZGUgPT09IEZpbHRlck1hdGNoTW9kZS5CZXR3ZWVuICYmIEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlVmFsdWVzID0gdmFsdWUuZmlsdGVyKHYgPT4gdiBpbnN0YW5jZW9mIERhdGUpO1xuICAgICAgICAgICAgaWYgKGRhdGVWYWx1ZXMubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGF0ZURlYm91bmNlU3ViamVjdC5uZXh0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10eXBlc1xuICAgIGF1dG9jb21wbGV0ZUZpbHRlcih2YWx1ZTogYW55KSB7XG4gICAgICAgIHRoaXMudXBkYXRlRmlsdGVyVmFsdWUodmFsdWUpO1xuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXR5cGVzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgZHJvcGRvd25GaWx0ZXIodmFsdWU6IGFueSkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUZpbHRlclZhbHVlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBvbk1hdGNoTW9kZUNoYW5nZShkaXNwbGF5TWF0Y2hNb2RlOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNEaXNwbGF5TWF0Y2hNb2RlID0gdGhpcy5maWx0ZXJDb25zdHJhaW50KCk/LmRpc3BsYXlNYXRjaE1vZGU7XG4gICAgICAgIGxldCB2YWx1ZSA9IHRoaXMuZmlsdGVyQ29uc3RyYWludCgpPy5kaXNwbGF5VmFsdWU7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiBwcmV2aW91c0Rpc3BsYXlNYXRjaE1vZGUgJiYgZGlzcGxheU1hdGNoTW9kZSAhPT0gcHJldmlvdXNEaXNwbGF5TWF0Y2hNb2RlKSB7XG4gICAgICAgICAgICAvLyBoYW5kbGUgdmFsdWVzIG9uIG1hdGNoIG1vZGUgY2hhbmdlc1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hNb2Rlc1dpdGhBcnJheVZhbHVlczogc3RyaW5nW10gPSBbRmlsdGVyTWF0Y2hNb2RlLkJldHdlZW4sIEZpbHRlck1hdGNoTW9kZS5JbiwgRmlsdGVyTWF0Y2hNb2RlLk5vdEluXTtcblxuICAgICAgICAgICAgaWYgKG1hdGNoTW9kZXNXaXRoQXJyYXlWYWx1ZXMuaW5kZXhPZihwcmV2aW91c0Rpc3BsYXlNYXRjaE1vZGUpID49IDAgJiYgbWF0Y2hNb2Rlc1dpdGhBcnJheVZhbHVlcy5pbmRleE9mKGRpc3BsYXlNYXRjaE1vZGUpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIC8vIGZyb20gYXJyYXkgdmFsdWVzIHRvIG5vbi1hcnJheSB2YWx1ZXNcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZT8uWzBdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hNb2Rlc1dpdGhBcnJheVZhbHVlcy5pbmRleE9mKHByZXZpb3VzRGlzcGxheU1hdGNoTW9kZSkgPT09IC0xICYmIGRpc3BsYXlNYXRjaE1vZGUgPT09IEZpbHRlck1hdGNoTW9kZS5CZXR3ZWVuKSB7XG4gICAgICAgICAgICAgICAgLy8gZnJvbSBub24tYXJyYXkgdmFsdWVzIHRvIGJldHdlZW5cbiAgICAgICAgICAgICAgICAvLyBpdCBjYW4gYWxyZWFkeSBiZSBhbiBhcnJheSBiZWNhdXNlIG9mIFwiZmFrZVwiIGVxdWFscyBmb3IgZGF0ZXMgd2l0aCB0aW1lc3RhbXBzICh0aGF0IGlzIGFjdHVhbGx5IGJldHdlZW4pXG4gICAgICAgICAgICAgICAgY29uc3QgZnJvbVZhbHVlID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZVswXSA6IHZhbHVlO1xuICAgICAgICAgICAgICAgIC8vIGZvciB0byB2YWx1ZSwgYWRkIDEgZGF5IChpZiBkYXRlKSBvciAxIChpZiBudW1iZXIpXG4gICAgICAgICAgICAgICAgY29uc3QgdG9WYWx1ZSA9IGZyb21WYWx1ZSBpbnN0YW5jZW9mIERhdGUgPyBuZXcgRGF0ZShmcm9tVmFsdWUuZ2V0VGltZSgpICsgMjQgKiAzNjAwICogMTAwMCkgOiB0eXBlb2YgZnJvbVZhbHVlID09PSAnbnVtYmVyJyA/IGZyb21WYWx1ZSArIDEgOiBmcm9tVmFsdWU7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBbZnJvbVZhbHVlLCB0b1ZhbHVlXTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hNb2Rlc1dpdGhBcnJheVZhbHVlcy5pbmRleE9mKHByZXZpb3VzRGlzcGxheU1hdGNoTW9kZSkgPj0gMCAmJiBkaXNwbGF5TWF0Y2hNb2RlID09PSBGaWx0ZXJNYXRjaE1vZGUuQmV0d2Vlbikge1xuICAgICAgICAgICAgICAgIC8vIGZyb20gYXJyYXkgdmFsdWVzIHRvIGJldHdlZW5cbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlWzBdLCB2YWx1ZVsxXV07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFt2YWx1ZVswXSwgdmFsdWVbMF1dO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBmaWx0ZXJzIHdpdGggZXF1YWxzIG9uIGRhdGVzIHdpdGggdGltZXpvbmVzIGFyZSBleHRyYSwgYmVjYXVzZSBkb3VibGUgdmFsdWUgbmVlZHMgdG8gYmUgYWRkZWQgYW5kIG1hdGNoIG1vZGUgY2hhbmdlZFxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGRpc3BsYXlNYXRjaE1vZGUgPT09IEZpbHRlck1hdGNoTW9kZS5FcXVhbHMgJiZcbiAgICAgICAgICAgICAgICB0aGlzLmRlc2NyaXB0b3IuZmlsdGVyVHlwZSA9PT0gRmlsdGVyVHlwZUVudW0uRGF0ZSAmJlxuICAgICAgICAgICAgICAgICh0aGlzLmRlc2NyaXB0b3IuZGF0ZVBpY2tlclNob3dUaW1lIHx8IHRoaXMuZGVzY3JpcHRvci5kYXRlUGlja2VyVmFsdWVOb1RpbWUgfHwgdGhpcy5kYXRlT25seURpc2FibGVkKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBbdmFsdWUsIHZhbHVlXTtcbiAgICAgICAgICAgICAgICBkaXNwbGF5TWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkJldHdlZW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldEZpbHRlckNvbnN0cmFpbnQoey4uLnRoaXMuZmlsdGVyQ29uc3RyYWludCgpLCBtYXRjaE1vZGU6IGRpc3BsYXlNYXRjaE1vZGUsIHZhbHVlOiB2YWx1ZX0pO1xuICAgICAgICB0aGlzLnVwZGF0ZUR0RmlsdGVyKCk7XG4gICAgICAgIHRoaXMuaGlkZU92ZXJsYXkoKTtcbiAgICB9XG5cbiAgICBvbk1hdGNoTW9kZUtleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgY29uc3QgaXRlbSA9IDxIVE1MTElFbGVtZW50PmV2ZW50LnRhcmdldDtcblxuICAgICAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY2FzZS1kZWNsYXJhdGlvbnNcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0SXRlbSA9IHRoaXMuZmluZE5leHRNZW51TW9kZUl0ZW0oaXRlbSk7XG4gICAgICAgICAgICAgICAgaWYgKG5leHRJdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW0ucmVtb3ZlQXR0cmlidXRlKCd0YWJpbmRleCcpO1xuICAgICAgICAgICAgICAgICAgICBuZXh0SXRlbS50YWJJbmRleCA9ICcwJztcbiAgICAgICAgICAgICAgICAgICAgbmV4dEl0ZW0uZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICdBcnJvd1VwJzpcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY2FzZS1kZWNsYXJhdGlvbnNcbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2SXRlbSA9IHRoaXMuZmluZFByZXZNZW51TW9kZUl0ZW0oaXRlbSk7XG4gICAgICAgICAgICAgICAgaWYgKHByZXZJdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW0ucmVtb3ZlQXR0cmlidXRlKCd0YWJpbmRleCcpO1xuICAgICAgICAgICAgICAgICAgICBwcmV2SXRlbS50YWJJbmRleCA9ICcwJztcbiAgICAgICAgICAgICAgICAgICAgcHJldkl0ZW0uZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Sb3dDbGVhckl0ZW1DbGljaygpIHtcbiAgICAgICAgdGhpcy5jbGVhckZpbHRlcigpO1xuICAgICAgICB0aGlzLmhpZGVPdmVybGF5KCk7XG4gICAgfVxuXG4gICAgdG9nZ2xlTWVudShldmVudDogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5vdmVybGF5VmlzaWJsZS5zZXQoIXRoaXMub3ZlcmxheVZpc2libGUoKSk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cblxuICAgIG9uVG9nZ2xlQnV0dG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgICAgICAgY2FzZSAnRXNjYXBlJzpcbiAgICAgICAgICAgIGNhc2UgJ1RhYic6XG4gICAgICAgICAgICAgICAgdGhpcy5vdmVybGF5VmlzaWJsZS5zZXQoZmFsc2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICdBcnJvd0Rvd24nOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm92ZXJsYXlWaXNpYmxlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZm9jdXNhYmxlID0gRG9tSGFuZGxlci5nZXRGb2N1c2FibGVFbGVtZW50cyg8SFRNTEVsZW1lbnQ+dGhpcy5vdmVybGF5KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvY3VzYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9jdXNhYmxlWzBdLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmFsdEtleSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm92ZXJsYXlWaXNpYmxlLnNldCh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkVzY2FwZSgpIHtcbiAgICAgICAgdGhpcy5vdmVybGF5VmlzaWJsZS5zZXQoZmFsc2UpO1xuICAgIH1cblxuICAgIG9uQ29udGVudENsaWNrKCkge1xuICAgICAgICB0aGlzLnNlbGZDbGljayA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gb25PdmVybGF5QW5pbWF0aW9uU3RhcnQoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KSB7XG4gICAgb25PdmVybGF5QW5pbWF0aW9uU3RhcnQoZXZlbnQ6IGFueSkge1xuICAgICAgICBzd2l0Y2ggKGV2ZW50LnRvU3RhdGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3Zpc2libGUnOlxuICAgICAgICAgICAgICAgIHRoaXMub3ZlcmxheSA9IGV2ZW50LmVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmRvY3VtZW50LmJvZHksIHRoaXMub3ZlcmxheSk7XG4gICAgICAgICAgICAgICAgWkluZGV4VXRpbHMuc2V0KCdvdmVybGF5JywgdGhpcy5vdmVybGF5LCB0aGlzLnByaW1lQ29uZmlnLnpJbmRleC5vdmVybGF5KTtcbiAgICAgICAgICAgICAgICBEb21IYW5kbGVyLmFic29sdXRlUG9zaXRpb24odGhpcy5vdmVybGF5LCB0aGlzLmljb24/Lm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMuYmluZERvY3VtZW50Q2xpY2tMaXN0ZW5lcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuYmluZERvY3VtZW50UmVzaXplTGlzdGVuZXIoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmJpbmRTY3JvbGxMaXN0ZW5lcigpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5vdmVybGF5RXZlbnRMaXN0ZW5lciA9IChlOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3ZlcmxheSAmJiB0aGlzLm92ZXJsYXkuY29udGFpbnMoZS50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGZDbGljayA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgdGhpcy5vdmVybGF5U3Vic2NyaXB0aW9uID0gdGhpcy5vdmVybGF5U2VydmljZS5jbGlja09ic2VydmFibGUucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKHRoaXMub3ZlcmxheUV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICd2b2lkJzpcbiAgICAgICAgICAgICAgICB0aGlzLm9uT3ZlcmxheUhpZGUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLm92ZXJsYXlTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBvbk92ZXJsYXlBbmltYXRpb25FbmQoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KSB7XG4gICAgb25PdmVybGF5QW5pbWF0aW9uRW5kKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgc3dpdGNoIChldmVudC50b1N0YXRlKSB7XG4gICAgICAgICAgICBjYXNlICd2b2lkJzpcbiAgICAgICAgICAgICAgICBaSW5kZXhVdGlscy5jbGVhcihldmVudC5lbGVtZW50KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBub0ZpbHRlckxhYmVsKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKFRyYW5zbGF0aW9uS2V5cy5OT19GSUxURVIpO1xuICAgIH1cblxuICAgIGNsZWFyRmlsdGVyKCkge1xuICAgICAgICB0aGlzLmluaXRGaWx0ZXJDb25zdHJhaW50KHRydWUpO1xuICAgICAgICB0aGlzLnByaW1lVGFibGUuX2ZpbHRlcigpO1xuICAgICAgICB0aGlzLmhpZGVPdmVybGF5KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZW5lcmF0ZU1hdGNoTW9kZU9wdGlvbnMoKSB7XG4gICAgICAgIGxldCBvcHRpb25zOiBTZWxlY3RJdGVtW10gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3IuZmlsdGVyVHlwZSA9PT0gRmlsdGVyVHlwZUVudW0uU3RyaW5nKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gW1xuICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLkNvbnRhaW5zLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuQ29udGFpbnMpfSxcbiAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5Ob3RDb250YWlucywgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLk5vdENvbnRhaW5zKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuTm90RXF1YWxzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuTm90RXF1YWxzKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuU3RhcnRzV2l0aCwgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLlN0YXJ0c1dpdGgpfSxcbiAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5FbmRzV2l0aCwgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLkVuZHNXaXRoKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRG9lc05vdEV4aXN0LCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRG9lc05vdEV4aXN0KX1cbiAgICAgICAgICAgIF07XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5kZXNjcmlwdG9yLmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLkJvb2xlYW4pIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBbe3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzKX1dO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGVzY3JpcHRvci5maWx0ZXJUeXBlID09PSBGaWx0ZXJUeXBlRW51bS5OdW1iZXIpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBbXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuTm90RXF1YWxzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuTm90RXF1YWxzKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuTGVzc1RoYW4sIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5MZXNzVGhhbil9LFxuICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLkxlc3NUaGFuT3JFcXVhbFRvLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuTGVzc1RoYW5PckVxdWFsVG8pfSxcbiAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5HcmVhdGVyVGhhbiwgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLkdyZWF0ZXJUaGFuKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuR3JlYXRlclRoYW5PckVxdWFsVG8sIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5HcmVhdGVyVGhhbk9yRXF1YWxUbyl9LFxuICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLkJldHdlZW4sIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5CZXR3ZWVuKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzKX0sXG4gICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRG9lc05vdEV4aXN0LCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRG9lc05vdEV4aXN0KX1cbiAgICAgICAgICAgIF07XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5kZXNjcmlwdG9yLmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLkxvb2t1cCB8fCB0aGlzLmRlc2NyaXB0b3IuZmlsdGVyVHlwZSA9PT0gRmlsdGVyVHlwZUVudW0uTG9va3VwRW51bSkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IFtcbiAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5FcXVhbHMsIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5FcXVhbHMpfSxcbiAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5Ob3RFcXVhbHMsIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5Ob3RFcXVhbHMpfSxcbiAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5FeGlzdHMsIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5FeGlzdHMpfSxcbiAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5Eb2VzTm90RXhpc3QsIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5Eb2VzTm90RXhpc3QpfVxuICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgaWYgKHRoaXMubG9va3VwRGVzY3JpcHRvcj8ubXVsdGlzZWxlY3QpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gW1xuICAgICAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5JbiwgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLkluKX0sXG4gICAgICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLk5vdEluLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuTm90SW4pfVxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5kZXNjcmlwdG9yLmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLkRhdGUpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5kZXNjcmlwdG9yLmRhdGVQaWNrZXJTaG93VGltZSAmJiAhdGhpcy5kZXNjcmlwdG9yLmRhdGVQaWNrZXJWYWx1ZU5vVGltZSAmJiAhdGhpcy5kYXRlT25seURpc2FibGVkKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IFtcbiAgICAgICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzKX0sXG4gICAgICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLk5vdEVxdWFscywgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLk5vdEVxdWFscyl9LFxuICAgICAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5MZXNzVGhhbk9yRXF1YWxUbywgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLkxlc3NUaGFuT3JFcXVhbFRvKX0sXG4gICAgICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLkdyZWF0ZXJUaGFuT3JFcXVhbFRvLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuR3JlYXRlclRoYW5PckVxdWFsVG8pfSxcbiAgICAgICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuQmV0d2VlbiwgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLkJldHdlZW4pfSxcbiAgICAgICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzKX0sXG4gICAgICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLkRvZXNOb3RFeGlzdCwgbGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oRmlsdGVyTWF0Y2hNb2RlLkRvZXNOb3RFeGlzdCl9XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IFtcbiAgICAgICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzKX0sXG4gICAgICAgICAgICAgICAgICAgIHt2YWx1ZTogRmlsdGVyTWF0Y2hNb2RlLkxlc3NUaGFuT3JFcXVhbFRvLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuTGVzc1RoYW5PckVxdWFsVG8pfSxcbiAgICAgICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuR3JlYXRlclRoYW5PckVxdWFsVG8sIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5HcmVhdGVyVGhhbk9yRXF1YWxUbyl9LFxuICAgICAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5CZXR3ZWVuLCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuQmV0d2Vlbil9LFxuICAgICAgICAgICAgICAgICAgICB7dmFsdWU6IEZpbHRlck1hdGNoTW9kZS5FeGlzdHMsIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKEZpbHRlck1hdGNoTW9kZS5FeGlzdHMpfSxcbiAgICAgICAgICAgICAgICAgICAge3ZhbHVlOiBGaWx0ZXJNYXRjaE1vZGUuRG9lc05vdEV4aXN0LCBsYWJlbDogdGhpcy5wcmltZUNvbmZpZy5nZXRUcmFuc2xhdGlvbihGaWx0ZXJNYXRjaE1vZGUuRG9lc05vdEV4aXN0KX1cbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGVzY3JpcHRvci5tYXRjaE1vZGVzKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gdGhpcy5kZXNjcmlwdG9yLm1hdGNoTW9kZXMubWFwKG1tID0+IDxTZWxlY3RJdGVtPnt2YWx1ZTogbW0sIGxhYmVsOiB0aGlzLnByaW1lQ29uZmlnLmdldFRyYW5zbGF0aW9uKG1tKX0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICAgICAgICBsZXQgcHJpbWVNYXRoY01vZGVPcHRpb25CeVR5cGU6IHN0cmluZ1tdIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKHRoaXMucHJpbWVUeXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICAgICAgICBwcmltZU1hdGhjTW9kZU9wdGlvbkJ5VHlwZSA9IHRoaXMucHJpbWVDb25maWcuZmlsdGVyTWF0Y2hNb2RlT3B0aW9ucy50ZXh0O1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByaW1lVHlwZSA9PT0gJ251bWVyaWMnKSB7XG4gICAgICAgICAgICAgICAgcHJpbWVNYXRoY01vZGVPcHRpb25CeVR5cGUgPSB0aGlzLnByaW1lQ29uZmlnLmZpbHRlck1hdGNoTW9kZU9wdGlvbnMubnVtZXJpYztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcmltZVR5cGUgPT09ICdkYXRlJykge1xuICAgICAgICAgICAgICAgIHByaW1lTWF0aGNNb2RlT3B0aW9uQnlUeXBlID0gdGhpcy5wcmltZUNvbmZpZy5maWx0ZXJNYXRjaE1vZGVPcHRpb25zLmRhdGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwcmltZU1hdGhjTW9kZU9wdGlvbkJ5VHlwZSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBwcmltZU1hdGhjTW9kZU9wdGlvbkJ5VHlwZS5tYXAoa2V5ID0+ICh7bGFiZWw6IHRoaXMucHJpbWVDb25maWcuZ2V0VHJhbnNsYXRpb24oa2V5KSwgdmFsdWU6IGtleX0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWF0Y2hNb2Rlcy5zZXQob3B0aW9ucyB8fCBbXSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXREZWZhdWx0TWF0Y2hNb2RlKCk6IHN0cmluZyB7XG4gICAgICAgIGxldCBkZWZhdWx0TWF0Y2hNb2RlOiBGaWx0ZXJNYXRjaE1vZGVFeHRlbmRlZFR5cGUgPSBGaWx0ZXJNYXRjaE1vZGUuQ29udGFpbnM7XG4gICAgICAgIGlmICh0aGlzLnByaW1lVHlwZSA9PT0gJ3RleHQnKSBkZWZhdWx0TWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLlN0YXJ0c1dpdGg7XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucHJpbWVUeXBlID09PSAnbnVtZXJpYycpIGRlZmF1bHRNYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzO1xuICAgICAgICBlbHNlIGlmICh0aGlzLnByaW1lVHlwZSA9PT0gJ2RhdGUnKSBkZWZhdWx0TWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkVxdWFscztcbiAgICAgICAgZWxzZSBpZiAodGhpcy5wcmltZVR5cGUgPT09ICdsb29rdXAnKSBkZWZhdWx0TWF0Y2hNb2RlID0gdGhpcy5sb29rdXBEZXNjcmlwdG9yPy5tdWx0aXNlbGVjdCA/IEZpbHRlck1hdGNoTW9kZS5JbiA6IEZpbHRlck1hdGNoTW9kZS5FcXVhbHM7XG5cbiAgICAgICAgLy8gb3ZlcndyaXRlIHR5cGUgZGVmYXVsdCBzZXQgaW4gZGVzY3JpcHRvclxuICAgICAgICBpZiAodGhpcy5kZXNjcmlwdG9yLmRlZmF1bHRNYXRjaE1vZGUpIHtcbiAgICAgICAgICAgIGRlZmF1bHRNYXRjaE1vZGUgPSB0aGlzLmRlc2NyaXB0b3IuZGVmYXVsdE1hdGNoTW9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGlmIGRlZmF1bHQgbW9kZSBleGlzdHMhXG4gICAgICAgIGlmICh0aGlzLm1hdGNoTW9kZXMoKS5sZW5ndGggPiAwICYmICF0aGlzLm1hdGNoTW9kZXMoKS5zb21lKG0gPT4gbS52YWx1ZSA9PT0gZGVmYXVsdE1hdGNoTW9kZSkpIHtcbiAgICAgICAgICAgIGRlZmF1bHRNYXRjaE1vZGUgPSB0aGlzLm1hdGNoTW9kZXMoKVswXS52YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkZWZhdWx0TWF0Y2hNb2RlO1xuICAgIH1cblxuICAgIHByaXZhdGUgZmluZE5leHRNZW51TW9kZUl0ZW0oaXRlbTogSFRNTExJRWxlbWVudCk6IGFueSB7XG4gICAgICAgIGNvbnN0IG5leHRJdGVtID0gPEhUTUxMSUVsZW1lbnQ+aXRlbS5uZXh0RWxlbWVudFNpYmxpbmc7XG5cbiAgICAgICAgaWYgKG5leHRJdGVtKSByZXR1cm4gRG9tSGFuZGxlci5oYXNDbGFzcyhuZXh0SXRlbSwgJ3AtY29sdW1uLWZpbHRlci1zZXBhcmF0b3InKSA/IHRoaXMuZmluZE5leHRNZW51TW9kZUl0ZW0obmV4dEl0ZW0pIDogbmV4dEl0ZW07XG4gICAgICAgIGVsc2UgcmV0dXJuIGl0ZW0ucGFyZW50RWxlbWVudD8uZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmaW5kUHJldk1lbnVNb2RlSXRlbShpdGVtOiBIVE1MTElFbGVtZW50KTogYW55IHtcbiAgICAgICAgY29uc3QgcHJldkl0ZW0gPSA8SFRNTExJRWxlbWVudD5pdGVtLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG5cbiAgICAgICAgaWYgKHByZXZJdGVtKSByZXR1cm4gRG9tSGFuZGxlci5oYXNDbGFzcyhwcmV2SXRlbSwgJ3AtY29sdW1uLWZpbHRlci1zZXBhcmF0b3InKSA/IHRoaXMuZmluZFByZXZNZW51TW9kZUl0ZW0ocHJldkl0ZW0pIDogcHJldkl0ZW07XG4gICAgICAgIGVsc2UgcmV0dXJuIGl0ZW0ucGFyZW50RWxlbWVudD8ubGFzdEVsZW1lbnRDaGlsZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzT3V0c2lkZUNsaWNrZWQoZXZlbnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIShcbiAgICAgICAgICAgIHRoaXMub3ZlcmxheT8uaXNTYW1lTm9kZShldmVudC50YXJnZXQpIHx8XG4gICAgICAgICAgICB0aGlzLm92ZXJsYXk/LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgfHxcbiAgICAgICAgICAgIHRoaXMuaWNvbj8ubmF0aXZlRWxlbWVudC5pc1NhbWVOb2RlKGV2ZW50LnRhcmdldCkgfHxcbiAgICAgICAgICAgIHRoaXMuaWNvbj8ubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpIHx8XG4gICAgICAgICAgICBEb21IYW5kbGVyLmhhc0NsYXNzKGV2ZW50LnRhcmdldCwgJ3AtY29sdW1uLWZpbHRlci1hZGQtYnV0dG9uJykgfHxcbiAgICAgICAgICAgIERvbUhhbmRsZXIuaGFzQ2xhc3MoZXZlbnQudGFyZ2V0LnBhcmVudEVsZW1lbnQsICdwLWNvbHVtbi1maWx0ZXItYWRkLWJ1dHRvbicpIHx8XG4gICAgICAgICAgICBEb21IYW5kbGVyLmhhc0NsYXNzKGV2ZW50LnRhcmdldCwgJ3AtY29sdW1uLWZpbHRlci1yZW1vdmUtYnV0dG9uJykgfHxcbiAgICAgICAgICAgIERvbUhhbmRsZXIuaGFzQ2xhc3MoZXZlbnQudGFyZ2V0LnBhcmVudEVsZW1lbnQsICdwLWNvbHVtbi1maWx0ZXItcmVtb3ZlLWJ1dHRvbicpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBiaW5kRG9jdW1lbnRDbGlja0xpc3RlbmVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuZG9jdW1lbnRDbGlja0xpc3RlbmVyKSB7XG4gICAgICAgICAgICBjb25zdCBkb2N1bWVudFRhcmdldDogYW55ID0gdGhpcy5lbCA/IHRoaXMuZWwubmF0aXZlRWxlbWVudC5vd25lckRvY3VtZW50IDogJ2RvY3VtZW50JztcblxuICAgICAgICAgICAgdGhpcy5kb2N1bWVudENsaWNrTGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbihkb2N1bWVudFRhcmdldCwgJ2NsaWNrJywgZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm92ZXJsYXlWaXNpYmxlKCkgJiYgIXRoaXMuc2VsZkNsaWNrICYmIHRoaXMuaXNPdXRzaWRlQ2xpY2tlZChldmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oaWRlT3ZlcmxheSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZkNsaWNrID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdW5iaW5kRG9jdW1lbnRDbGlja0xpc3RlbmVyKCkge1xuICAgICAgICBpZiAodGhpcy5kb2N1bWVudENsaWNrTGlzdGVuZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnRDbGlja0xpc3RlbmVyKCk7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50Q2xpY2tMaXN0ZW5lciA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnNlbGZDbGljayA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBiaW5kRG9jdW1lbnRSZXNpemVMaXN0ZW5lcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRvY3VtZW50UmVzaXplTGlzdGVuZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnRSZXNpemVMaXN0ZW5lciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKHRoaXMud2luZG93LCAncmVzaXplJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm92ZXJsYXlWaXNpYmxlKCkgJiYgIURvbUhhbmRsZXIuaXNUb3VjaERldmljZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGlkZU92ZXJsYXkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdW5iaW5kRG9jdW1lbnRSZXNpemVMaXN0ZW5lcigpIHtcbiAgICAgICAgaWYgKHRoaXMuZG9jdW1lbnRSZXNpemVMaXN0ZW5lcikge1xuICAgICAgICAgICAgdGhpcy5kb2N1bWVudFJlc2l6ZUxpc3RlbmVyKCk7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50UmVzaXplTGlzdGVuZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBiaW5kU2Nyb2xsTGlzdGVuZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5zY3JvbGxIYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbEhhbmRsZXIgPSBuZXcgQ29ubmVjdGVkT3ZlcmxheVNjcm9sbEhhbmRsZXIodGhpcy5pY29uPy5uYXRpdmVFbGVtZW50LCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3ZlcmxheVZpc2libGUoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmhpZGVPdmVybGF5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNjcm9sbEhhbmRsZXIuYmluZFNjcm9sbExpc3RlbmVyKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1bmJpbmRTY3JvbGxMaXN0ZW5lcigpIHtcbiAgICAgICAgaWYgKHRoaXMuc2Nyb2xsSGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxIYW5kbGVyLnVuYmluZFNjcm9sbExpc3RlbmVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGhpZGVPdmVybGF5KCkge1xuICAgICAgICB0aGlzLm92ZXJsYXlWaXNpYmxlLnNldChmYWxzZSk7XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbk92ZXJsYXlIaWRlKCkge1xuICAgICAgICB0aGlzLnVuYmluZERvY3VtZW50Q2xpY2tMaXN0ZW5lcigpO1xuICAgICAgICB0aGlzLnVuYmluZERvY3VtZW50UmVzaXplTGlzdGVuZXIoKTtcbiAgICAgICAgdGhpcy51bmJpbmRTY3JvbGxMaXN0ZW5lcigpO1xuICAgICAgICB0aGlzLm92ZXJsYXkgPSBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlRmlsdGVyVmFsdWUodmFsdWU6IGFueSkge1xuICAgICAgICB0aGlzLmZpbHRlckNvbnN0cmFpbnQuc2V0KHsuLi50aGlzLmZpbHRlckNvbnN0cmFpbnQoKSwgdmFsdWU6IHZhbHVlfSk7XG4gICAgICAgIHRoaXMudXBkYXRlRHRGaWx0ZXIoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZUR0RmlsdGVyKCkge1xuICAgICAgICB0aGlzLnByaW1lVGFibGUuZmlsdGVyc1t0aGlzLnByaW1lRmllbGRdID0gdGhpcy5maWx0ZXJDb25zdHJhaW50KCkhO1xuICAgICAgICB0aGlzLnByaW1lVGFibGUuX2ZpbHRlcigpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdEZpbHRlckNvbnN0cmFpbnQocmVzZXQgPSBmYWxzZSkge1xuICAgICAgICBpZiAocmVzZXQpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRNYXRjaE1vZGUgPSB0aGlzLmdldERlZmF1bHRNYXRjaE1vZGUoKTtcbiAgICAgICAgICAgIHRoaXMucHJpbWVUYWJsZS5maWx0ZXJzW3RoaXMucHJpbWVGaWVsZF0gPSB7dmFsdWU6IG51bGwsIG1hdGNoTW9kZTogZGVmYXVsdE1hdGNoTW9kZX07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgaW50ZXJuYWwgZmlsdGVyIGNvbnN0cmFpbnRcbiAgICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnByaW1lVGFibGUuZmlsdGVyc1t0aGlzLnByaW1lRmllbGRdO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShtZXRhZGF0YSkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0RmlsdGVyQ29uc3RyYWludChtZXRhZGF0YVswXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldEZpbHRlckNvbnN0cmFpbnQobWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRGaWx0ZXJDb25zdHJhaW50KG1ldGFkYXRhPzogUHJpbWVGaWx0ZXJNZXRhZGF0YSkge1xuICAgICAgICBsZXQgbWF0Y2hNb2RlID0gbWV0YWRhdGE/Lm1hdGNoTW9kZSA/PyB0aGlzLmdldERlZmF1bHRNYXRjaE1vZGUoKTtcbiAgICAgICAgbGV0IGRpc3BsYXlWYWx1ZSA9IG1ldGFkYXRhPy52YWx1ZTtcbiAgICAgICAgbGV0IGRpc3BsYXlNYXRjaE1vZGUgPSBtYXRjaE1vZGU7XG5cbiAgICAgICAgLy8gd2hlbiBlcXVhbHMgaXMgdXNlZCBvbiBkYXRlcyB3aXRoIHRpbWUsIHRoZSBhY3R1YWwgZmlsdGVyIHdpbGwgYmUgYmV0d2VlbiwgYnV0IGRpc3BsYXllZCBhcyBlcXVhbHNcbiAgICAgICAgaWYgKHRoaXMuZGVzY3JpcHRvci5maWx0ZXJUeXBlID09PSBGaWx0ZXJUeXBlRW51bS5EYXRlICYmICh0aGlzLmRlc2NyaXB0b3IuZGF0ZVBpY2tlclNob3dUaW1lIHx8IHRoaXMuZGVzY3JpcHRvci5kYXRlUGlja2VyVmFsdWVOb1RpbWUgfHwgdGhpcy5kYXRlT25seURpc2FibGVkKSkge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIG1hdGNoTW9kZSA9PT0gRmlsdGVyTWF0Y2hNb2RlLkJldHdlZW4gJiZcbiAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KG1ldGFkYXRhPy52YWx1ZSkgJiZcbiAgICAgICAgICAgICAgICBtZXRhZGF0YT8udmFsdWUubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE/LnZhbHVlLmV2ZXJ5KHYgPT4gdiBpbnN0YW5jZW9mIERhdGUgfHwgdHlwZW9mIHYgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2ID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IGRhdGVUb0lzb1N0cmluZyhtZXRhZGF0YS52YWx1ZVswXSBhcyBEYXRlIHwgc3RyaW5nIHwgbnVtYmVyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbmREYXRlID0gZGF0ZVRvSXNvU3RyaW5nKG1ldGFkYXRhLnZhbHVlWzFdIGFzIERhdGUgfCBzdHJpbmcgfCBudW1iZXIpO1xuXG4gICAgICAgICAgICAgICAgLy8gMjAyMC0xMS0wMlQxMToxMjoxMi4wMDBcbiAgICAgICAgICAgICAgICBjb25zdCBjbXBMZW5ndGggPSB0aGlzLmRlc2NyaXB0b3IuZGF0ZVBpY2tlclNob3dUaW1lID8gKHRoaXMuZGVzY3JpcHRvci5kYXRlUGlja2VyU2hvd1NlY29uZHMgPyAxOSA6IDE2KSA6IDEwO1xuXG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0RGF0ZS5zdWJzdHJpbmcoMCwgY21wTGVuZ3RoKSA9PT0gZW5kRGF0ZS5zdWJzdHJpbmcoMCwgY21wTGVuZ3RoKSkge1xuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5TWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkVxdWFscztcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheVZhbHVlID0gbmV3IERhdGUobWV0YWRhdGEudmFsdWVbMF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hNb2RlID09PSBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzICYmICFtZXRhZGF0YT8udmFsdWUpIHtcbiAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuQmV0d2VlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3IuZmlsdGVyVHlwZSA9PT0gRmlsdGVyVHlwZUVudW0uRGF0ZSAmJiBkaXNwbGF5VmFsdWUpIHtcbiAgICAgICAgICAgIC8vIGRpc3BsYXkgdmFsdWUgZm9yIGNhbGVuZGFyIGNhbm5vdCBiZSBzdHJpbmcsIGNvbnZlcnQgdG8gZGF0ZVxuICAgICAgICAgICAgZGlzcGxheVZhbHVlID0gQXJyYXkuaXNBcnJheShkaXNwbGF5VmFsdWUpXG4gICAgICAgICAgICAgICAgPyBkaXNwbGF5VmFsdWUubWFwKHYgPT4gKCEodiBpbnN0YW5jZW9mIERhdGUpID8gbmV3IERhdGUodikgOiB2KSlcbiAgICAgICAgICAgICAgICA6IGRpc3BsYXlWYWx1ZSBpbnN0YW5jZW9mIERhdGVcbiAgICAgICAgICAgICAgICAgID8gZGlzcGxheVZhbHVlXG4gICAgICAgICAgICAgICAgICA6IG5ldyBEYXRlKGRpc3BsYXlWYWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpbHRlckNvbnN0cmFpbnQuc2V0KHtcbiAgICAgICAgICAgIG1hdGNoTW9kZSxcbiAgICAgICAgICAgIHZhbHVlOiBtZXRhZGF0YT8udmFsdWUsXG4gICAgICAgICAgICBkaXNwbGF5TWF0Y2hNb2RlLFxuICAgICAgICAgICAgZGlzcGxheVZhbHVlOiBkaXNwbGF5VmFsdWUgPz8gbnVsbFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wcmltZVRhYmxlLmZpbHRlcnNbdGhpcy5wcmltZUZpZWxkXSA9IHRoaXMuZmlsdGVyQ29uc3RyYWludCgpITtcbiAgICB9XG59XG5cbmludGVyZmFjZSBGaWx0ZXJNZXRhZGF0YSBleHRlbmRzIFByaW1lRmlsdGVyTWV0YWRhdGEge1xuICAgIC8qKlxuICAgICAqIFRoZSB2YWx1ZSB1c2VkIGZvciBkaXNwbGF5LlxuICAgICAqL1xuICAgIGRpc3BsYXlWYWx1ZT86IGFueTtcbiAgICAvKipcbiAgICAgKiBUaGUgbWF0Y2ggbW9kZSBmb3IgZGlzcGxheS5cbiAgICAgKi9cbiAgICBkaXNwbGF5TWF0Y2hNb2RlPzogc3RyaW5nO1xufVxuIiwiPGRpdiBjbGFzcz1cInAtY29sdW1uLWZpbHRlciBwLWNvbHVtbi1maWx0ZXItcm93XCI+XG4gICAgQHN3aXRjaCAocHJpbWVUeXBlKSB7XG4gICAgICAgIEBjYXNlICgndGV4dCcpIHtcbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICAgICAgY2xhc3M9XCJtbmctY29sdW1uLWZpbHRlci1zdHJpbmctaW5wdXRcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJmaWx0ZXJDb25zdHJhaW50KCk/LmRpc3BsYXlWYWx1ZVwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzSW5wdXREaXNhYmxlZCgpXCJcbiAgICAgICAgICAgICAgICAoaW5wdXQpPVwib25UZXh0TW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwib25UZXh0SW5wdXRFbnRlcktleURvd24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgW2F0dHIucGxhY2Vob2xkZXJdPVwiZGVzY3JpcHRvci5wbGFjZWhvbGRlciA/PyAnbW5nVGFibGUudHlwZVRvRmlsdGVyJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgW21uZ0lucHV0VHJpbV09XCJkZXNjcmlwdG9yLnRyaW1PcHRpb25cIiAvPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnbnVtZXJpYycpIHtcbiAgICAgICAgICAgIEBpZiAoZmlsdGVyQ29uc3RyYWludCgpPy5kaXNwbGF5TWF0Y2hNb2RlID09PSAnYmV0d2VlbicpIHtcbiAgICAgICAgICAgICAgICA8bW5nLW51bWJlci1yYW5nZVxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJtbmctY29sdW1uLWZpbHRlci1udW1iZXItaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmaWx0ZXJDb25zdHJhaW50KCk/LmRpc3BsYXlWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uTnVtZXJpY01vZGVsQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAoa2V5RG93bik9XCJvbk51bWVyaWNJbnB1dEtleURvd24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJkZXNjcmlwdG9yLnBsYWNlaG9sZGVyID8/ICdtbmdUYWJsZS50eXBlVG9GaWx0ZXInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgW3VzZUdyb3VwaW5nXT1cImRlc2NyaXB0b3IubnVtYmVyVXNlR3JvdXBpbmdcIlxuICAgICAgICAgICAgICAgICAgICBbbWluRnJhY3Rpb25EaWdpdHNdPVwiZGVzY3JpcHRvci5udW1iZXJNaW5GcmFjdGlvbkRpZ2l0c1wiXG4gICAgICAgICAgICAgICAgICAgIFttYXhGcmFjdGlvbkRpZ2l0c109XCJkZXNjcmlwdG9yLm51bWJlck1heEZyYWN0aW9uRGlnaXRzXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzSW5wdXREaXNhYmxlZCgpXCIgLz5cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxwLWlucHV0TnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIGlucHV0U3R5bGVDbGFzcz1cIm1uZy1jb2x1bW4tZmlsdGVyLW51bWJlci1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImZpbHRlckNvbnN0cmFpbnQoKT8uZGlzcGxheVZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25OdW1lcmljTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIChvbktleURvd24pPVwib25OdW1lcmljSW5wdXRLZXlEb3duKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZGVzY3JpcHRvci5wbGFjZWhvbGRlciA/PyAnbW5nVGFibGUudHlwZVRvRmlsdGVyJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIFt1c2VHcm91cGluZ109XCJkZXNjcmlwdG9yLm51bWJlclVzZUdyb3VwaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgW21pbkZyYWN0aW9uRGlnaXRzXT1cImRlc2NyaXB0b3IubnVtYmVyTWluRnJhY3Rpb25EaWdpdHNcIlxuICAgICAgICAgICAgICAgICAgICBbbWF4RnJhY3Rpb25EaWdpdHNdPVwiZGVzY3JpcHRvci5udW1iZXJNYXhGcmFjdGlvbkRpZ2l0c1wiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0lucHV0RGlzYWJsZWQoKVwiIC8+XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBAY2FzZSAoJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICA8cC10cmlTdGF0ZUNoZWNrYm94IFtuZ01vZGVsXT1cImZpbHRlckNvbnN0cmFpbnQoKT8uZGlzcGxheVZhbHVlXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25UcmlzdGF0ZU1vZGVsQ2hhbmdlKCRldmVudClcIj48L3AtdHJpU3RhdGVDaGVja2JveD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoJ2RhdGUnKSB7XG4gICAgICAgICAgICBAaWYgKGZpbHRlckNvbnN0cmFpbnQoKT8uZGlzcGxheU1hdGNoTW9kZSA9PT0gJ2JldHdlZW4nKSB7XG4gICAgICAgICAgICAgICAgPG1uZy1kYXRlLXJhbmdlXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImZpbHRlckNvbnN0cmFpbnQoKT8uZGlzcGxheVZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25EYXRlRmlsdGVyTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIFtzaG93VGltZV09XCJkZXNjcmlwdG9yLmRhdGVQaWNrZXJTaG93VGltZVwiXG4gICAgICAgICAgICAgICAgICAgIFtkYXRlRm9ybWF0XT1cImRlc2NyaXB0b3IuZGF0ZVBpY2tlckZvcm1hdFwiXG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJkZXNjcmlwdG9yLnBsYWNlaG9sZGVyID8/ICdtbmdUYWJsZS50eXBlVG9GaWx0ZXInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzSW5wdXREaXNhYmxlZCgpXCI+PC9tbmctZGF0ZS1yYW5nZT5cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgIGFwcGVuZFRvPVwiYm9keVwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImZpbHRlckNvbnN0cmFpbnQoKT8uZGlzcGxheVZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25EYXRlRmlsdGVyTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJkZXNjcmlwdG9yLnBsYWNlaG9sZGVyID8/ICdtbmdUYWJsZS50eXBlVG9GaWx0ZXInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgW3Nob3dJY29uXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCJkZXNjcmlwdG9yLmRhdGVQaWNrZXJGb3JtYXQgPz8gJ2RkLm1tLnl5J1wiXG4gICAgICAgICAgICAgICAgICAgIFtzaG93VGltZV09XCJkZXNjcmlwdG9yLmRhdGVQaWNrZXJTaG93VGltZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmaXJzdERheU9mV2Vla109XCIxXCI+XG4gICAgICAgICAgICAgICAgPC9wLWNhbGVuZGFyPlxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnbG9va3VwJykge1xuICAgICAgICAgICAgQGlmIChsb29rdXBEZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICAgICAgQHN3aXRjaCAobG9va3VwRGVzY3JpcHRvci5sb29rdXBUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlIChsb29rdXBUeXBlQXV0b2NvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bW5nLWF1dG9jb21wbGV0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImZpbHRlckNvbnN0cmFpbnQoKT8uZGlzcGxheVZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YVByb3ZpZGVyXT1cImxvb2t1cERlc2NyaXB0b3IuZGF0YVByb3ZpZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc1RyYWNrUHJvcGVydHldPVwibG9va3VwRGVzY3JpcHRvci5vcHRpb25zVmFsdWVQcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNWYWx1ZVByb3BlcnR5XT1cImxvb2t1cERlc2NyaXB0b3Iub3B0aW9uc1ZhbHVlUHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zTGFiZWxQcm9wZXJ0eV09XCJsb29rdXBEZXNjcmlwdG9yLm9wdGlvbnNMYWJlbFByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc0xhYmVsVHJhbnNsYXRlXT1cImxvb2t1cERlc2NyaXB0b3Iub3B0aW9uc0xhYmVsVHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbXVsdGlzZWxlY3RdPVwibG9va3VwRGVzY3JpcHRvci5tdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F1dG9DbGVhcl09XCJsb29rdXBEZXNjcmlwdG9yLmF1dG9jb21wbGV0ZUF1dG9DbGVhciA/PyBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wZW5PbkZvY3VzXT1cImxvb2t1cERlc2NyaXB0b3IuYXV0b2NvbXBsZXRlQXV0b0NsZWFyID8/IHRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbmxpbmVTZWFyY2hdPVwibG9va3VwRGVzY3JpcHRvci5hdXRvY29tcGxldGVJbmxpbmVTZWFyY2ggPz8gZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJkZXNjcmlwdG9yLnBsYWNlaG9sZGVyID8/ICdtbmdUYWJsZS5zZWFyY2hUb0ZpbHRlcicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc05hbWVdPVwibG9va3VwRGVzY3JpcHRvci5jbGFzc05hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkcm9wZG93bkNsYXNzTmFtZV09XCJsb29rdXBEZXNjcmlwdG9yLmRyb3Bkb3duQ2xhc3NOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNJbnB1dERpc2FibGVkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJhdXRvY29tcGxldGVGaWx0ZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlYXJjaFRyaW1dPVwiZGVzY3JpcHRvci50cmltT3B0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21uZy1hdXRvY29tcGxldGU+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKGxvb2t1cFR5cGVEcm9wZG93bikge1xuICAgICAgICAgICAgICAgICAgICAgICAgPG1uZy1kcm9wZG93blxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImZpbHRlckNvbnN0cmFpbnQoKT8uZGlzcGxheVZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YVByb3ZpZGVyXT1cImxvb2t1cERlc2NyaXB0b3IuZGF0YVByb3ZpZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc1ZhbHVlUHJvcGVydHldPVwibG9va3VwRGVzY3JpcHRvci5vcHRpb25zVmFsdWVQcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNMYWJlbFByb3BlcnR5XT1cImxvb2t1cERlc2NyaXB0b3Iub3B0aW9uc0xhYmVsUHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zTGFiZWxUcmFuc2xhdGVdPVwibG9va3VwRGVzY3JpcHRvci5vcHRpb25zTGFiZWxUcmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttdWx0aXNlbGVjdF09XCJsb29rdXBEZXNjcmlwdG9yLm11bHRpc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZGVzY3JpcHRvci5wbGFjZWhvbGRlciA/PyAnbW5nVGFibGUuc2VsZWN0VG9GaWx0ZXInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NOYW1lXT1cImxvb2t1cERlc2NyaXB0b3IuY2xhc3NOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZHJvcGRvd25DbGFzc05hbWVdPVwibG9va3VwRGVzY3JpcHRvci5kcm9wZG93bkNsYXNzTmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dDbGVhcl09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NoYW5nZVZhbHVlT25CbHVyXT1cImxvb2t1cERlc2NyaXB0b3IubXVsdGlzZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0lucHV0RGlzYWJsZWQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cImRyb3Bkb3duRmlsdGVyKCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbW5nLWRyb3Bkb3duPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgQGlmIChtYXRjaE1vZGVzKCkubGVuZ3RoID4gMSkge1xuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAjaWNvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cInAtY29sdW1uLWZpbHRlci1tZW51LWJ1dHRvbiBwLWxpbmtcIlxuICAgICAgICAgICAgYXJpYS1oYXNwb3B1cD1cInRydWVcIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCJvdmVybGF5VmlzaWJsZSgpXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsncC1jb2x1bW4tZmlsdGVyLW1lbnUtYnV0dG9uLW9wZW4nOiBvdmVybGF5VmlzaWJsZSgpLCAncC1jb2x1bW4tZmlsdGVyLW1lbnUtYnV0dG9uLWFjdGl2ZSc6IGlzRmlsdGVyU2V0KCl9XCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVNZW51KCRldmVudClcIlxuICAgICAgICAgICAgKGtleWRvd24pPVwib25Ub2dnbGVCdXR0b25LZXlEb3duKCRldmVudClcIj5cbiAgICAgICAgICAgIDxGaWx0ZXJJY29uIFtzdHlsZUNsYXNzXT1cIidwaS1maWx0ZXItaWNvbidcIiAvPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICB9XG4gICAgPGJ1dHRvbiAjaWNvbiBbbmdDbGFzc109XCJ7J3AtaGlkZGVuLXNwYWNlJzogIWlzRmlsdGVyU2V0KCl9XCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicC1jb2x1bW4tZmlsdGVyLWNsZWFyLWJ1dHRvbiBwLWxpbmtcIiAoY2xpY2spPVwiY2xlYXJGaWx0ZXIoKVwiPlxuICAgICAgICA8RmlsdGVyU2xhc2hJY29uIC8+XG4gICAgPC9idXR0b24+XG4gICAgQGlmIChvdmVybGF5VmlzaWJsZSgpKSB7XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwicC1jb2x1bW4tZmlsdGVyLW92ZXJsYXkgcC1jb21wb25lbnQgcC1mbHVpZFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25Db250ZW50Q2xpY2soKVwiXG4gICAgICAgICAgICBbQG92ZXJsYXlBbmltYXRpb25dPVwiJ3Zpc2libGUnXCJcbiAgICAgICAgICAgIChAb3ZlcmxheUFuaW1hdGlvbi5zdGFydCk9XCJvbk92ZXJsYXlBbmltYXRpb25TdGFydCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChAb3ZlcmxheUFuaW1hdGlvbi5kb25lKT1cIm9uT3ZlcmxheUFuaW1hdGlvbkVuZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChrZXlkb3duLmVzY2FwZSk9XCJvbkVzY2FwZSgpXCI+XG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJwLWNvbHVtbi1maWx0ZXItcm93LWl0ZW1zXCI+XG4gICAgICAgICAgICAgICAgQGZvciAobWF0Y2hNb2RlIG9mIG1hdGNoTW9kZXMoKTsgdHJhY2sgbWF0Y2hNb2RlOyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICA8bGlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1jb2x1bW4tZmlsdGVyLXJvdy1pdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbk1hdGNoTW9kZUNoYW5nZShtYXRjaE1vZGUudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChrZXlkb3duKT1cIm9uTWF0Y2hNb2RlS2V5RG93bigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cInRoaXMub25NYXRjaE1vZGVDaGFuZ2UobWF0Y2hNb2RlLnZhbHVlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3AtaGlnaGxpZ2h0JzogbWF0Y2hNb2RlLnZhbHVlID09PSBmaWx0ZXJDb25zdHJhaW50KCk/LmRpc3BsYXlNYXRjaE1vZGV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLnRhYmluZGV4XT1cImkgPT09IDAgPyAnMCcgOiBudWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBtYXRjaE1vZGUubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicC1jb2x1bW4tZmlsdGVyLXNlcGFyYXRvclwiPjwvbGk+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicC1jb2x1bW4tZmlsdGVyLXJvdy1pdGVtXCIgKGNsaWNrKT1cIm9uUm93Q2xlYXJJdGVtQ2xpY2soKVwiIChrZXlkb3duKT1cIm9uTWF0Y2hNb2RlS2V5RG93bigkZXZlbnQpXCIgKGtleWRvd24uZW50ZXIpPVwib25Sb3dDbGVhckl0ZW1DbGljaygpXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IG5vRmlsdGVyTGFiZWwgfX1cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuPC9kaXY+XG4iXX0=