@mediusinc/mng-commons 5.1.0-rc.0 → 5.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +7 -6
  2. package/core/helpers/coercion.d.ts +1 -0
  3. package/core/index.d.ts +0 -1
  4. package/esm2022/core/components/notification/notification-wrapper.component.mjs +5 -6
  5. package/esm2022/core/components/pages/error/error.page.component.mjs +4 -4
  6. package/esm2022/core/components/pages/not-found/not-found.page.component.mjs +4 -4
  7. package/esm2022/core/directives/component.directive.mjs +3 -3
  8. package/esm2022/core/directives/template.directive.mjs +3 -3
  9. package/esm2022/core/helpers/coercion.mjs +4 -1
  10. package/esm2022/core/index.mjs +1 -2
  11. package/esm2022/core/pipes/boolean.pipe.mjs +3 -3
  12. package/esm2022/core/pipes/class-map.pipe.mjs +3 -3
  13. package/esm2022/core/pipes/enum.pipe.mjs +5 -5
  14. package/esm2022/core/pipes/enumerate-async.pipe.mjs +3 -3
  15. package/esm2022/core/pipes/enumerate.pipe.mjs +3 -3
  16. package/esm2022/core/pipes/getter.pipe.mjs +3 -3
  17. package/esm2022/core/pipes/i18n-property.pipe.mjs +3 -3
  18. package/esm2022/core/pipes/json-path.pipe.mjs +3 -3
  19. package/esm2022/core/pipes/parametrize.pipe.mjs +3 -3
  20. package/esm2022/core/pipes/template.pipe.mjs +3 -3
  21. package/esm2022/core/security/permission.service.mjs +3 -3
  22. package/esm2022/core/services/commons-init.service.mjs +3 -3
  23. package/esm2022/core/services/commons-router.service.mjs +3 -3
  24. package/esm2022/core/services/commons.service.mjs +3 -3
  25. package/esm2022/core/services/local-storage-config.service.mjs +3 -3
  26. package/esm2022/form/components/autocomplete/autocomplete.component.mjs +4 -4
  27. package/esm2022/form/components/date-range/date-range.component.mjs +4 -4
  28. package/esm2022/form/components/dropdown/dropdown.component.mjs +4 -4
  29. package/esm2022/form/directives/input-trim.directive.mjs +14 -19
  30. package/esm2022/table/api/models/table.model.mjs +1 -1
  31. package/esm2022/table/components/column-filter-full/column-filter-full.component.mjs +4 -4
  32. package/esm2022/table/components/column-value/column-value.component.mjs +43 -53
  33. package/esm2022/table/components/table/table.component.mjs +300 -365
  34. package/esm2022/table/pipes/locale-default-row-class.pipe.mjs +3 -3
  35. package/esm2022/table/pipes/table-column-filter-class.pipe.mjs +3 -3
  36. package/esm2022/table/services/data-list.service.mjs +3 -3
  37. package/esm2022/tableview/action/components/action/action.component.mjs +5 -5
  38. package/esm2022/tableview/action/components/editor/action-editor.component.mjs +6 -7
  39. package/esm2022/tableview/action/components/editor/injector-context/action-editor-injector-context.component.mjs +5 -4
  40. package/esm2022/tableview/action/components/localization/data-language-dropdown.component.mjs +3 -3
  41. package/esm2022/tableview/action/components/route/action-route.component.mjs +3 -3
  42. package/esm2022/tableview/action/components/table/action-table.component.mjs +43 -92
  43. package/esm2022/tableview/action/services/component-action-executor.service.mjs +3 -3
  44. package/esm2022/tableview/action/services/data-provider-executor.service.mjs +3 -3
  45. package/esm2022/tableview/action/services/navigation.service.mjs +3 -3
  46. package/esm2022/tableview/action/services/root-action-executor.service.mjs +3 -3
  47. package/esm2022/tableview/action/services/view-container.service.mjs +3 -3
  48. package/esm2022/tableview/api/editor/descriptors/field-base.descriptor.mjs +1 -1
  49. package/esm2022/tableview/api/editor/descriptors/field-lookup.descriptor.mjs +1 -1
  50. package/esm2022/tableview/api/editor/descriptors/field-many.descriptor.mjs +4 -1
  51. package/esm2022/tableview/api/editor/descriptors/field.descriptor.mjs +6 -14
  52. package/esm2022/tableview/api/editor/models/field-action-context.model.mjs +1 -1
  53. package/esm2022/tableview/api/editor/models/form-editor.interface.mjs +1 -1
  54. package/esm2022/tableview/api/editor/models/formly-custom-field.model.mjs +5 -5
  55. package/esm2022/tableview/api/editor/models/formly-field.model.mjs +1 -1
  56. package/esm2022/tableview/api/index.mjs +1 -2
  57. package/esm2022/tableview/editor/components/editor/form-editor.component.mjs +17 -17
  58. package/esm2022/tableview/editor/components/formly/fields/formly-field-action/formly-field-action.component.mjs +4 -4
  59. package/esm2022/tableview/editor/components/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.mjs +3 -3
  60. package/esm2022/tableview/editor/components/formly/fields/formly-field-custom/formly-field-custom.component.mjs +3 -3
  61. package/esm2022/tableview/editor/components/formly/fields/formly-field-datepicker/formly-field-datepicker.component.mjs +47 -6
  62. package/esm2022/tableview/editor/components/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +3 -3
  63. package/esm2022/tableview/editor/components/formly/fields/formly-field-fieldset/formly-field-fieldset.component.mjs +3 -3
  64. package/esm2022/tableview/editor/components/formly/fields/formly-field-input/formly-field-input.component.mjs +4 -4
  65. package/esm2022/tableview/editor/components/formly/fields/formly-field-label/formly-field-label.component.mjs +3 -3
  66. package/esm2022/tableview/editor/components/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.mjs +15 -29
  67. package/esm2022/tableview/editor/components/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +10 -11
  68. package/esm2022/tableview/editor/components/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +18 -22
  69. package/esm2022/tableview/editor/components/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +3 -3
  70. package/esm2022/tableview/editor/components/formly/fields/formly-field-type.abstract.component.mjs +4 -4
  71. package/esm2022/tableview/editor/components/formly/wrappers/formly-field-no-label-wrapper/formly-field-no-label-wrapper.component.mjs +3 -3
  72. package/esm2022/tableview/editor/components/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.mjs +3 -3
  73. package/esm2022/tableview/editor/helpers/editor-formly.mjs +14 -2
  74. package/esm2022/tableview/editor/helpers/editor-validators.mjs +25 -0
  75. package/esm2022/tableview/editor/helpers/formly-config.mjs +7 -5
  76. package/esm2022/tableview/editor/services/form-editor.service.mjs +3 -3
  77. package/esm2022/tableview/index.mjs +2 -1
  78. package/esm2022/tableview/tableview/components/route/tableview-route.component.mjs +3 -3
  79. package/esm2022/tableview/tableview/components/tableview/tableview.component.mjs +4 -4
  80. package/fesm2022/mediusinc-mng-commons-core.mjs +69 -111
  81. package/fesm2022/mediusinc-mng-commons-core.mjs.map +1 -1
  82. package/fesm2022/mediusinc-mng-commons-form.mjs +23 -27
  83. package/fesm2022/mediusinc-mng-commons-form.mjs.map +1 -1
  84. package/fesm2022/mediusinc-mng-commons-table-api.mjs.map +1 -1
  85. package/fesm2022/mediusinc-mng-commons-table.mjs +357 -431
  86. package/fesm2022/mediusinc-mng-commons-table.mjs.map +1 -1
  87. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs +13 -39
  88. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs.map +1 -1
  89. package/fesm2022/mediusinc-mng-commons-tableview.mjs +252 -240
  90. package/fesm2022/mediusinc-mng-commons-tableview.mjs.map +1 -1
  91. package/form/directives/input-trim.directive.d.ts +5 -8
  92. package/package.json +15 -15
  93. package/table/api/models/table.model.d.ts +1 -1
  94. package/table/components/column-value/column-value.component.d.ts +11 -17
  95. package/table/components/table/table.component.d.ts +43 -47
  96. package/tableview/action/components/editor/action-editor.component.d.ts +1 -2
  97. package/tableview/action/components/table/action-table.component.d.ts +26 -29
  98. package/tableview/api/editor/descriptors/field-base.descriptor.d.ts +3 -3
  99. package/tableview/api/editor/descriptors/field-lookup.descriptor.d.ts +3 -3
  100. package/tableview/api/editor/descriptors/field-many.descriptor.d.ts +2 -1
  101. package/tableview/api/editor/descriptors/field.descriptor.d.ts +13 -9
  102. package/tableview/api/editor/models/field-action-context.model.d.ts +1 -1
  103. package/tableview/api/editor/models/form-editor.interface.d.ts +23 -6
  104. package/tableview/api/editor/models/formly-custom-field.model.d.ts +22 -19
  105. package/tableview/api/editor/models/formly-field.model.d.ts +20 -0
  106. package/tableview/api/index.d.ts +0 -1
  107. package/tableview/editor/components/editor/form-editor.component.d.ts +7 -7
  108. package/tableview/editor/components/formly/fields/formly-field-action/formly-field-action.component.d.ts +1 -1
  109. package/tableview/editor/components/formly/fields/formly-field-datepicker/formly-field-datepicker.component.d.ts +3 -0
  110. package/tableview/editor/components/formly/fields/formly-field-input/formly-field-input.component.d.ts +2 -3
  111. package/tableview/editor/components/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.d.ts +3 -6
  112. package/tableview/editor/components/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.d.ts +2 -4
  113. package/tableview/editor/components/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.d.ts +4 -8
  114. package/tableview/editor/components/formly/fields/formly-field-type.abstract.component.d.ts +3 -3
  115. package/tableview/editor/helpers/editor-validators.d.ts +7 -0
  116. package/tableview/index.d.ts +1 -0
  117. package/version-info.json +6 -6
  118. package/core/directives/dialog-keydown-handler.directive.d.ts +0 -12
  119. package/esm2022/core/directives/dialog-keydown-handler.directive.mjs +0 -49
  120. package/esm2022/tableview/api/editor/helpers/field-validators.mjs +0 -23
  121. package/tableview/api/editor/helpers/field-validators.d.ts +0 -7
@@ -1,6 +1,6 @@
1
1
  import { AsyncPipe, NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
2
- import { ChangeDetectionStrategy, Component, DestroyRef, EventEmitter, Injector, Input, Output, QueryList, Type, ViewChild, ViewChildren, computed, contentChildren, inject, signal } from '@angular/core';
3
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
+ import { ChangeDetectionStrategy, Component, Injector, afterNextRender, computed, contentChildren, effect, inject, input, output, signal, viewChild, viewChildren } from '@angular/core';
3
+ import { outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
4
4
  import { FormsModule } from '@angular/forms';
5
5
  import { ActivatedRoute, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';
6
6
  import { TranslateModule, TranslateService } from '@ngx-translate/core';
@@ -9,11 +9,11 @@ import { ButtonModule } from 'primeng/button';
9
9
  import { MultiSelectModule } from 'primeng/multiselect';
10
10
  import { Table, TableModule } from 'primeng/table';
11
11
  import { TooltipModule } from 'primeng/tooltip';
12
- import { Observable, isObservable, of } from 'rxjs';
12
+ import { NEVER, Subject, combineLatest, of, switchMap } from 'rxjs';
13
13
  import { filter } from 'rxjs/operators';
14
- import { ClassMapPipe, CommonsService, ComponentDirective, FilterMatchMode, I18nPropertyPipe, LocalStorageService, LoggerService, TemplateDirective, boolean$Attribute, dataListParamsToUrlQuery, findTemplateByName, fromSubscribeError, fromTableLoadToDataListParams, fromUrlQueryToDataListParams, getErrorLogLevel, mergeDataListParamsWithDefaults, toObservable } from '@mediusinc/mng-commons/core';
14
+ import { ClassMapPipe, CommonsService, ComponentDirective, FilterMatchMode, I18nPropertyPipe, LocalStorageService, LoggerService, TemplateDirective, booleanOrUndefinedAttribute, toObservable as commonsToObservable, dataListParamsToUrlQuery, findTemplateByName, fromSubscribeError, fromTableLoadToDataListParams, fromUrlQueryToDataListParams, getErrorLogLevel, mergeDataListParamsWithDefaults } from '@mediusinc/mng-commons/core';
15
15
  import { FilterTypeEnum } from '@mediusinc/mng-commons/filter';
16
- import { TableDescriptorInst, TableDynamicDescriptorInst, TablePaginationModeEnum, TableSizeEnum, tableDescriptor } from '@mediusinc/mng-commons/table/api';
16
+ import { TableDynamicDescriptorInst, TablePaginationModeEnum, TableSizeEnum, tableDescriptor } from '@mediusinc/mng-commons/table/api';
17
17
  import { tableNotificationError } from '../../helpers/notification';
18
18
  import { generateTableLayoutPrefsKey } from '../../helpers/table-layout-prefs';
19
19
  import { LocaleDefaultRowClassPipe } from '../../pipes/locale-default-row-class.pipe';
@@ -29,13 +29,11 @@ import * as i4 from "primeng/button";
29
29
  import * as i5 from "primeng/tooltip";
30
30
  import * as i6 from "@ngx-translate/core";
31
31
  import * as i7 from "@angular/forms";
32
- // Sorts and Filters must be string by default - Item could be anything
33
32
  export class TableComponent {
34
33
  constructor() {
35
34
  this.cmpTypeName = 'TableComponent';
36
35
  this.logger = inject(LoggerService).create(this.cmpTypeName);
37
36
  this.injector = inject(Injector);
38
- this.destroyRef = inject(DestroyRef);
39
37
  this.router = inject(Router);
40
38
  this.route = inject(ActivatedRoute);
41
39
  this.translate = inject(TranslateService);
@@ -43,201 +41,216 @@ export class TableComponent {
43
41
  this.commons = inject(CommonsService);
44
42
  this.localStorageService = inject(LocalStorageService);
45
43
  this.dataListService = inject((DataListService));
46
- this.useQueryParams = false;
44
+ // metadata input
45
+ this.descriptorInput = input.required({ alias: 'descriptor' });
46
+ // data source inputs
47
+ this.items = input();
48
+ this.result = input();
49
+ this.loadingInput = input(undefined, { alias: 'loading', transform: booleanOrUndefinedAttribute });
50
+ this.dataProvider = input();
47
51
  // extra features input
48
- this.selectionMode = 'multiple';
49
- this.selectionEnabled = false;
52
+ this.useQueryParamsInput = input(false, { alias: 'useQueryParams' });
53
+ this.cellClickEnabled = input(true);
54
+ this.selectionMode = input('multiple');
55
+ this.selectionEnabled = input(false);
56
+ // styling
57
+ this.columnLastMinWidth = input();
58
+ // component inputs
59
+ this.captionComponent = input();
60
+ this.columnCustomLastComponent = input();
61
+ this.globalFilterFieldsInput = input(undefined, { alias: 'globalFilterFields' });
62
+ // cell click
63
+ this.cellClickSubject = new Subject();
64
+ this.isCellClickObserved = signal(this.cellClickSubject.observed);
65
+ this.isCellClickEnabled = computed(() => this.cellClickEnabled() && this.isCellClickObserved());
50
66
  // event outputs
51
- this.loadEventEmitter = new EventEmitter();
52
- this.cellClickEventEmitter = new EventEmitter();
53
- this.selectionChangeEventEmitter = new EventEmitter();
54
- this.captionCmpInstEventEmitter = new EventEmitter();
55
- this.columnCustomLastCmpInstEventEmitter = new EventEmitter();
67
+ this.tableLoad = output();
68
+ this.cellClick = outputFromObservable(this.cellClickSubject);
69
+ this.selectionChange = output();
70
+ this.captionComponentInstance = output();
71
+ this.columnCustomLastComponentInstance = output();
56
72
  // content and view queries
57
73
  this.templates = contentChildren(TemplateDirective);
74
+ this.components = viewChildren((ComponentDirective));
75
+ this.primeTable = viewChild.required(Table);
58
76
  // templates
59
77
  this.captionTemplate = computed(() => findTemplateByName([...this.templates()], 'caption'));
60
78
  this.columnCustomLastTemplate = computed(() => findTemplateByName([...this.templates()], 'columnCustomLast'));
61
79
  this.footerTemplate = computed(() => findTemplateByName([...this.templates()], 'footer'));
62
80
  this.rowExpandTemplate = computed(() => findTemplateByName([...this.templates()], 'rowExpandContent'));
63
81
  // data provider and items
64
- this.useDataProvider = false;
65
- this.isLazy = signal(false);
66
- this.isPagination = signal(false);
82
+ this.useQueryParams = computed(() => (this.paginationMode() === TablePaginationModeEnum.InfiniteScroll ? false : this.useQueryParamsInput()));
83
+ this.isLazy = computed(() => this.dataProvider()?.isLazy === true);
84
+ this.isPagination = computed(() => this.paginationMode() === TablePaginationModeEnum.Pagination);
67
85
  this.useQueryParamsInitialized = signal(false);
68
- // infinite scroll
69
- this.infiniteScroll = signal(false);
70
86
  // visual
71
- this.className = signal('');
72
- this.tableFullHeightOffset = signal(undefined);
73
- this.rowHeight = signal(undefined);
87
+ this.paginationMode = computed(() => {
88
+ if (typeof this.descriptor().paginationMode !== 'undefined') {
89
+ // descriptor choice is the most strong - if defined, use this value
90
+ return this.descriptor().paginationMode;
91
+ }
92
+ else if (typeof this.dataProvider() !== 'undefined') {
93
+ // when data provider is used, use pagination
94
+ return TablePaginationModeEnum.Pagination;
95
+ }
96
+ else {
97
+ return TablePaginationModeEnum.None;
98
+ }
99
+ });
100
+ this.infiniteScroll = computed(() => this.paginationMode() === TablePaginationModeEnum.InfiniteScroll);
101
+ this.className = computed(() => {
102
+ let className = this.descriptor().className ?? '';
103
+ switch (this.descriptor().size) {
104
+ case TableSizeEnum.Small:
105
+ className += ' p-datatable-sm';
106
+ break;
107
+ case TableSizeEnum.Large:
108
+ className += ' p-datatable-lg';
109
+ break;
110
+ }
111
+ if (this.descriptor().hasGridlines) {
112
+ className += ' p-datatable-gridlines';
113
+ }
114
+ return className;
115
+ });
116
+ this.tableFullHeightOffset = computed(() => (this.paginationMode() === TablePaginationModeEnum.InfiniteScroll ? this.descriptor().tableFullHeightOffset ?? 315 : undefined));
117
+ this.rowHeight = computed(() => (this.paginationMode() === TablePaginationModeEnum.InfiniteScroll ? this.descriptor().rowHeight ?? 45 : undefined));
74
118
  // data provider
75
- this.dataProviderService = null;
119
+ this.dataProviderService = computed(() => {
120
+ const dataProvider = this.dataProvider();
121
+ return dataProvider?.serviceType ? this.injector.get(dataProvider.serviceType) : null;
122
+ });
76
123
  this.latestLazyLoadEventVersion = 0;
77
124
  this.latestParamsWithDefaultsVersion = 0;
78
125
  // descriptors
79
126
  this.descriptor = signal(tableDescriptor());
80
- this.columns = signal([]);
127
+ this.localstorageKey = computed(() => {
128
+ const descriptor = this.descriptor();
129
+ return descriptor.model.typeName || descriptor.model.i18nBaseKey
130
+ ? generateTableLayoutPrefsKey(descriptor.model.typeName ?? descriptor.model.i18nBaseKey, this.router.url, descriptor.identifier)
131
+ : null;
132
+ });
133
+ this.layoutPrefsSaveCnt = signal(0);
134
+ this.layoutPreferences = computed(() => {
135
+ const lsKey = this.localstorageKey();
136
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
137
+ const cnt = this.layoutPrefsSaveCnt(); // needed to force updates on user changes
138
+ const layoutPrefs = lsKey ? this.localStorageService.getItem(this.cmpTypeName, lsKey) : undefined;
139
+ return layoutPrefs ?? { columnWidths: {} };
140
+ });
141
+ this.columns = computed(() => this.computColumnsWithLayout());
81
142
  this.visibleColumns = computed(() => this.columns().filter(col => col.isVisible));
82
143
  // filter, sort
83
144
  this.hasColumnFilters = computed(() => this.filterDescriptors().length > 0);
84
145
  this.filterDescriptors = computed(() => this.descriptor().filters);
85
- this.defaultParams = computed(() => {
86
- const params = {
87
- offset: 0,
88
- limit: this.dataListService.rowsPerPageOptions()[0],
89
- sort: this.descriptor()
90
- .sorts.filter(s => s.defaultIsEnabled)
91
- .map(s => ({
92
- property: s.property,
93
- ascending: s.defaultIsAscending
94
- })),
95
- filters: {}
96
- };
97
- this.filterDescriptors()
98
- .filter(d => d.hasDefaultValue)
99
- .forEach(f => {
100
- let matchMode = f.defaultMatchMode;
101
- if (!matchMode) {
102
- switch (f.filterType) {
103
- case FilterTypeEnum.String:
104
- matchMode = FilterMatchMode.Contains;
105
- break;
106
- case FilterTypeEnum.Lookup:
107
- case FilterTypeEnum.LookupEnum: {
108
- const lookupFilter = f;
109
- if (lookupFilter.multiselect) {
110
- matchMode = FilterMatchMode.In;
111
- }
112
- break;
113
- }
114
- default:
115
- break;
116
- }
117
- }
118
- if (!matchMode) {
119
- matchMode = FilterMatchMode.Equals;
120
- }
121
- if (f.matchModes && !f.matchModes?.includes(matchMode)) {
122
- matchMode = f.matchModes[0];
123
- }
124
- let value = undefined;
125
- if (Array.isArray(value)) {
126
- value = [...value];
127
- }
128
- else {
129
- value = f.defaultValue;
130
- }
131
- const property = f.property;
132
- params.filters[property] = {
133
- value: value,
134
- matchMode: matchMode
135
- };
136
- });
137
- return params;
138
- });
146
+ this.defaultParams = computed(() => this.computeDefaultDataListParams());
139
147
  this.isFilterChanged = false;
140
148
  this.isSortChanged = false;
141
149
  this.anyColumnVisible = computed(() => this.visibleColumns().length > 0);
142
- this.hasCustomLastColumn = signal(false);
150
+ this.hasCustomLastColumn = computed(() => this.columnCustomLastComponent || this.columnCustomLastTemplate());
143
151
  this.hasLastColumn = computed(() => this.hasCustomLastColumn() || this.areColumnsToggleable() || this.areColumnsReorderable());
144
152
  // layout prefs
145
153
  this.areColumnsReorderable = computed(() => this.descriptor().columns.some(value => value.isReorderable));
146
154
  this.areColumnsToggleable = computed(() => this.descriptor().columns.some(value => value.isToggleable));
147
- this.layoutPreferences = { columnWidths: {} };
148
- this.localstorageKey = '';
149
155
  // other
150
156
  this.routerIsNavigationOutsideInProgress = false;
151
- }
152
- ngOnInit() {
153
- this.setMainAndRelatedDescriptors(this.descriptorInput);
154
- const descriptor = this.descriptor();
155
- // map row settings
156
- if (Array.isArray(descriptor.rowsPerPageOptions) && descriptor.rowsPerPageOptions.length > 0) {
157
- this.dataListService.rowsPerPageOptions.set(descriptor.rowsPerPageOptions);
158
- }
159
- if (descriptor.defaultNumRows) {
160
- this.dataListService.rows.set(this.dataListService.rowsPerPageOptions().includes(descriptor.defaultNumRows) ? descriptor.defaultNumRows : this.dataListService.rowsPerPageOptions()[0]);
161
- }
162
- // other
163
- this.hasCustomLastColumn.set(this.columnCustomLastComponent !== undefined || this.columnCustomLastTemplate() !== undefined);
164
- // define all styles
165
- let className = descriptor.className ?? '';
166
- switch (descriptor.size) {
167
- case TableSizeEnum.Small:
168
- className += ' p-datatable-sm';
169
- break;
170
- case TableSizeEnum.Large:
171
- className += ' p-datatable-lg';
172
- break;
173
- }
174
- if (descriptor.hasGridlines) {
175
- className += ' p-datatable-gridlines';
176
- }
177
- this.className.set(className ?? '');
178
- // check if infinite scroll
179
- let paginationMode = TablePaginationModeEnum.None;
180
- if (typeof descriptor.paginationMode !== 'undefined') {
181
- // descriptor choice is the most strong - if defined, use this value
182
- paginationMode = descriptor.paginationMode;
183
- }
184
- else if (typeof this.dataProvider !== 'undefined') {
185
- // when data provider is used, use pagination
186
- paginationMode = TablePaginationModeEnum.Pagination;
187
- }
188
- if (paginationMode === TablePaginationModeEnum.InfiniteScroll) {
189
- this.infiniteScroll.set(true);
190
- this.tableFullHeightOffset.set(descriptor?.tableFullHeightOffset ?? 315);
191
- this.rowHeight.set(descriptor?.rowHeight ?? 45);
192
- this.useQueryParams = false;
193
- }
194
- else if (paginationMode === TablePaginationModeEnum.Pagination) {
195
- this.isPagination.set(true);
196
- }
197
- // check if data provider is supplied, if is, use it primarily
198
- if (this.dataProvider) {
199
- // map subjects to observables and initiate data
200
- this.useDataProvider = true;
201
- this.isLazy.set(this.dataProvider.isLazy);
202
- // inject service
203
- if (this.dataProvider.serviceType) {
204
- this.dataProviderService = this.injector.get(this.dataProvider.serviceType);
157
+ effect(() => {
158
+ const descriptor = this.descriptor();
159
+ if (Array.isArray(descriptor.rowsPerPageOptions) && descriptor.rowsPerPageOptions.length > 0) {
160
+ this.dataListService.rowsPerPageOptions.set(descriptor.rowsPerPageOptions);
205
161
  }
206
- this.dataProvider.getAllReload$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
207
- next: () => {
208
- this.reload();
162
+ if (descriptor.defaultNumRows) {
163
+ this.dataListService.rows.set(this.dataListService.rowsPerPageOptions().includes(descriptor.defaultNumRows) ? descriptor.defaultNumRows : this.dataListService.rowsPerPageOptions()[0]);
164
+ }
165
+ }, { allowSignalWrites: true });
166
+ effect(() => {
167
+ const loading = this.loadingInput();
168
+ if (loading !== undefined) {
169
+ this.dataListService.loading.set(loading);
170
+ }
171
+ }, { allowSignalWrites: true });
172
+ effect(() => {
173
+ const result = this.result();
174
+ if (result !== undefined) {
175
+ this.dataListService.data.set(result.data);
176
+ this.dataListService.count.set(result.totalCount ?? result.data.length);
177
+ const loading = this.loadingInput();
178
+ if (loading == undefined) {
179
+ // only set if input is not defined
180
+ this.dataListService.loading.set(false);
209
181
  }
210
- });
211
- }
212
- else {
213
- // if query result is provided, use it as secondary source or else try to use items
214
- if (this.result) {
215
- this.subscribeToQueryInput();
216
182
  }
217
- else if (this.items) {
218
- this.subscribeToItemsInput();
183
+ }, { allowSignalWrites: true });
184
+ effect(() => {
185
+ const result = this.result();
186
+ const items = this.items();
187
+ if (result == undefined && items !== undefined) {
188
+ this.dataListService.data.set(items);
189
+ this.dataListService.count.set(items.length);
190
+ const loading = this.loadingInput();
191
+ if (loading == undefined) {
192
+ // only set if input is not defined
193
+ this.dataListService.loading.set(false);
194
+ }
219
195
  }
220
- if (this.loadingInput) {
221
- this.loadingInput.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(res => this.dataListService.loading.set(res));
196
+ }, { allowSignalWrites: true });
197
+ effect(() => {
198
+ this.dataListService.globalFilterFields.set(this.globalFilterFieldsInput() ?? this.columns().map(c => c.descriptor.property));
199
+ }, { allowSignalWrites: true });
200
+ afterNextRender(() => {
201
+ this.isCellClickObserved.set(this.cellClickSubject.observed);
202
+ });
203
+ toObservable(this.dataProvider)
204
+ .pipe(switchMap(dp => dp?.getAllReload$ ?? of({})))
205
+ .subscribe({
206
+ next: () => {
207
+ this.reload();
222
208
  }
223
- }
224
- this.initializeDataLoadingTriggers();
225
- }
226
- ngOnChanges(changes) {
227
- if (changes['result'] && !changes['result'].firstChange) {
228
- this.subscribeToQueryInput();
229
- }
230
- if (changes['items'] && !changes['items'].firstChange) {
231
- this.subscribeToItemsInput();
232
- }
233
- if (changes['globalFilterFieldsInput'] && !changes['globalFilterFieldsInput'].firstChange) {
234
- this.dataListService.globalFilterFields.set(changes['globalFilterFieldsInput'].currentValue ?? this.columns().map(c => c.descriptor.property));
235
- }
209
+ });
210
+ combineLatest([toObservable(this.descriptorInput), toObservable(this.dataProvider), toObservable(this.useQueryParams)])
211
+ .pipe(
212
+ // dataProvider is needed to ensure correct order of execution and reload
213
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
214
+ switchMap(([descriptorInput, dataProvider, useQueryParams]) => {
215
+ if (descriptorInput !== this.descriptor()) {
216
+ this.descriptor.set(descriptorInput);
217
+ }
218
+ if (useQueryParams) {
219
+ // trigger table loads from route updates
220
+ return this.route.queryParams;
221
+ }
222
+ else {
223
+ return of(null);
224
+ }
225
+ }))
226
+ .subscribe(qp => {
227
+ if (qp === null) {
228
+ // load data immediately by creating default sorts and filters (primeng will trigger onLazyLoad event on sort&filter metadata change)
229
+ const defaultSort = this.createSortMeta(this.defaultParams());
230
+ if (!defaultSort || defaultSort.length > 0) {
231
+ this.dataListService.sortMeta.set(defaultSort);
232
+ }
233
+ const defaultFilter = this.createFilterMeta();
234
+ if (defaultFilter) {
235
+ this.dataListService.filterMeta.set(defaultFilter);
236
+ }
237
+ this.loadTableWithDataProvider({});
238
+ }
239
+ else {
240
+ this.loadTableFromRouteUpdate(qp);
241
+ }
242
+ });
243
+ toObservable(this.useQueryParams)
244
+ .pipe(switchMap(useQp => (useQp ? this.router.events : NEVER)), filter(e => (e instanceof NavigationStart && e.url.split('?')[0].split('#')[0] !== this.router.url.split('?')[0].split('#')[0]) ||
245
+ e instanceof NavigationEnd ||
246
+ e instanceof NavigationCancel ||
247
+ e instanceof NavigationError))
248
+ .subscribe(e => {
249
+ this.routerIsNavigationOutsideInProgress = e instanceof NavigationStart;
250
+ });
236
251
  }
237
252
  ngOnDestroy() {
238
253
  this.dataProviderSubscription?.unsubscribe();
239
- this.resultSubscription?.unsubscribe();
240
- this.itemsSubscription?.unsubscribe();
241
254
  }
242
255
  reload(emitEvent = false, resetParams = false) {
243
256
  const paramsWithDefaults = resetParams || !this.latestParamsWithDefaults ? this.defaultParams() : mergeDataListParamsWithDefaults(this.latestParamsWithDefaults, this.defaultParams());
@@ -247,7 +260,7 @@ export class TableComponent {
247
260
  this.dataProviderLatestLazyLoadEvent = event;
248
261
  this.latestLazyLoadEventVersion++;
249
262
  const params = fromTableLoadToDataListParams(event);
250
- if (this.useQueryParams) {
263
+ if (this.useQueryParams()) {
251
264
  if (!this.routerIsNavigationOutsideInProgress) {
252
265
  // this check is necessary: from some reason, primeNG commits one last lazy load event whenever any angular router navigation occurs
253
266
  this.router.navigate([], {
@@ -270,16 +283,19 @@ export class TableComponent {
270
283
  this.isFilterChanged = true;
271
284
  }
272
285
  onCellClick(event, col, item, idx) {
286
+ if (!this.isCellClickEnabled()) {
287
+ return;
288
+ }
273
289
  const tableEvent = {
274
290
  column: col,
275
291
  rowItem: item,
276
292
  rowIndex: idx,
277
293
  event: event
278
294
  };
279
- this.cellClickEventEmitter.next(tableEvent);
295
+ this.cellClickSubject.next(tableEvent);
280
296
  }
281
297
  onSelectionChange(event) {
282
- this.selectionChangeEventEmitter.emit(event);
298
+ this.selectionChange.emit(event);
283
299
  }
284
300
  /**
285
301
  * Method is called on column resize
@@ -288,26 +304,29 @@ export class TableComponent {
288
304
  onTableColumnResize({ element }) {
289
305
  const fieldId = element.id;
290
306
  const width = element.offsetWidth;
307
+ const layoutPrefs = this.layoutPreferences();
291
308
  const col = this.columns().find(el => el.descriptor.property === fieldId);
292
309
  if (col)
293
310
  col.width = width;
294
- if (!this.layoutPreferences.columnWidths)
295
- this.layoutPreferences.columnWidths = {};
296
- this.layoutPreferences.columnWidths[fieldId] = width;
297
- this.saveLayoutPreferences();
311
+ if (!layoutPrefs.columnWidths)
312
+ layoutPrefs.columnWidths = {};
313
+ layoutPrefs.columnWidths[fieldId] = width;
314
+ this.saveLayoutPreferences(layoutPrefs);
298
315
  }
299
316
  loadTableWithDataProvider(paramsWithDefaults, emitEvent = true) {
300
- if (!this.useDataProvider || !this.dataProvider) {
317
+ const dataProvider = this.dataProvider();
318
+ if (!dataProvider || paramsWithDefaults.limit === 0) {
301
319
  return;
302
320
  }
303
321
  this.dataProviderSubscription?.unsubscribe();
304
322
  this.dataListService.loading.set(true);
305
323
  this.latestParamsWithDefaults = paramsWithDefaults;
306
324
  this.latestParamsWithDefaultsVersion++;
307
- this.dataProviderSubscription = toObservable(this.dataProvider.getAll(paramsWithDefaults, this.dataProviderService, this.descriptor().isLocalized ? this.commons.appDataLocale() ?? undefined : undefined)).subscribe({
325
+ this.dataProviderSubscription = commonsToObservable(dataProvider.getAll(paramsWithDefaults, this.dataProviderService(), this.descriptor().isLocalized ? this.commons.appDataLocale() ?? undefined : undefined)).subscribe({
308
326
  next: res => {
309
- if (this.descriptorInput instanceof TableDynamicDescriptorInst) {
310
- this.setMainAndRelatedDescriptors(this.descriptorInput.toTableDescriptorFromData(res));
327
+ const descriptorInput = this.descriptorInput();
328
+ if (descriptorInput instanceof TableDynamicDescriptorInst) {
329
+ this.descriptor.set(descriptorInput.toTableDescriptorFromData(res));
311
330
  }
312
331
  if (this.infiniteScroll()) {
313
332
  let items = this.dataListService.data();
@@ -341,7 +360,7 @@ export class TableComponent {
341
360
  originalEvent: this.dataProviderLatestLazyLoadEvent,
342
361
  params: paramsWithDefaults
343
362
  };
344
- this.loadEventEmitter.next(tableEvent);
363
+ this.tableLoad.emit(tableEvent);
345
364
  }
346
365
  }
347
366
  loadTableFromRouteUpdate(urlParams) {
@@ -353,57 +372,6 @@ export class TableComponent {
353
372
  this.useQueryParamsInitialized.set(true);
354
373
  this.loadTableWithDataProvider(paramsWithDefaults);
355
374
  }
356
- setMainAndRelatedDescriptors(descriptor) {
357
- if (descriptor instanceof TableDynamicDescriptorInst) {
358
- this.descriptor.set(descriptor);
359
- this.columns.set([]);
360
- return;
361
- }
362
- // get layout preferences if they exist
363
- if (descriptor.model.typeName) {
364
- this.localstorageKey = generateTableLayoutPrefsKey(descriptor.model.typeName, this.router.url, descriptor.identifier);
365
- const preferences = this.localStorageService.getItem(this.cmpTypeName, this.localstorageKey);
366
- if (preferences && typeof preferences === 'object') {
367
- if (preferences.columnWidths) {
368
- this.layoutPreferences.columnWidths = preferences.columnWidths;
369
- }
370
- if (preferences.columnOrder && Array.isArray(preferences.columnOrder) && preferences.columnOrder.every((el) => typeof el === 'string')) {
371
- this.layoutPreferences.columnOrder = preferences.columnOrder;
372
- }
373
- if (preferences.columnVisibility && Array.isArray(preferences.columnVisibility) && preferences.columnVisibility.every((el) => typeof el === 'string')) {
374
- this.layoutPreferences.columnVisibility = preferences.columnVisibility;
375
- }
376
- }
377
- }
378
- else {
379
- this.localstorageKey = '';
380
- this.layoutPreferences = { columnWidths: {} };
381
- }
382
- // initialize columns with additional properties
383
- const timestamp = new Date().getTime();
384
- let columns = descriptor.columns.map(col => ({
385
- id: `${col.property}-${timestamp}`,
386
- descriptor: col,
387
- filter: descriptor.filters.find(f => f.showOnColumn === col.property),
388
- sort: descriptor.sorts.find(f => f.showOnColumn === col.property),
389
- disabled: !col.isToggleable,
390
- isVisible: this.layoutPreferences.columnVisibility ? this.layoutPreferences.columnVisibility.includes(col.property) : col.isVisible,
391
- width: this.layoutPreferences.columnWidths?.[col.property]
392
- }));
393
- if (this.layoutPreferences.columnOrder) {
394
- for (let i = 0; i < this.layoutPreferences.columnOrder.length; i++) {
395
- const colName = this.layoutPreferences.columnOrder[i];
396
- const colWithPrefs = columns.find(el => el.descriptor.property === colName);
397
- if (colWithPrefs) {
398
- colWithPrefs.orderIdx = i;
399
- }
400
- }
401
- }
402
- columns = columns.sort((a, b) => (a.orderIdx !== undefined && b.orderIdx !== undefined ? a.orderIdx - b.orderIdx : 0));
403
- this.descriptor.set(descriptor);
404
- this.columns.set(columns);
405
- this.dataListService.globalFilterFields.set(this.globalFilterFieldsInput ?? this.columns().map(c => c.descriptor.property));
406
- }
407
375
  updatePrimeSortAndFilter(paramsWithDefaults) {
408
376
  this.dataListService.sortMeta.set(this.createSortMeta(paramsWithDefaults));
409
377
  this.dataListService.filterMeta.set(this.createFilterMeta(paramsWithDefaults));
@@ -432,66 +400,32 @@ export class TableComponent {
432
400
  }
433
401
  return null;
434
402
  }
435
- initializeDataLoadingTriggers() {
436
- if (this.useQueryParams) {
437
- // trigger table loads from route updates
438
- this.route.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(qp => {
439
- this.loadTableFromRouteUpdate(qp);
440
- });
441
- this.router.events
442
- .pipe(takeUntilDestroyed(this.destroyRef), filter(e => (e instanceof NavigationStart && e.url.split('?')[0].split('#')[0] !== this.router.url.split('?')[0].split('#')[0]) ||
443
- e instanceof NavigationEnd ||
444
- e instanceof NavigationCancel ||
445
- e instanceof NavigationError))
446
- .subscribe(e => {
447
- this.routerIsNavigationOutsideInProgress = e instanceof NavigationStart;
448
- });
449
- }
450
- else {
451
- // load data immediately by creating default sorts and filters (primeng will trigger onLazyLoad event on sort&filter metadata change)
452
- const defaultSort = this.createSortMeta();
453
- if (!defaultSort || defaultSort.length > 0) {
454
- this.dataListService.sortMeta.set(defaultSort);
455
- }
456
- const defaultFilter = this.createFilterMeta();
457
- if (defaultFilter) {
458
- this.dataListService.filterMeta.set(defaultFilter);
459
- }
460
- }
461
- }
462
403
  onColumnToggle(event) {
463
- const timestamp = new Date().getTime();
464
- const columns = [...this.columns()];
465
- for (const col of columns) {
466
- const isVisible = event.value.includes(col);
467
- if (isVisible !== col.isVisible) {
468
- col.isVisible = isVisible;
469
- col.id = `${col.descriptor.property}-${timestamp}`;
470
- }
471
- }
472
- this.columns.set(columns);
473
- this.layoutPreferences.columnVisibility = this.visibleColumns().map(el => el.descriptor.property);
474
- this.saveLayoutPreferences();
404
+ const layoutPrefs = this.layoutPreferences();
405
+ const selectedColumns = event.value.map(v => v.descriptor.property);
406
+ const hiddenColumns = this.columns()
407
+ .filter(c => selectedColumns.indexOf(c.descriptor.property) < 0)
408
+ .map(c => c.descriptor.property);
409
+ layoutPrefs.columnHidden = hiddenColumns;
410
+ this.saveLayoutPreferences(layoutPrefs);
475
411
  }
476
412
  onColumnToggleAll() {
477
- const timestamp = new Date().getTime();
413
+ const layoutPrefs = this.layoutPreferences();
478
414
  const columns = [...this.columns()];
479
- const isVisible = !columns.some(c => c.isVisible);
415
+ const isVisible = !this.columns().some(c => c.isVisible);
480
416
  for (const col of columns) {
481
417
  if (isVisible !== col.isVisible) {
482
418
  col.isVisible = isVisible;
483
- col.id = `${col.descriptor.property}-${timestamp}`;
484
419
  }
485
420
  }
486
- this.columns.set(columns);
487
- this.layoutPreferences.columnVisibility = this.visibleColumns().map(el => el.descriptor.property);
488
- this.saveLayoutPreferences();
421
+ layoutPrefs.columnHidden = columns.filter(c => !c.isVisible).map(c => c.descriptor.property);
422
+ this.saveLayoutPreferences(layoutPrefs);
489
423
  }
490
424
  onColumnReorder(event) {
491
425
  if (event.dropIndex !== undefined && event.dropIndex >= 0 && event.dragIndex !== undefined && event.dragIndex >= 0 && event.dropIndex !== event.dragIndex) {
492
426
  const eventDropIndex = event.dropIndex;
493
427
  const eventDragIndex = event.dragIndex;
494
- const prevVisibleColumns = this.columns().filter(el => el.isVisible);
428
+ const prevVisibleColumns = this.columns().filter(c => c.isVisible);
495
429
  const colAtDrop = prevVisibleColumns[eventDropIndex];
496
430
  const colAtDrag = prevVisibleColumns[eventDragIndex];
497
431
  const colAtDropIndex = this.columns().findIndex(el => el.id === colAtDrop.id);
@@ -501,59 +435,112 @@ export class TableComponent {
501
435
  columns.splice(colAtDragIndex, 1);
502
436
  const dropIndex = columns.findIndex(el => el.id === colAtDrop.id) + (eventDropIndex > eventDragIndex ? 1 : 0);
503
437
  columns = [...columns.slice(0, dropIndex), colAtDrag, ...columns.slice(dropIndex)];
504
- const timestamp = new Date().getTime();
505
- for (let i = Math.min(eventDropIndex, eventDragIndex); i < columns.length; i++) {
506
- columns[i].id = `${columns[i].descriptor.property}-${timestamp}`;
507
- }
508
- this.columns.set(columns);
509
- this.layoutPreferences.columnOrder = columns.map(el => el.descriptor.property);
510
- this.saveLayoutPreferences();
438
+ const layoutPrefs = this.layoutPreferences();
439
+ layoutPrefs.columnOrder = columns.map(el => el.descriptor.property);
440
+ this.saveLayoutPreferences(layoutPrefs);
511
441
  }
512
442
  }
513
443
  }
514
- saveLayoutPreferences() {
515
- if (this.descriptor().model.typeName) {
516
- this.localStorageService.setItem(this.cmpTypeName, this.localstorageKey, this.layoutPreferences);
444
+ saveLayoutPreferences(layoutPrefs) {
445
+ const key = this.localstorageKey();
446
+ if (key) {
447
+ this.localStorageService.setItem(this.cmpTypeName, key, layoutPrefs);
448
+ this.layoutPrefsSaveCnt.update(v => v + 1);
517
449
  }
518
450
  }
519
- subscribeToQueryInput() {
520
- this.resultSubscription?.unsubscribe();
521
- if (!this.result) {
522
- return;
523
- }
524
- this.resultSubscription = this.result.subscribe(res => {
525
- this.dataListService.data.set(res?.data ?? []);
526
- this.dataListService.count.set(res?.totalCount ?? 0);
527
- this.dataListService.loading.set(false);
451
+ computeDefaultDataListParams() {
452
+ const params = {
453
+ offset: 0,
454
+ limit: this.dataListService.rowsPerPageOptions()[0],
455
+ sort: this.descriptor()
456
+ .sorts.filter(s => s.defaultIsEnabled)
457
+ .map(s => ({
458
+ property: s.property,
459
+ ascending: s.defaultIsAscending
460
+ })),
461
+ filters: {}
462
+ };
463
+ this.filterDescriptors()
464
+ .filter(d => d.hasDefaultValue)
465
+ .forEach(f => {
466
+ let matchMode = f.defaultMatchMode;
467
+ if (!matchMode) {
468
+ switch (f.filterType) {
469
+ case FilterTypeEnum.String:
470
+ matchMode = FilterMatchMode.Contains;
471
+ break;
472
+ case FilterTypeEnum.Lookup:
473
+ case FilterTypeEnum.LookupEnum: {
474
+ const lookupFilter = f;
475
+ if (lookupFilter.multiselect) {
476
+ matchMode = FilterMatchMode.In;
477
+ }
478
+ break;
479
+ }
480
+ default:
481
+ break;
482
+ }
483
+ }
484
+ if (!matchMode) {
485
+ matchMode = FilterMatchMode.Equals;
486
+ }
487
+ if (f.matchModes && !f.matchModes?.includes(matchMode)) {
488
+ matchMode = f.matchModes[0];
489
+ }
490
+ let value = undefined;
491
+ if (Array.isArray(value)) {
492
+ value = [...value];
493
+ }
494
+ else {
495
+ value = f.defaultValue;
496
+ }
497
+ const property = f.property;
498
+ params.filters[property] = {
499
+ value: value,
500
+ matchMode: matchMode
501
+ };
528
502
  });
503
+ return params;
529
504
  }
530
- subscribeToItemsInput() {
531
- this.itemsSubscription?.unsubscribe();
532
- if (!this.items) {
533
- return;
505
+ computColumnsWithLayout() {
506
+ const descriptor = this.descriptor();
507
+ const layoutPrefs = this.layoutPreferences();
508
+ // initialize columns with additional properties
509
+ const timestamp = new Date().getTime();
510
+ const columns = descriptor.columns.map(col => ({
511
+ id: `${col.property}-${timestamp}`,
512
+ descriptor: col,
513
+ filter: descriptor.filters.find(f => f.showOnColumn === col.property),
514
+ sort: descriptor.sorts.find(f => f.showOnColumn === col.property),
515
+ disabled: !col.isToggleable,
516
+ isVisible: layoutPrefs.columnHidden ? !layoutPrefs.columnHidden.includes(col.property) : col.isVisible,
517
+ width: layoutPrefs.columnWidths?.[col.property]
518
+ }));
519
+ if (layoutPrefs.columnOrder) {
520
+ for (let i = 0; i < layoutPrefs.columnOrder.length; i++) {
521
+ const colName = layoutPrefs.columnOrder[i];
522
+ const colWithPrefs = columns.find(el => el.descriptor.property === colName);
523
+ if (colWithPrefs) {
524
+ colWithPrefs.orderIdx = i;
525
+ }
526
+ }
534
527
  }
535
- this.itemsSubscription = this.items.subscribe(qr => {
536
- this.dataListService.data.set(qr);
537
- this.dataListService.count.set(qr.length);
538
- this.dataListService.loading.set(false);
539
- });
528
+ return columns.sort((a, b) => (a.orderIdx !== undefined && b.orderIdx !== undefined ? a.orderIdx - b.orderIdx : 0));
540
529
  }
541
530
  /**
542
531
  * Reset column order and column visibility to default settings
543
532
  */
544
533
  resetDefaultLayout() {
545
- const timestamp = new Date().getTime();
546
- const columns = this.descriptor().columns.map(col => ({ id: `${col.property}-${timestamp}`, descriptor: col, disabled: !col.isToggleable, isVisible: col.isVisible }));
547
- this.columns.set(columns);
548
- if (this.descriptor().model.typeName) {
549
- this.localStorageService.removeItem(this.cmpTypeName, this.localstorageKey);
534
+ const key = this.localstorageKey();
535
+ if (key) {
536
+ this.localStorageService.removeItem(this.cmpTypeName, key);
537
+ this.layoutPrefsSaveCnt.update(v => v + 1);
550
538
  }
551
- this.layoutPreferences = {};
552
539
  }
553
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
554
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: TableComponent, isStandalone: true, selector: "mng-table", inputs: { descriptorInput: ["descriptor", "descriptorInput"], items: ["items", "items", (value) => (value == null ? undefined : isObservable(value) ? value : of(value))], result: ["result", "result", (value) => (value == null ? undefined : isObservable(value) ? value : of(value))], loadingInput: ["loading", "loadingInput", boolean$Attribute], dataProvider: "dataProvider", useQueryParams: "useQueryParams", selectionMode: "selectionMode", selectionEnabled: "selectionEnabled", columnLastMinWidth: "columnLastMinWidth", captionComponent: "captionComponent", columnCustomLastComponent: "columnCustomLastComponent", globalFilterFieldsInput: ["globalFilterFields", "globalFilterFieldsInput"] }, outputs: { loadEventEmitter: "tableLoad", cellClickEventEmitter: "cellClick", selectionChangeEventEmitter: "selectionChange", captionCmpInstEventEmitter: "captionComponentInstance", columnCustomLastCmpInstEventEmitter: "columnCustomLastComponentInstance" }, providers: [DataListService], queries: [{ propertyName: "templates", predicate: TemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "primeTable", first: true, predicate: Table, descendants: true }, { propertyName: "components", predicate: ComponentDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [style.height]=\"tableFullHeightOffset() ? 'calc(100vh - ' + tableFullHeightOffset() + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination() && !infiniteScroll()\"\n [rows]=\"infiniteScroll() ? 20 : dataListService.rows()\"\n [first]=\"infiniteScroll() ? 0 : dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"infiniteScroll() ? undefined : dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"!infiniteScroll()\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled ? selectionMode : null\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll()\"\n [virtualScrollItemSize]=\"rowHeight()\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n @if (captionTemplate() || captionComponent || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent) {\n <div [mngComponent]=\"captionComponent\" (instanceCreated)=\"captionCmpInstEventEmitter.next($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n @if (selectionEnabled) {\n @if (selectionMode === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [style.height.px]=\"rowHeight\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled) {\n @if (selectionMode === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"cellClickEventEmitter.observed\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent) {\n <div [mngComponent]=\"columnCustomLastComponent\" (instanceCreated)=\"columnCustomLastCmpInstEventEmitter.next($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n", dependencies: [{ kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "pipe", type: I18nPropertyPipe, name: "mngI18nProperty" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TableColumnValueComponent, selector: "mng-table-column-value", inputs: ["descriptor", "item"] }, { kind: "pipe", type: ClassMapPipe, name: "mngClassMap" }, { kind: "pipe", type: LocaleDefaultRowClassPipe, name: "mngLocaleDefaultRowClass" }, { kind: "component", type: TableColumnFilterFullComponent, selector: "mng-table-column-filter-full", inputs: ["descriptor"] }, { kind: "pipe", type: TableColumnFilterClassPipe, name: "mngTableColumnFilterClass" }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i1.RowToggler, selector: "[pRowToggler]", inputs: ["pRowToggler", "pRowTogglerDisabled"] }, { kind: "directive", type: i1.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "directive", type: i1.ReorderableColumn, selector: "[pReorderableColumn]", inputs: ["pReorderableColumnDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i1.TableRadioButton, selector: "p-tableRadioButton", inputs: ["disabled", "value", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i1.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i1.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i3.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "size", "style", "styleClass", "badgeClass", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
540
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
541
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TableComponent, isStandalone: true, selector: "mng-table", inputs: { descriptorInput: { classPropertyName: "descriptorInput", publicName: "descriptor", isSignal: true, isRequired: true, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, result: { classPropertyName: "result", publicName: "result", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, dataProvider: { classPropertyName: "dataProvider", publicName: "dataProvider", isSignal: true, isRequired: false, transformFunction: null }, useQueryParamsInput: { classPropertyName: "useQueryParamsInput", publicName: "useQueryParams", isSignal: true, isRequired: false, transformFunction: null }, cellClickEnabled: { classPropertyName: "cellClickEnabled", publicName: "cellClickEnabled", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selectionEnabled: { classPropertyName: "selectionEnabled", publicName: "selectionEnabled", isSignal: true, isRequired: false, transformFunction: null }, columnLastMinWidth: { classPropertyName: "columnLastMinWidth", publicName: "columnLastMinWidth", isSignal: true, isRequired: false, transformFunction: null }, captionComponent: { classPropertyName: "captionComponent", publicName: "captionComponent", isSignal: true, isRequired: false, transformFunction: null }, columnCustomLastComponent: { classPropertyName: "columnCustomLastComponent", publicName: "columnCustomLastComponent", isSignal: true, isRequired: false, transformFunction: null }, globalFilterFieldsInput: { classPropertyName: "globalFilterFieldsInput", publicName: "globalFilterFields", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tableLoad: "tableLoad", cellClick: "cellClick", selectionChange: "selectionChange", captionComponentInstance: "captionComponentInstance", columnCustomLastComponentInstance: "columnCustomLastComponentInstance" }, providers: [DataListService], queries: [{ propertyName: "templates", predicate: TemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "components", predicate: (ComponentDirective), descendants: true, isSignal: true }, { propertyName: "primeTable", first: true, predicate: Table, descendants: true, isSignal: true }], ngImport: i0, template: "<div [style.height]=\"tableFullHeightOffset() ? 'calc(100vh - ' + tableFullHeightOffset() + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams() || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination() && !infiniteScroll()\"\n [rows]=\"infiniteScroll() ? 20 : dataListService.rows()\"\n [first]=\"infiniteScroll() ? 0 : dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"infiniteScroll() ? undefined : dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"!infiniteScroll()\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll()\"\n [virtualScrollItemSize]=\"rowHeight()\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n @if (captionTemplate() || captionComponent() || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent()) {\n <div [mngComponent]=\"captionComponent()\" (instanceCreated)=\"captionComponentInstance.emit($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [style.height.px]=\"rowHeight()\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent()) {\n <div [mngComponent]=\"columnCustomLastComponent()\" (instanceCreated)=\"columnCustomLastComponentInstance.emit($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled() ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled() ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n", dependencies: [{ kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "pipe", type: I18nPropertyPipe, name: "mngI18nProperty" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TableColumnValueComponent, selector: "mng-table-column-value", inputs: ["descriptor", "item"] }, { kind: "pipe", type: ClassMapPipe, name: "mngClassMap" }, { kind: "pipe", type: LocaleDefaultRowClassPipe, name: "mngLocaleDefaultRowClass" }, { kind: "component", type: TableColumnFilterFullComponent, selector: "mng-table-column-filter-full", inputs: ["descriptor"] }, { kind: "pipe", type: TableColumnFilterClassPipe, name: "mngTableColumnFilterClass" }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i1.RowToggler, selector: "[pRowToggler]", inputs: ["pRowToggler", "pRowTogglerDisabled"] }, { kind: "directive", type: i1.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "directive", type: i1.ReorderableColumn, selector: "[pReorderableColumn]", inputs: ["pReorderableColumnDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i1.TableRadioButton, selector: "p-tableRadioButton", inputs: ["disabled", "value", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i1.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i1.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i3.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
555
542
  }
556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: TableComponent, decorators: [{
543
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TableComponent, decorators: [{
557
544
  type: Component,
558
545
  args: [{ standalone: true, selector: 'mng-table', imports: [
559
546
  AsyncPipe,
@@ -573,58 +560,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
573
560
  TooltipModule,
574
561
  TranslateModule,
575
562
  FormsModule
576
- ], providers: [DataListService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [style.height]=\"tableFullHeightOffset() ? 'calc(100vh - ' + tableFullHeightOffset() + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination() && !infiniteScroll()\"\n [rows]=\"infiniteScroll() ? 20 : dataListService.rows()\"\n [first]=\"infiniteScroll() ? 0 : dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"infiniteScroll() ? undefined : dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"!infiniteScroll()\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled ? selectionMode : null\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll()\"\n [virtualScrollItemSize]=\"rowHeight()\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n @if (captionTemplate() || captionComponent || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent) {\n <div [mngComponent]=\"captionComponent\" (instanceCreated)=\"captionCmpInstEventEmitter.next($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n @if (selectionEnabled) {\n @if (selectionMode === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [style.height.px]=\"rowHeight\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled) {\n @if (selectionMode === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"cellClickEventEmitter.observed\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent) {\n <div [mngComponent]=\"columnCustomLastComponent\" (instanceCreated)=\"columnCustomLastCmpInstEventEmitter.next($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n" }]
577
- }], propDecorators: { descriptorInput: [{
578
- type: Input,
579
- args: [{ required: true, alias: 'descriptor' }]
580
- }], items: [{
581
- type: Input,
582
- args: [{ transform: (value) => (value == null ? undefined : isObservable(value) ? value : of(value)) }]
583
- }], result: [{
584
- type: Input,
585
- args: [{
586
- transform: (value) => (value == null ? undefined : isObservable(value) ? value : of(value))
587
- }]
588
- }], loadingInput: [{
589
- type: Input,
590
- args: [{ alias: 'loading', transform: boolean$Attribute }]
591
- }], dataProvider: [{
592
- type: Input
593
- }], useQueryParams: [{
594
- type: Input
595
- }], selectionMode: [{
596
- type: Input
597
- }], selectionEnabled: [{
598
- type: Input
599
- }], columnLastMinWidth: [{
600
- type: Input
601
- }], captionComponent: [{
602
- type: Input
603
- }], columnCustomLastComponent: [{
604
- type: Input
605
- }], globalFilterFieldsInput: [{
606
- type: Input,
607
- args: ['globalFilterFields']
608
- }], loadEventEmitter: [{
609
- type: Output,
610
- args: ['tableLoad']
611
- }], cellClickEventEmitter: [{
612
- type: Output,
613
- args: ['cellClick']
614
- }], selectionChangeEventEmitter: [{
615
- type: Output,
616
- args: ['selectionChange']
617
- }], captionCmpInstEventEmitter: [{
618
- type: Output,
619
- args: ['captionComponentInstance']
620
- }], columnCustomLastCmpInstEventEmitter: [{
621
- type: Output,
622
- args: ['columnCustomLastComponentInstance']
623
- }], components: [{
624
- type: ViewChildren,
625
- args: [ComponentDirective]
626
- }], primeTable: [{
627
- type: ViewChild,
628
- args: [Table]
629
- }] } });
630
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDOUUsT0FBTyxFQUNILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixRQUFRLEVBQ1IsS0FBSyxFQUlMLE1BQU0sRUFDTixTQUFTLEVBSVQsSUFBSSxFQUNKLFNBQVMsRUFDVCxZQUFZLEVBQ1osUUFBUSxFQUNSLGVBQWUsRUFDZixNQUFNLEVBQ04sTUFBTSxFQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUMsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFVLE1BQU0sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBRWxJLE9BQU8sRUFBQyxlQUFlLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEVBQWlCLGNBQWMsRUFBVyxNQUFNLGFBQWEsQ0FBQztBQUNyRSxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUF5QixpQkFBaUIsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQzlFLE9BQU8sRUFBQyxLQUFLLEVBQStDLFdBQVcsRUFBQyxNQUFNLGVBQWUsQ0FBQztB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LENBQUMsQ0FBQyxFQUFDO2dCQU14SSxNQUFNO3NCQUhaLEtBQUs7dUJBQUM7d0JBQ0gsU0FBUyxFQUFFLENBQUMsS0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBRSxLQUEwQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBNkIsQ0FBQyxDQUFDO3FCQUNySztnQkFFK0QsWUFBWTtzQkFBM0UsS0FBSzt1QkFBQyxFQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFDO2dCQUN2QyxZQUFZO3NCQUEzQixLQUFLO2dCQUNVLGNBQWM7c0JBQTdCLEtBQUs7Z0JBR1UsYUFBYTtzQkFBNUIsS0FBSztnQkFDVSxnQkFBZ0I7c0JBQS9CLEtBQUs7Z0JBR1Usa0JBQWtCO3NCQUFqQyxLQUFLO2dCQUdVLGdCQUFnQjtzQkFBL0IsS0FBSztnQkFDVSx5QkFBeUI7c0JBQXhDLEtBQUs7Z0JBQzhCLHVCQUF1QjtzQkFBMUQsS0FBSzt1QkFBQyxvQkFBb0I7Z0JBR0MsZ0JBQWdCO3NCQUEzQyxNQUFNO3VCQUFDLFdBQVc7Z0JBQ1MscUJBQXFCO3NCQUFoRCxNQUFNO3VCQUFDLFdBQVc7Z0JBQ2UsMkJBQTJCO3NCQUE1RCxNQUFNO3VCQUFDLGlCQUFpQjtnQkFDa0IsMEJBQTBCO3NCQUFwRSxNQUFNO3VCQUFDLDBCQUEwQjtnQkFDa0IsbUNBQW1DO3NCQUF0RixNQUFNO3VCQUFDLG1DQUFtQztnQkFJRixVQUFVO3NCQUFsRCxZQUFZO3VCQUFDLGtCQUFrQjtnQkFDUCxVQUFVO3NCQUFsQyxTQUFTO3VCQUFDLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FzeW5jUGlwZSwgTmdDbGFzcywgTmdTdHlsZSwgTmdUZW1wbGF0ZU91dGxldH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ29tcG9uZW50LFxuICAgIERlc3Ryb3lSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIEluamVjdG9yLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT25Jbml0LFxuICAgIE91dHB1dCxcbiAgICBRdWVyeUxpc3QsXG4gICAgU2lnbmFsLFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVHlwZSxcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuLFxuICAgIGNvbXB1dGVkLFxuICAgIGNvbnRlbnRDaGlsZHJlbixcbiAgICBpbmplY3QsXG4gICAgc2lnbmFsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHt0YWtlVW50aWxEZXN0cm95ZWR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7Rm9ybXNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7QWN0aXZhdGVkUm91dGUsIE5hdmlnYXRpb25DYW5jZWwsIE5hdmlnYXRpb25FbmQsIE5hdmlnYXRpb25FcnJvciwgTmF2aWdhdGlvblN0YXJ0LCBQYXJhbXMsIFJvdXRlcn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcblxuaW1wb3J0IHtUcmFuc2xhdGVNb2R1bGUsIFRyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtGaWx0ZXJNZXRhZGF0YSwgTWVzc2FnZVNlcnZpY2UsIFNvcnRNZXRhfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQge0J1dHRvbk1vZHVsZX0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHtNdWx0aVNlbGVjdENoYW5nZUV2ZW50LCBNdWx0aVNlbGVjdE1vZHVsZX0gZnJvbSAncHJpbWVuZy9tdWx0aXNlbGVjdCc7XG5pbXBvcnQge1RhYmxlLCBUYWJsZUNvbHVtblJlb3JkZXJFdmVudCwgVGFibGVMYXp5TG9hZEV2ZW50LCBUYWJsZU1vZHVsZX0gZnJvbSAncHJpbWVuZy90YWJsZSc7XG5pbXBvcnQge1Rvb2x0aXBNb2R1bGV9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5pbXBvcnQge09ic2VydmFibGUsIFN1YnNjcmlwdGlvbiwgaXNPYnNlcnZhYmxlLCBvZn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2ZpbHRlcn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge1xuICAgIENsYXNzTWFwUGlwZSxcbiAgICBDb21tb25zU2VydmljZSxcbiAgICBDb21wb25lbnREaXJlY3RpdmUsXG4gICAgRGF0YUxpc3RQYXJhbXMsXG4gICAgRGF0YUxpc3RSZXN1bHQsXG4gICAgRmlsdGVyTWF0Y2hNb2RlLFxuICAgIEkxOG5Qcm9wZXJ0eVBpcGUsXG4gICAgTG9jYWxTdG9yYWdlU2VydmljZSxcbiAgICBMb2dnZXJTZXJ2aWNlLFxuICAgIFRlbXBsYXRlRGlyZWN0aXZlLFxuICAgIGJvb2xlYW4kQXR0cmlidXRlLFxuICAgIGRhdGFMaXN0UGFyYW1zVG9VcmxRdWVyeSxcbiAgICBmaW5kVGVtcGxhdGVCeU5hbWUsXG4gICAgZnJvbVN1YnNjcmliZUVycm9yLFxuICAgIGZyb21UYWJsZUxvYWRUb0RhdGFMaXN0UGFyYW1zLFxuICAgIGZyb21VcmxRdWVyeVRvRGF0YUxpc3RQYXJhbXMsXG4gICAgZ2V0RXJyb3JMb2dMZXZlbCxcbiAgICBtZXJnZURhdGFMaXN0UGFyYW1zV2l0aERlZmF1bHRzLFxuICAgIHRvT2JzZXJ2YWJsZVxufSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL2NvcmUnO1xuaW1wb3J0IHtGaWx0ZXJMb29rdXBEZXNjcmlwdG9yLCBGaWx0ZXJUeXBlRW51bX0gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy9maWx0ZXInO1xuaW1wb3J0IHtcbiAgICBDb2x1bW5EZXNjcmlwdG9yLFxuICAgIElUYWJsZURhdGFQcm92aWRlcixcbiAgICBUYWJsZUNlbGxDbGlja0V2ZW50LFxuICAgIFRhYmxlRGVzY3JpcHRvckluc3QsXG4gICAgVGFibGVEeW5hbWljRGVzY3JpcHRvckluc3QsXG4gICAgVGFibGVMYXlvdXRQcmVmZXJlbmNlcyxcbiAgICBUYWJsZUxvYWRFdmVudCxcbiAgICBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bSxcbiAgICBUYWJsZVNpemVFbnVtLFxuICAgIHRhYmxlRGVzY3JpcHRvclxufSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL3RhYmxlL2FwaSc7XG5cbmltcG9ydCB7dGFibGVOb3RpZmljYXRpb25FcnJvcn0gZnJvbSAnLi4vLi4vaGVscGVycy9ub3RpZmljYXRpb24nO1xuaW1wb3J0IHtnZW5lcmF0ZVRhYmxlTGF5b3V0UHJlZnNLZXl9IGZyb20gJy4uLy4uL2hlbHBlcnMvdGFibGUtbGF5b3V0LXByZWZzJztcbmltcG9ydCB7Q29sdW1uV2l0aFByZWZlcmVuY2VzfSBmcm9tICcuLi8uLi9tb2RlbHMvY29sdW1uLXByZWZlcmVuY2VzLm1vZGVsJztcbmltcG9ydCB7TG9jYWxlRGVmYXVsdFJvd0NsYXNzUGlwZX0gZnJvbSAnLi4vLi4vcGlwZXMvbG9jYWxlLWRlZmF1bHQtcm93LWNsYXNzLnBpcGUnO1xuaW1wb3J0IHtUYWJsZUNvbHVtbkZpbHRlckNsYXNzUGlwZX0gZnJvbSAnLi4vLi4vcGlwZXMvdGFibGUtY29sdW1uLWZpbHRlci1jbGFzcy5waXBlJztcbmltcG9ydCB7RGF0YUxpc3RTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9kYXRhLWxpc3Quc2VydmljZSc7XG5pbXBvcnQge1RhYmxlQ29sdW1uRmlsdGVyRnVsbENvbXBvbmVudH0gZnJvbSAnLi4vY29sdW1uLWZpbHRlci1mdWxsL2NvbHVtbi1maWx0ZXItZnVsbC5jb21wb25lbnQnO1xuaW1wb3J0IHtUYWJsZUNvbHVtblZhbHVlQ29tcG9uZW50fSBmcm9tICcuLi9jb2x1bW4tdmFsdWUvY29sdW1uLXZhbHVlLmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdtbmctdGFibGUnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi90YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gICAgaW1wb3J0czogW1xuICAgICAgICBBc3luY1BpcGUsXG4gICAgICAgIENvbXBvbmVudERpcmVjdGl2ZSxcbiAgICAgICAgSTE4blByb3BlcnR5UGlwZSxcbiAgICAgICAgTmdDbGFzcyxcbiAgICAgICAgTmdTdHlsZSxcbiAgICAgICAgTmdUZW1wbGF0ZU91dGxldCxcbiAgICAgICAgVGFibGVDb2x1bW5WYWx1ZUNvbXBvbmVudCxcbiAgICAgICAgQ2xhc3NNYXBQaXBlLFxuICAgICAgICBMb2NhbGVEZWZhdWx0Um93Q2xhc3NQaXBlLFxuICAgICAgICBUYWJsZUNvbHVtbkZpbHRlckZ1bGxDb21wb25lbnQsXG4gICAgICAgIFRhYmxlQ29sdW1uRmlsdGVyQ2xhc3NQaXBlLFxuICAgICAgICBUYWJsZU1vZHVsZSxcbiAgICAgICAgTXVsdGlTZWxlY3RNb2R1bGUsXG4gICAgICAgIEJ1dHRvbk1vZHVsZSxcbiAgICAgICAgVG9vbHRpcE1vZHVsZSxcbiAgICAgICAgVHJhbnNsYXRlTW9kdWxlLFxuICAgICAgICBGb3Jtc01vZHVsZVxuICAgIF0sXG4gICAgcHJvdmlkZXJzOiBbRGF0YUxpc3RTZXJ2aWNlXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbi8vIFNvcnRzIGFuZCBGaWx0ZXJzIG11c3QgYmUgc3RyaW5nIGJ5IGRlZmF1bHQgLSBJdGVtIGNvdWxkIGJlIGFueXRoaW5nXG5leHBvcnQgY2xhc3MgVGFibGVDb21wb25lbnQ8SXRlbSA9IGFueSwgU2VydmljZSA9IHVuZGVmaW5lZCwgU29ydHMgPSBhbnksIEZpbHRlcnMgZXh0ZW5kcyBrZXlvZiBhbnkgPSBhbnk+IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gICAgcHVibGljIHJlYWRvbmx5IGNtcFR5cGVOYW1lID0gJ1RhYmxlQ29tcG9uZW50JztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyID0gaW5qZWN0KExvZ2dlclNlcnZpY2UpLmNyZWF0ZSh0aGlzLmNtcFR5cGVOYW1lKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlID0gaW5qZWN0KEFjdGl2YXRlZFJvdXRlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zbGF0ZSA9IGluamVjdChUcmFuc2xhdGVTZXJ2aWNlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VTZXJ2aWNlID0gaW5qZWN0KE1lc3NhZ2VTZXJ2aWNlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbW1vbnMgPSBpbmplY3QoQ29tbW9uc1NlcnZpY2UpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9jYWxTdG9yYWdlU2VydmljZSA9IGluamVjdChMb2NhbFN0b3JhZ2VTZXJ2aWNlKTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YUxpc3RTZXJ2aWNlID0gaW5qZWN0KERhdGFMaXN0U2VydmljZTxJdGVtPik7XG5cbiAgICAvLyBtZXRhZGF0YSBpbnB1dFxuICAgIEBJbnB1dCh7cmVxdWlyZWQ6IHRydWUsIGFsaWFzOiAnZGVzY3JpcHRvcid9KSBwdWJsaWMgZGVzY3JpcHRvcklucHV0ITogVGFibGVEZXNjcmlwdG9ySW5zdDxJdGVtLCBTb3J0cywgRmlsdGVycz47XG5cbiAgICAvLyBkYXRhIHNvdXJjZSBpbnB1dHNcbiAgICBASW5wdXQoe3RyYW5zZm9ybTogKHZhbHVlOiB1bmtub3duKSA9PiAodmFsdWUgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGlzT2JzZXJ2YWJsZSh2YWx1ZSkgPyAodmFsdWUgYXMgT2JzZXJ2YWJsZTxJdGVtW10+KSA6IG9mKHZhbHVlIGFzIEl0ZW1bXSkpfSkgcHVibGljIGl0ZW1zPzogT2JzZXJ2YWJsZTxcbiAgICAgICAgQXJyYXk8SXRlbT5cbiAgICA+O1xuICAgIEBJbnB1dCh7XG4gICAgICAgIHRyYW5zZm9ybTogKHZhbHVlOiB1bmtub3duKSA9PiAodmFsdWUgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGlzT2JzZXJ2YWJsZSh2YWx1ZSkgPyAodmFsdWUgYXMgT2JzZXJ2YWJsZTxEYXRhTGlzdFJlc3VsdDxJdGVtPj4pIDogb2YodmFsdWUgYXMgRGF0YUxpc3RSZXN1bHQ8SXRlbT4pKVxuICAgIH0pXG4gICAgcHVibGljIHJlc3VsdD86IE9ic2VydmFibGU8RGF0YUxpc3RSZXN1bHQ8SXRlbT4gfCB1bmRlZmluZWQ+O1xuICAgIEBJbnB1dCh7YWxpYXM6ICdsb2FkaW5nJywgdHJhbnNmb3JtOiBib29sZWFuJEF0dHJpYnV0ZX0pIHB1YmxpYyBsb2FkaW5nSW5wdXQ/OiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuICAgIEBJbnB1dCgpIHB1YmxpYyBkYXRhUHJvdmlkZXI/OiBJVGFibGVEYXRhUHJvdmlkZXI8SXRlbSwgU2VydmljZSwgU29ydHMsIEZpbHRlcnM+O1xuICAgIEBJbnB1dCgpIHB1YmxpYyB1c2VRdWVyeVBhcmFtcyA9IGZhbHNlO1xuXG4gICAgLy8gZXh0cmEgZmVhdHVyZXMgaW5wdXRcbiAgICBASW5wdXQoKSBwdWJsaWMgc2VsZWN0aW9uTW9kZTogJ3NpbmdsZScgfCAnbXVsdGlwbGUnID0gJ211bHRpcGxlJztcbiAgICBASW5wdXQoKSBwdWJsaWMgc2VsZWN0aW9uRW5hYmxlZCA9IGZhbHNlO1xuXG4gICAgLy8gc3R5bGluZ1xuICAgIEBJbnB1dCgpIHB1YmxpYyBjb2x1bW5MYXN0TWluV2lkdGg/OiBudW1iZXI7XG5cbiAgICAvLyBjb21wb25lbnQgaW5wdXRzXG4gICAgQElucHV0KCkgcHVibGljIGNhcHRpb25Db21wb25lbnQ/OiBUeXBlPGFueT47XG4gICAgQElucHV0KCkgcHVibGljIGNvbHVtbkN1c3RvbUxhc3RDb21wb25lbnQ/OiBUeXBlPGFueT47XG4gICAgQElucHV0KCdnbG9iYWxGaWx0ZXJGaWVsZHMnKSBwdWJsaWMgZ2xvYmFsRmlsdGVyRmllbGRzSW5wdXQ/OiBzdHJpbmdbXTtcblxuICAgIC8vIGV2ZW50IG91dHB1dHNcbiAgICBAT3V0cHV0KCd0YWJsZUxvYWQnKSBwdWJsaWMgbG9hZEV2ZW50RW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8VGFibGVMb2FkRXZlbnQ+KCk7XG4gICAgQE91dHB1dCgnY2VsbENsaWNrJykgcHVibGljIGNlbGxDbGlja0V2ZW50RW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8VGFibGVDZWxsQ2xpY2tFdmVudDxJdGVtPj4oKTtcbiAgICBAT3V0cHV0KCdzZWxlY3Rpb25DaGFuZ2UnKSBwdWJsaWMgc2VsZWN0aW9uQ2hhbmdlRXZlbnRFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcjxBcnJheTxJdGVtPj4oKTtcbiAgICBAT3V0cHV0KCdjYXB0aW9uQ29tcG9uZW50SW5zdGFuY2UnKSBwdWJsaWMgY2FwdGlvbkNtcEluc3RFdmVudEVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgICBAT3V0cHV0KCdjb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50SW5zdGFuY2UnKSBwdWJsaWMgY29sdW1uQ3VzdG9tTGFzdENtcEluc3RFdmVudEVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAgIC8vIGNvbnRlbnQgYW5kIHZpZXcgcXVlcmllc1xuICAgIHB1YmxpYyB0ZW1wbGF0ZXMgPSBjb250ZW50Q2hpbGRyZW4oVGVtcGxhdGVEaXJlY3RpdmUpO1xuICAgIEBWaWV3Q2hpbGRyZW4oQ29tcG9uZW50RGlyZWN0aXZlKSBwdWJsaWMgY29tcG9uZW50cyE6IFF1ZXJ5TGlzdDxDb21wb25lbnREaXJlY3RpdmU8YW55Pj47XG4gICAgQFZpZXdDaGlsZChUYWJsZSkgcHVibGljIHByaW1lVGFibGUhOiBUYWJsZTtcblxuICAgIC8vIHRlbXBsYXRlc1xuICAgIHB1YmxpYyBjYXB0aW9uVGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAnY2FwdGlvbicpKTtcbiAgICBwdWJsaWMgY29sdW1uQ3VzdG9tTGFzdFRlbXBsYXRlOiBTaWduYWw8VGVtcGxhdGVSZWY8YW55PiB8IG51bGw+ID0gY29tcHV0ZWQoKCkgPT4gZmluZFRlbXBsYXRlQnlOYW1lKFsuLi50aGlzLnRlbXBsYXRlcygpXSwgJ2NvbHVtbkN1c3RvbUxhc3QnKSk7XG4gICAgcHVibGljIGZvb3RlclRlbXBsYXRlOiBTaWduYWw8VGVtcGxhdGVSZWY8YW55PiB8IG51bGw+ID0gY29tcHV0ZWQoKCkgPT4gZmluZFRlbXBsYXRlQnlOYW1lKFsuLi50aGlzLnRlbXBsYXRlcygpXSwgJ2Zvb3RlcicpKTtcbiAgICBwdWJsaWMgcm93RXhwYW5kVGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAncm93RXhwYW5kQ29udGVudCcpKTtcblxuICAgIC8vIGRhdGEgcHJvdmlkZXIgYW5kIGl0ZW1zXG4gICAgcHJpdmF0ZSB1c2VEYXRhUHJvdmlkZXIgPSBmYWxzZTtcbiAgICBwdWJsaWMgaXNMYXp5ID0gc2lnbmFsKGZhbHNlKTtcbiAgICBwdWJsaWMgaXNQYWdpbmF0aW9uID0gc2lnbmFsKGZhbHNlKTtcbiAgICBwdWJsaWMgdXNlUXVlcnlQYXJhbXNJbml0aWFsaXplZCA9IHNpZ25hbChmYWxzZSk7XG5cbiAgICAvLyBpbmZpbml0ZSBzY3JvbGxcbiAgICBwdWJsaWMgaW5maW5pdGVTY3JvbGwgPSBzaWduYWwoZmFsc2UpO1xuXG4gICAgLy8gdmlzdWFsXG4gICAgcHVibGljIGNsYXNzTmFtZSA9IHNpZ25hbCgnJyk7XG4gICAgcHVibGljIHRhYmxlRnVsbEhlaWdodE9mZnNldCA9IHNpZ25hbDxudW1iZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gICAgcHVibGljIHJvd0hlaWdodCA9IHNpZ25hbDxudW1iZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbiAgICAvLyBkYXRhIHByb3ZpZGVyXG4gICAgcHJpdmF0ZSBkYXRhUHJvdmlkZXJTZXJ2aWNlOiBhbnkgPSBudWxsO1xuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyTGF0ZXN0TGF6eUxvYWRFdmVudD86IFRhYmxlTGF6eUxvYWRFdmVudDtcbiAgICBwcml2YXRlIGxhdGVzdExhenlMb2FkRXZlbnRWZXJzaW9uID0gMDtcbiAgICBwcml2YXRlIGxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cz86IERhdGFMaXN0UGFyYW1zO1xuICAgIHByaXZhdGUgbGF0ZXN0UGFyYW1zV2l0aERlZmF1bHRzVmVyc2lvbiA9IDA7XG4gICAgcHJpdmF0ZSBkYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSByZXN1bHRTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBpdGVtc1N1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcblxuICAgIC8vIGRlc2NyaXB0b3JzXG4gICAgcHVibGljIGRlc2NyaXB0b3IgPSBzaWduYWw8VGFibGVEZXNjcmlwdG9ySW5zdDxhbnksIGFueSwgYW55Pj4odGFibGVEZXNjcmlwdG9yPHN0cmluZywgc3RyaW5nLCBzdHJpbmc+KCkpO1xuICAgIHB1YmxpYyBjb2x1bW5zID0gc2lnbmFsPENvbHVtbldpdGhQcmVmZXJlbmNlc1tdPihbXSk7XG4gICAgcHVibGljIHZpc2libGVDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKGNvbCA9PiBjb2wuaXNWaXNpYmxlKSk7XG5cbiAgICAvLyBmaWx0ZXIsIHNvcnRcbiAgICBwdWJsaWMgaGFzQ29sdW1uRmlsdGVycyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMoKS5sZW5ndGggPiAwKTtcbiAgICBwcml2YXRlIGZpbHRlckRlc2NyaXB0b3JzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kZXNjcmlwdG9yKCkuZmlsdGVycyk7XG4gICAgcHJpdmF0ZSBkZWZhdWx0UGFyYW1zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBwYXJhbXM6IERhdGFMaXN0UGFyYW1zID0ge1xuICAgICAgICAgICAgb2Zmc2V0OiAwLFxuICAgICAgICAgICAgbGltaXQ6IHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnJvd3NQZXJQYWdlT3B0aW9ucygpWzBdLFxuICAgICAgICAgICAgc29ydDogdGhpcy5kZXNjcmlwdG9yKClcbiAgICAgICAgICAgICAgICAuc29ydHMuZmlsdGVyKHMgPT4gcy5kZWZhdWx0SXNFbmFibGVkKVxuICAgICAgICAgICAgICAgIC5tYXAocyA9PiAoe1xuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogcy5wcm9wZXJ0eSxcbiAgICAgICAgICAgICAgICAgICAgYXNjZW5kaW5nOiBzLmRlZmF1bHRJc0FzY2VuZGluZ1xuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgIGZpbHRlcnM6IHt9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5maWx0ZXJEZXNjcmlwdG9ycygpXG4gICAgICAgICAgICAuZmlsdGVyKGQgPT4gZC5oYXNEZWZhdWx0VmFsdWUpXG4gICAgICAgICAgICAuZm9yRWFjaChmID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgbWF0Y2hNb2RlOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBmLmRlZmF1bHRNYXRjaE1vZGU7XG4gICAgICAgICAgICAgICAgaWYgKCFtYXRjaE1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChmLmZpbHRlclR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRmlsdGVyVHlwZUVudW0uU3RyaW5nOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZSA9IEZpbHRlck1hdGNoTW9kZS5Db250YWlucztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRmlsdGVyVHlwZUVudW0uTG9va3VwOlxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBGaWx0ZXJUeXBlRW51bS5Mb29rdXBFbnVtOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9va3VwRmlsdGVyID0gZiBhcyBGaWx0ZXJMb29rdXBEZXNjcmlwdG9yPGFueSwgSXRlbT47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvb2t1cEZpbHRlci5tdWx0aXNlbGVjdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuSW47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoTW9kZSkge1xuICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuRXF1YWxzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChmLm1hdGNoTW9kZXMgJiYgIWYubWF0Y2hNb2Rlcz8uaW5jbHVkZXMobWF0Y2hNb2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBmLm1hdGNoTW9kZXNbMF07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlOiBhbnkgfCBhbnlbXSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBbLi4udmFsdWVdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZi5kZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvcGVydHkgPSBmLnByb3BlcnR5O1xuICAgICAgICAgICAgICAgIHBhcmFtcy5maWx0ZXJzIVtwcm9wZXJ0eV0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlOiBtYXRjaE1vZGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHBhcmFtcztcbiAgICB9KTtcbiAgICBwcml2YXRlIGlzRmlsdGVyQ2hhbmdlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgaXNTb3J0Q2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgcHVibGljIGFueUNvbHVtblZpc2libGUgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnZpc2libGVDb2x1bW5zKCkubGVuZ3RoID4gMCk7XG4gICAgcHVibGljIGhhc0N1c3RvbUxhc3RDb2x1bW4gPSBzaWduYWwoZmFsc2UpO1xuICAgIHB1YmxpYyBoYXNMYXN0Q29sdW1uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5oYXNDdXN0b21MYXN0Q29sdW1uKCkgfHwgdGhpcy5hcmVDb2x1bW5zVG9nZ2xlYWJsZSgpIHx8IHRoaXMuYXJlQ29sdW1uc1Jlb3JkZXJhYmxlKCkpO1xuXG4gICAgLy8gbGF5b3V0IHByZWZzXG4gICAgcHVibGljIGFyZUNvbHVtbnNSZW9yZGVyYWJsZSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVzY3JpcHRvcigpLmNvbHVtbnMuc29tZSh2YWx1ZSA9PiB2YWx1ZS5pc1Jlb3JkZXJhYmxlKSk7XG4gICAgcHVibGljIGFyZUNvbHVtbnNUb2dnbGVhYmxlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kZXNjcmlwdG9yKCkuY29sdW1ucy5zb21lKHZhbHVlID0+IHZhbHVlLmlzVG9nZ2xlYWJsZSkpO1xuICAgIHByaXZhdGUgbGF5b3V0UHJlZmVyZW5jZXM6IFRhYmxlTGF5b3V0UHJlZmVyZW5jZXMgPSB7Y29sdW1uV2lkdGhzOiB7fX07XG4gICAgcHJpdmF0ZSBsb2NhbHN0b3JhZ2VLZXkgPSAnJztcblxuICAgIC8vIG90aGVyXG4gICAgcHJpdmF0ZSByb3V0ZXJJc05hdmlnYXRpb25PdXRzaWRlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuXG4gICAgcHVibGljIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLnNldE1haW5BbmRSZWxhdGVkRGVzY3JpcHRvcnModGhpcy5kZXNjcmlwdG9ySW5wdXQpO1xuXG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3IoKTtcblxuICAgICAgICAvLyBtYXAgcm93IHNldHRpbmdzXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRlc2NyaXB0b3Iucm93c1BlclBhZ2VPcHRpb25zKSAmJiBkZXNjcmlwdG9yLnJvd3NQZXJQYWdlT3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMuc2V0KGRlc2NyaXB0b3Iucm93c1BlclBhZ2VPcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVzY3JpcHRvci5kZWZhdWx0TnVtUm93cykge1xuICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cy5zZXQoXG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93c1BlclBhZ2VPcHRpb25zKCkuaW5jbHVkZXMoZGVzY3JpcHRvci5kZWZhdWx0TnVtUm93cykgPyBkZXNjcmlwdG9yLmRlZmF1bHROdW1Sb3dzIDogdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93c1BlclBhZ2VPcHRpb25zKClbMF1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBvdGhlclxuICAgICAgICB0aGlzLmhhc0N1c3RvbUxhc3RDb2x1bW4uc2V0KHRoaXMuY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudCAhPT0gdW5kZWZpbmVkIHx8IHRoaXMuY29sdW1uQ3VzdG9tTGFzdFRlbXBsYXRlKCkgIT09IHVuZGVmaW5lZCk7XG5cbiAgICAgICAgLy8gZGVmaW5lIGFsbCBzdHlsZXNcbiAgICAgICAgbGV0IGNsYXNzTmFtZSA9IGRlc2NyaXB0b3IuY2xhc3NOYW1lID8/ICcnO1xuXG4gICAgICAgIHN3aXRjaCAoZGVzY3JpcHRvci5zaXplKSB7XG4gICAgICAgICAgICBjYXNlIFRhYmxlU2l6ZUVudW0uU21hbGw6XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9ICcgcC1kYXRhdGFibGUtc20nO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBUYWJsZVNpemVFbnVtLkxhcmdlOlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZSArPSAnIHAtZGF0YXRhYmxlLWxnJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVzY3JpcHRvci5oYXNHcmlkbGluZXMpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSArPSAnIHAtZGF0YXRhYmxlLWdyaWRsaW5lcyc7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNsYXNzTmFtZS5zZXQoY2xhc3NOYW1lID8/ICcnKTtcblxuICAgICAgICAvLyBjaGVjayBpZiBpbmZpbml0ZSBzY3JvbGxcbiAgICAgICAgbGV0IHBhZ2luYXRpb25Nb2RlID0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uTm9uZTtcbiAgICAgICAgaWYgKHR5cGVvZiBkZXNjcmlwdG9yLnBhZ2luYXRpb25Nb2RlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgLy8gZGVzY3JpcHRvciBjaG9pY2UgaXMgdGhlIG1vc3Qgc3Ryb25nIC0gaWYgZGVmaW5lZCwgdXNlIHRoaXMgdmFsdWVcbiAgICAgICAgICAgIHBhZ2luYXRpb25Nb2RlID0gZGVzY3JpcHRvci5wYWdpbmF0aW9uTW9kZTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5kYXRhUHJvdmlkZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAvLyB3aGVuIGRhdGEgcHJvdmlkZXIgaXMgdXNlZCwgdXNlIHBhZ2luYXRpb25cbiAgICAgICAgICAgIHBhZ2luYXRpb25Nb2RlID0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uUGFnaW5hdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYWdpbmF0aW9uTW9kZSA9PT0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uSW5maW5pdGVTY3JvbGwpIHtcbiAgICAgICAgICAgIHRoaXMuaW5maW5pdGVTY3JvbGwuc2V0KHRydWUpO1xuICAgICAgICAgICAgdGhpcy50YWJsZUZ1bGxIZWlnaHRPZmZzZXQuc2V0KGRlc2NyaXB0b3I/LnRhYmxlRnVsbEhlaWdodE9mZnNldCA/PyAzMTUpO1xuICAgICAgICAgICAgdGhpcy5yb3dIZWlnaHQuc2V0KGRlc2NyaXB0b3I/LnJvd0hlaWdodCA/PyA0NSk7XG4gICAgICAgICAgICB0aGlzLnVzZVF1ZXJ5UGFyYW1zID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAocGFnaW5hdGlvbk1vZGUgPT09IFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLlBhZ2luYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuaXNQYWdpbmF0aW9uLnNldCh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjaGVjayBpZiBkYXRhIHByb3ZpZGVyIGlzIHN1cHBsaWVkLCBpZiBpcywgdXNlIGl0IHByaW1hcmlseVxuICAgICAgICBpZiAodGhpcy5kYXRhUHJvdmlkZXIpIHtcbiAgICAgICAgICAgIC8vIG1hcCBzdWJqZWN0cyB0byBvYnNlcnZhYmxlcyBhbmQgaW5pdGlhdGUgZGF0YVxuICAgICAgICAgICAgdGhpcy51c2VEYXRhUHJvdmlkZXIgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5pc0xhenkuc2V0KHRoaXMuZGF0YVByb3ZpZGVyLmlzTGF6eSk7XG5cbiAgICAgICAgICAgIC8vIGluamVjdCBzZXJ2aWNlXG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhUHJvdmlkZXIuc2VydmljZVR5cGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFQcm92aWRlclNlcnZpY2UgPSB0aGlzLmluamVjdG9yLmdldDxhbnk+KHRoaXMuZGF0YVByb3ZpZGVyLnNlcnZpY2VUeXBlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXIuZ2V0QWxsUmVsb2FkJC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGlmIHF1ZXJ5IHJlc3VsdCBpcyBwcm92aWRlZCwgdXNlIGl0IGFzIHNlY29uZGFyeSBzb3VyY2Ugb3IgZWxzZSB0cnkgdG8gdXNlIGl0ZW1zXG4gICAgICAgICAgICBpZiAodGhpcy5yZXN1bHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN1YnNjcmliZVRvUXVlcnlJbnB1dCgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdWJzY3JpYmVUb0l0ZW1zSW5wdXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmxvYWRpbmdJbnB1dCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZ0lucHV0LnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpLnN1YnNjcmliZShyZXMgPT4gdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQocmVzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmluaXRpYWxpemVEYXRhTG9hZGluZ1RyaWdnZXJzKCk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICBpZiAoY2hhbmdlc1sncmVzdWx0J10gJiYgIWNoYW5nZXNbJ3Jlc3VsdCddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnN1YnNjcmliZVRvUXVlcnlJbnB1dCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoYW5nZXNbJ2l0ZW1zJ10gJiYgIWNoYW5nZXNbJ2l0ZW1zJ10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaWJlVG9JdGVtc0lucHV0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hhbmdlc1snZ2xvYmFsRmlsdGVyRmllbGRzSW5wdXQnXSAmJiAhY2hhbmdlc1snZ2xvYmFsRmlsdGVyRmllbGRzSW5wdXQnXS5maXJzdENoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZ2xvYmFsRmlsdGVyRmllbGRzLnNldChjaGFuZ2VzWydnbG9iYWxGaWx0ZXJGaWVsZHNJbnB1dCddLmN1cnJlbnRWYWx1ZSA/PyB0aGlzLmNvbHVtbnMoKS5tYXAoYyA9PiBjLmRlc2NyaXB0b3IucHJvcGVydHkpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMucmVzdWx0U3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLml0ZW1zU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWxvYWQoZW1pdEV2ZW50ID0gZmFsc2UsIHJlc2V0UGFyYW1zID0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zV2l0aERlZmF1bHRzOiBEYXRhTGlzdFBhcmFtcyA9XG4gICAgICAgICAgICByZXNldFBhcmFtcyB8fCAhdGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHMgPyB0aGlzLmRlZmF1bHRQYXJhbXMoKSA6IG1lcmdlRGF0YUxpc3RQYXJhbXNXaXRoRGVmYXVsdHModGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHMsIHRoaXMuZGVmYXVsdFBhcmFtcygpKTtcbiAgICAgICAgdGhpcy5sb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKHBhcmFtc1dpdGhEZWZhdWx0cywgZW1pdEV2ZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25UYWJsZUxhenlMb2FkKGV2ZW50OiBUYWJsZUxhenlMb2FkRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJMYXRlc3RMYXp5TG9hZEV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIHRoaXMubGF0ZXN0TGF6eUxvYWRFdmVudFZlcnNpb24rKztcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBmcm9tVGFibGVMb2FkVG9EYXRhTGlzdFBhcmFtcyhldmVudCk7XG5cbiAgICAgICAgaWYgKHRoaXMudXNlUXVlcnlQYXJhbXMpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5yb3V0ZXJJc05hdmlnYXRpb25PdXRzaWRlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgIC8vIHRoaXMgY2hlY2sgaXMgbmVjZXNzYXJ5OiBmcm9tIHNvbWUgcmVhc29uLCBwcmltZU5HIGNvbW1pdHMgb25lIGxhc3QgbGF6eSBsb2FkIGV2ZW50IHdoZW5ldmVyIGFueSBhbmd1bGFyIHJvdXRlciBuYXZpZ2F0aW9uIG9jY3Vyc1xuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFtdLCB7XG4gICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlVG86IHRoaXMucm91dGUsXG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VVcmw6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5UGFyYW1zOiBkYXRhTGlzdFBhcmFtc1RvVXJsUXVlcnkocGFyYW1zLCB0aGlzLmRlZmF1bHRQYXJhbXMoKSlcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9hZFRhYmxlV2l0aERhdGFQcm92aWRlcihtZXJnZURhdGFMaXN0UGFyYW1zV2l0aERlZmF1bHRzKHBhcmFtcywgdGhpcy5kZWZhdWx0UGFyYW1zKCkpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBwdWJsaWMgb25UYWJsZVNvcnQoZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLmlzU29ydENoYW5nZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBwdWJsaWMgb25UYWJsZUZpbHRlcihldmVudDogYW55KSB7XG4gICAgICAgIHRoaXMuaXNGaWx0ZXJDaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25DZWxsQ2xpY2soZXZlbnQ6IEV2ZW50LCBjb2w6IENvbHVtbkRlc2NyaXB0b3I8YW55LCBJdGVtPiwgaXRlbTogSXRlbSwgaWR4OiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgdGFibGVFdmVudDogVGFibGVDZWxsQ2xpY2tFdmVudDxJdGVtPiA9IHtcbiAgICAgICAgICAgIGNvbHVtbjogY29sLFxuICAgICAgICAgICAgcm93SXRlbTogaXRlbSxcbiAgICAgICAgICAgIHJvd0luZGV4OiBpZHgsXG4gICAgICAgICAgICBldmVudDogZXZlbnRcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jZWxsQ2xpY2tFdmVudEVtaXR0ZXIubmV4dCh0YWJsZUV2ZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZWxlY3Rpb25DaGFuZ2UoZXZlbnQ6IEFycmF5PEl0ZW0+KSB7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlRXZlbnRFbWl0dGVyLmVtaXQoZXZlbnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBpcyBjYWxsZWQgb24gY29sdW1uIHJlc2l6ZVxuICAgICAqIEBwYXJhbSBlbGVtZW50IGV2ZW50J3MgZWxlbWVudFxuICAgICAqL1xuICAgIHB1YmxpYyBvblRhYmxlQ29sdW1uUmVzaXplKHtlbGVtZW50fTogYW55KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGZpZWxkSWQ6IHN0cmluZyA9IGVsZW1lbnQuaWQ7XG4gICAgICAgIGNvbnN0IHdpZHRoOiBudW1iZXIgPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuXG4gICAgICAgIGNvbnN0IGNvbCA9IHRoaXMuY29sdW1ucygpLmZpbmQoZWwgPT4gZWwuZGVzY3JpcHRvci5wcm9wZXJ0eSA9PT0gZmllbGRJZCk7XG4gICAgICAgIGlmIChjb2wpIGNvbC53aWR0aCA9IHdpZHRoO1xuICAgICAgICBpZiAoIXRoaXMubGF5b3V0UHJlZmVyZW5jZXMuY29sdW1uV2lkdGhzKSB0aGlzLmxheW91dFByZWZlcmVuY2VzLmNvbHVtbldpZHRocyA9IHt9O1xuXG4gICAgICAgIHRoaXMubGF5b3V0UHJlZmVyZW5jZXMuY29sdW1uV2lkdGhzW2ZpZWxkSWRdID0gd2lkdGg7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKHBhcmFtc1dpdGhEZWZhdWx0czogRGF0YUxpc3RQYXJhbXMsIGVtaXRFdmVudCA9IHRydWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLnVzZURhdGFQcm92aWRlciB8fCAhdGhpcy5kYXRhUHJvdmlkZXIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5sb2FkaW5nLnNldCh0cnVlKTtcblxuICAgICAgICB0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cyA9IHBhcmFtc1dpdGhEZWZhdWx0cztcbiAgICAgICAgdGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHNWZXJzaW9uKys7XG5cbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24gPSB0b09ic2VydmFibGUoXG4gICAgICAgICAgICB0aGlzLmRhdGFQcm92aWRlci5nZXRBbGwoXG4gICAgICAgICAgICAgICAgcGFyYW1zV2l0aERlZmF1bHRzIGFzIERhdGFMaXN0UGFyYW1zPFNvcnRzLCBGaWx0ZXJzPixcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFQcm92aWRlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgdGhpcy5kZXNjcmlwdG9yKCkuaXNMb2NhbGl6ZWQgPyB0aGlzLmNvbW1vbnMuYXBwRGF0YUxvY2FsZSgpID8/IHVuZGVmaW5lZCA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgKVxuICAgICAgICApLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiByZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3JJbnB1dCBpbnN0YW5jZW9mIFRhYmxlRHluYW1pY0Rlc2NyaXB0b3JJbnN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0TWFpbkFuZFJlbGF0ZWREZXNjcmlwdG9ycyh0aGlzLmRlc2NyaXB0b3JJbnB1dC50b1RhYmxlRGVzY3JpcHRvckZyb21EYXRhKHJlcykpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmluZmluaXRlU2Nyb2xsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5kYXRhTGlzdFNlcnZpY2UuZGF0YSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0ZpbHRlckNoYW5nZWQgfHwgdGhpcy5pc1NvcnRDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zLnNwbGljZShwYXJhbXNXaXRoRGVmYXVsdHMhLm9mZnNldCA/PyAwLCBwYXJhbXNXaXRoRGVmYXVsdHMhLmxpbWl0ID8/IHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnJvd3MoKSwgLi4uKHJlcz8uZGF0YSA/PyBbXSkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5kYXRhLnNldChpdGVtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZGF0YS5zZXQocmVzPy5kYXRhID8/IFtdKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5jb3VudC5zZXQocmVzPy50b3RhbENvdW50ID8/IDApOyAvLyBjb3VudCBpcyBub3QgcmVhbGx5IGltcG9ydGFudCBoZXJlXG5cbiAgICAgICAgICAgICAgICB0aGlzLmlzRmlsdGVyQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuaXNTb3J0Q2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICAgICAgICB0YWJsZU5vdGlmaWNhdGlvbkVycm9yKHRoaXMudHJhbnNsYXRlLCB0aGlzLmRlc2NyaXB0b3IoKSwgZXJyLCB0aGlzLm1lc3NhZ2VTZXJ2aWNlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5kYXRhLnNldChbXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuY291bnQuc2V0KDApO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gZnJvbVN1YnNjcmliZUVycm9yKGVyciwgJ1RhYmxlQ29tcG9uZW50RXJyb3InLCB7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5UGFyYW06IHBhcmFtc1dpdGhEZWZhdWx0c1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhlcnJvciwgZ2V0RXJyb3JMb2dMZXZlbChlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoZW1pdEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCB0YWJsZUV2ZW50OiBUYWJsZUxvYWRFdmVudCA9IHtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbEV2ZW50OiB0aGlzLmRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnQsXG4gICAgICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXNXaXRoRGVmYXVsdHNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmxvYWRFdmVudEVtaXR0ZXIubmV4dCh0YWJsZUV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbG9hZFRhYmxlRnJvbVJvdXRlVXBkYXRlKHVybFBhcmFtczogUGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtc1dpdGhEZWZhdWx0cyA9IG1lcmdlRGF0YUxpc3RQYXJhbXNXaXRoRGVmYXVsdHMoZnJvbVVybFF1ZXJ5VG9EYXRhTGlzdFBhcmFtcyh1cmxQYXJhbXMpLCB0aGlzLmRlZmF1bHRQYXJhbXMoKSk7XG4gICAgICAgIGlmICh0aGlzLmxhdGVzdExhenlMb2FkRXZlbnRWZXJzaW9uIDwgdGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHNWZXJzaW9uICsgMSkge1xuICAgICAgICAgICAgLy8gdXBkYXRlIG9ubHkgaWYgbmV3IHZlcnNpb24gZnJvbSBxdWVyeSBwYXJhbXMgd2lsbCBiZSBoaWdoZXJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUHJpbWVTb3J0QW5kRmlsdGVyKHBhcmFtc1dpdGhEZWZhdWx0cyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51c2VRdWVyeVBhcmFtc0luaXRpYWxpemVkLnNldCh0cnVlKTtcbiAgICAgICAgdGhpcy5sb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKHBhcmFtc1dpdGhEZWZhdWx0cyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRNYWluQW5kUmVsYXRlZERlc2NyaXB0b3JzKGRlc2NyaXB0b3I6IFRhYmxlRGVzY3JpcHRvckluc3Q8YW55LCBhbnksIGFueT4pIHtcbiAgICAgICAgaWYgKGRlc2NyaXB0b3IgaW5zdGFuY2VvZiBUYWJsZUR5bmFtaWNEZXNjcmlwdG9ySW5zdCkge1xuICAgICAgICAgICAgdGhpcy5kZXNjcmlwdG9yLnNldChkZXNjcmlwdG9yKTtcbiAgICAgICAgICAgIHRoaXMuY29sdW1ucy5zZXQoW10pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZ2V0IGxheW91dCBwcmVmZXJlbmNlcyBpZiB0aGV5IGV4aXN0XG4gICAgICAgIGlmIChkZXNjcmlwdG9yLm1vZGVsLnR5cGVOYW1lKSB7XG4gICAgICAgICAgICB0aGlzLmxvY2Fsc3RvcmFnZUtleSA9IGdlbmVyYXRlVGFibGVMYXlvdXRQcmVmc0tleShkZXNjcmlwdG9yLm1vZGVsLnR5cGVOYW1lLCB0aGlzLnJvdXRlci51cmwsIGRlc2NyaXB0b3IuaWRlbnRpZmllcik7XG4gICAgICAgICAgICBjb25zdCBwcmVmZXJlbmNlcyA9IHRoaXMubG9jYWxTdG9yYWdlU2VydmljZS5nZXRJdGVtPFRhYmxlTGF5b3V0UHJlZmVyZW5jZXM+KHRoaXMuY21wVHlwZU5hbWUsIHRoaXMubG9jYWxzdG9yYWdlS2V5KTtcbiAgICAgICAgICAgIGlmIChwcmVmZXJlbmNlcyAmJiB0eXBlb2YgcHJlZmVyZW5jZXMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByZWZlcmVuY2VzLmNvbHVtbldpZHRocykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxheW91dFByZWZlcmVuY2VzLmNvbHVtbldpZHRocyA9IHByZWZlcmVuY2VzLmNvbHVtbldpZHRocyBhcyBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocHJlZmVyZW5jZXMuY29sdW1uT3JkZXIgJiYgQXJyYXkuaXNBcnJheShwcmVmZXJlbmNlcy5jb2x1bW5PcmRlcikgJiYgcHJlZmVyZW5jZXMuY29sdW1uT3JkZXIuZXZlcnkoKGVsOiBhbnkpID0+IHR5cGVvZiBlbCA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0UHJlZmVyZW5jZXMuY29sdW1uT3JkZXIgPSBwcmVmZXJlbmNlcy5jb2x1bW5PcmRlcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHByZWZlcmVuY2VzLmNvbHVtblZpc2liaWxpdHkgJiYgQXJyYXkuaXNBcnJheShwcmVmZXJlbmNlcy5jb2x1bW5WaXNpYmlsaXR5KSAmJiBwcmVmZXJlbmNlcy5jb2x1bW5WaXNpYmlsaXR5LmV2ZXJ5KChlbDogYW55KSA9PiB0eXBlb2YgZWwgPT09ICdzdHJpbmcnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxheW91dFByZWZlcmVuY2VzLmNvbHVtblZpc2liaWxpdHkgPSBwcmVmZXJlbmNlcy5jb2x1bW5WaXNpYmlsaXR5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxzdG9yYWdlS2V5ID0gJyc7XG4gICAgICAgICAgICB0aGlzLmxheW91dFByZWZlcmVuY2VzID0ge2NvbHVtbldpZHRoczoge319O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBjb2x1bW5zIHdpdGggYWRkaXRpb25hbCBwcm9wZXJ0aWVzXG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBsZXQgY29sdW1uczogQ29sdW1uV2l0aFByZWZlcmVuY2VzW10gPSBkZXNjcmlwdG9yLmNvbHVtbnMubWFwKGNvbCA9PiAoe1xuICAgICAgICAgICAgaWQ6IGAke2NvbC5wcm9wZXJ0eX0tJHt0aW1lc3RhbXB9YCxcbiAgICAgICAgICAgIGRlc2NyaXB0b3I6IGNvbCxcbiAgICAgICAgICAgIGZpbHRlcjogZGVzY3JpcHRvci5maWx0ZXJzLmZpbmQoZiA9PiBmLnNob3dPbkNvbHVtbiA9PT0gY29sLnByb3BlcnR5KSxcbiAgICAgICAgICAgIHNvcnQ6IGRlc2NyaXB0b3Iuc29ydHMuZmluZChmID0+IGYuc2hvd09uQ29sdW1uID09PSBjb2wucHJvcGVydHkpLFxuICAgICAgICAgICAgZGlzYWJsZWQ6ICFjb2wuaXNUb2dnbGVhYmxlLFxuICAgICAgICAgICAgaXNWaXNpYmxlOiB0aGlzLmxheW91dFByZWZlcmVuY2VzLmNvbHVtblZpc2liaWxpdHkgPyB0aGlzLmxheW91dFByZWZlcmVuY2VzLmNvbHVtblZpc2liaWxpdHkuaW5jbHVkZXMoY29sLnByb3BlcnR5KSA6IGNvbC5pc1Zpc2libGUsXG4gICAgICAgICAgICB3aWR0aDogdGhpcy5sYXlvdXRQcmVmZXJlbmNlcy5jb2x1bW5XaWR0aHM/Lltjb2wucHJvcGVydHldXG4gICAgICAgIH0pKTtcblxuICAgICAgICBpZiAodGhpcy5sYXlvdXRQcmVmZXJlbmNlcy5jb2x1bW5PcmRlcikge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxheW91dFByZWZlcmVuY2VzLmNvbHVtbk9yZGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sTmFtZSA9IHRoaXMubGF5b3V0UHJlZmVyZW5jZXMuY29sdW1uT3JkZXJbaV07XG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2l0aFByZWZzID0gY29sdW1ucy5maW5kKGVsID0+IGVsLmRlc2NyaXB0b3IucHJvcGVydHkgPT09IGNvbE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChjb2xXaXRoUHJlZnMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sV2l0aFByZWZzLm9yZGVySWR4ID0gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb2x1bW5zID0gY29sdW1ucy5zb3J0KChhLCBiKSA9PiAoYS5vcmRlcklkeCAhPT0gdW5kZWZpbmVkICYmIGIub3JkZXJJZHggIT09IHVuZGVmaW5lZCA/IGEub3JkZXJJZHggLSBiLm9yZGVySWR4IDogMCkpO1xuXG4gICAgICAgIHRoaXMuZGVzY3JpcHRvci5zZXQoZGVzY3JpcHRvcik7XG4gICAgICAgIHRoaXMuY29sdW1ucy5zZXQoY29sdW1ucyk7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmdsb2JhbEZpbHRlckZpZWxkcy5zZXQodGhpcy5nbG9iYWxGaWx0ZXJGaWVsZHNJbnB1dCA/PyB0aGlzLmNvbHVtbnMoKS5tYXAoYyA9PiBjLmRlc2NyaXB0b3IucHJvcGVydHkpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVByaW1lU29ydEFuZEZpbHRlcihwYXJhbXNXaXRoRGVmYXVsdHM6IERhdGFMaXN0UGFyYW1zKSB7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNvcnRNZXRhLnNldCh0aGlzLmNyZWF0ZVNvcnRNZXRhKHBhcmFtc1dpdGhEZWZhdWx0cykpO1xuICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhLnNldCh0aGlzLmNyZWF0ZUZpbHRlck1ldGEocGFyYW1zV2l0aERlZmF1bHRzKSk7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnJvd3Muc2V0KHBhcmFtc1dpdGhEZWZhdWx0cz8ubGltaXQgPz8gdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cygpKTtcbiAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uub2Zmc2V0LnNldChwYXJhbXNXaXRoRGVmYXVsdHM/Lm9mZnNldCA/PyAwKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZUZpbHRlck1ldGEocGFyYW1zV2l0aERlZmF1bHRzPzogRGF0YUxpc3RQYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcHJpbWVGaWx0ZXJNZXRhOiB7W3M6IHN0cmluZ106IEZpbHRlck1ldGFkYXRhfSA9IHt9O1xuICAgICAgICAvLyBpZiBhbnkgZmlsdGVyIGlzIHByZXNlbnQsIG5vIGRlZmF1bHQgZmlsdGVycyBzaG91bGQgYmUgYXBwbGllZCFcblxuICAgICAgICBpZiAocGFyYW1zV2l0aERlZmF1bHRzPy5maWx0ZXJzKSB7XG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyhwYXJhbXNXaXRoRGVmYXVsdHMuZmlsdGVycykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgcHJpbWVGaWx0ZXJNZXRhW2tleV0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlOiB2YWx1ZS5tYXRjaE1vZGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJpbWVGaWx0ZXJNZXRhO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlU29ydE1ldGEocGFyYW1zV2l0aERlZmF1bHRzPzogRGF0YUxpc3RQYXJhbXMpOiBTb3J0TWV0YVtdIHwgbnVsbCB7XG4gICAgICAgIGlmIChwYXJhbXNXaXRoRGVmYXVsdHM/LnNvcnQgIT09IHVuZGVmaW5lZCAmJiBBcnJheS5pc0FycmF5KHBhcmFtc1dpdGhEZWZhdWx0cz8uc29ydCkgJiYgcGFyYW1zV2l0aERlZmF1bHRzPy5zb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJhbXNXaXRoRGVmYXVsdHM/LnNvcnQubWFwKFxuICAgICAgICAgICAgICAgIHMgPT5cbiAgICAgICAgICAgICAgICAgICAgPFNvcnRNZXRhPntcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkOiBzLnByb3BlcnR5LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXI6IHMuYXNjZW5kaW5nID8gMSA6IC0xXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRpYWxpemVEYXRhTG9hZGluZ1RyaWdnZXJzKCkge1xuICAgICAgICBpZiAodGhpcy51c2VRdWVyeVBhcmFtcykge1xuICAgICAgICAgICAgLy8gdHJpZ2dlciB0YWJsZSBsb2FkcyBmcm9tIHJvdXRlIHVwZGF0ZXNcbiAgICAgICAgICAgIHRoaXMucm91dGUucXVlcnlQYXJhbXMucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKHFwID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRUYWJsZUZyb21Sb3V0ZVVwZGF0ZShxcCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMucm91dGVyLmV2ZW50c1xuICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgZSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgTmF2aWdhdGlvblN0YXJ0ICYmIGUudXJsLnNwbGl0KCc/JylbMF0uc3BsaXQoJyMnKVswXSAhPT0gdGhpcy5yb3V0ZXIudXJsLnNwbGl0KCc/JylbMF0uc3BsaXQoJyMnKVswXSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uQ2FuY2VsIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25FcnJvclxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm91dGVySXNOYXZpZ2F0aW9uT3V0c2lkZUluUHJvZ3Jlc3MgPSBlIGluc3RhbmNlb2YgTmF2aWdhdGlvblN0YXJ0O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gbG9hZCBkYXRhIGltbWVkaWF0ZWx5IGJ5IGNyZWF0aW5nIGRlZmF1bHQgc29ydHMgYW5kIGZpbHRlcnMgKHByaW1lbmcgd2lsbCB0cmlnZ2VyIG9uTGF6eUxvYWQgZXZlbnQgb24gc29ydCZmaWx0ZXIgbWV0YWRhdGEgY2hhbmdlKVxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdFNvcnQgPSB0aGlzLmNyZWF0ZVNvcnRNZXRhKCk7XG4gICAgICAgICAgICBpZiAoIWRlZmF1bHRTb3J0IHx8IGRlZmF1bHRTb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5zb3J0TWV0YS5zZXQoZGVmYXVsdFNvcnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0RmlsdGVyID0gdGhpcy5jcmVhdGVGaWx0ZXJNZXRhKCk7XG4gICAgICAgICAgICBpZiAoZGVmYXVsdEZpbHRlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmZpbHRlck1ldGEuc2V0KGRlZmF1bHRGaWx0ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uVG9nZ2xlKGV2ZW50OiBNdWx0aVNlbGVjdENoYW5nZUV2ZW50KSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gWy4uLnRoaXMuY29sdW1ucygpXTtcbiAgICAgICAgZm9yIChjb25zdCBjb2wgb2YgY29sdW1ucykge1xuICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gZXZlbnQudmFsdWUuaW5jbHVkZXMoY29sKTtcbiAgICAgICAgICAgIGlmIChpc1Zpc2libGUgIT09IGNvbC5pc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgICBjb2wuaXNWaXNpYmxlID0gaXNWaXNpYmxlO1xuICAgICAgICAgICAgICAgIGNvbC5pZCA9IGAke2NvbC5kZXNjcmlwdG9yLnByb3BlcnR5fS0ke3RpbWVzdGFtcH1gO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29sdW1ucy5zZXQoY29sdW1ucyk7XG4gICAgICAgIHRoaXMubGF5b3V0UHJlZmVyZW5jZXMuY29sdW1uVmlzaWJpbGl0eSA9IHRoaXMudmlzaWJsZUNvbHVtbnMoKS5tYXAoZWwgPT4gZWwuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uVG9nZ2xlQWxsKCkge1xuICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IFsuLi50aGlzLmNvbHVtbnMoKV07XG4gICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9ICFjb2x1bW5zLnNvbWUoYyA9PiBjLmlzVmlzaWJsZSk7XG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIGNvbHVtbnMpIHtcbiAgICAgICAgICAgIGlmIChpc1Zpc2libGUgIT09IGNvbC5pc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgICBjb2wuaXNWaXNpYmxlID0gaXNWaXNpYmxlO1xuICAgICAgICAgICAgICAgIGNvbC5pZCA9IGAke2NvbC5kZXNjcmlwdG9yLnByb3BlcnR5fS0ke3RpbWVzdGFtcH1gO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29sdW1ucy5zZXQoY29sdW1ucyk7XG4gICAgICAgIHRoaXMubGF5b3V0UHJlZmVyZW5jZXMuY29sdW1uVmlzaWJpbGl0eSA9IHRoaXMudmlzaWJsZUNvbHVtbnMoKS5tYXAoZWwgPT4gZWwuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uUmVvcmRlcihldmVudDogVGFibGVDb2x1bW5SZW9yZGVyRXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmRyb3BJbmRleCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmRyb3BJbmRleCA+PSAwICYmIGV2ZW50LmRyYWdJbmRleCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmRyYWdJbmRleCA+PSAwICYmIGV2ZW50LmRyb3BJbmRleCAhPT0gZXZlbnQuZHJhZ0luZGV4KSB7XG4gICAgICAgICAgICBjb25zdCBldmVudERyb3BJbmRleCA9IGV2ZW50LmRyb3BJbmRleDtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RHJhZ0luZGV4ID0gZXZlbnQuZHJhZ0luZGV4O1xuICAgICAgICAgICAgY29uc3QgcHJldlZpc2libGVDb2x1bW5zID0gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKGVsID0+IGVsLmlzVmlzaWJsZSk7XG4gICAgICAgICAgICBjb25zdCBjb2xBdERyb3AgPSBwcmV2VmlzaWJsZUNvbHVtbnNbZXZlbnREcm9wSW5kZXhdO1xuICAgICAgICAgICAgY29uc3QgY29sQXREcmFnID0gcHJldlZpc2libGVDb2x1bW5zW2V2ZW50RHJhZ0luZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGNvbEF0RHJvcEluZGV4ID0gdGhpcy5jb2x1bW5zKCkuZmluZEluZGV4KGVsID0+IGVsLmlkID09PSBjb2xBdERyb3AuaWQpO1xuICAgICAgICAgICAgY29uc3QgY29sQXREcmFnSW5kZXggPSB0aGlzLmNvbHVtbnMoKS5maW5kSW5kZXgoZWwgPT4gZWwuaWQgPT09IGNvbEF0RHJhZy5pZCk7XG5cbiAgICAgICAgICAgIGlmIChjb2xBdERyb3BJbmRleCA+IC0xICYmIGNvbEF0RHJhZ0luZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICBsZXQgY29sdW1ucyA9IFsuLi50aGlzLmNvbHVtbnMoKV07XG4gICAgICAgICAgICAgICAgY29sdW1ucy5zcGxpY2UoY29sQXREcmFnSW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRyb3BJbmRleCA9IGNvbHVtbnMuZmluZEluZGV4KGVsID0+IGVsLmlkID09PSBjb2xBdERyb3AuaWQpICsgKGV2ZW50RHJvcEluZGV4ID4gZXZlbnREcmFnSW5kZXggPyAxIDogMCk7XG4gICAgICAgICAgICAgICAgY29sdW1ucyA9IFsuLi5jb2x1bW5zLnNsaWNlKDAsIGRyb3BJbmRleCksIGNvbEF0RHJhZywgLi4uY29sdW1ucy5zbGljZShkcm9wSW5kZXgpXTtcbiAgICAgICAgICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gTWF0aC5taW4oZXZlbnREcm9wSW5kZXgsIGV2ZW50RHJhZ0luZGV4KTsgaSA8IGNvbHVtbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uc1tpXS5pZCA9IGAke2NvbHVtbnNbaV0uZGVzY3JpcHRvci5wcm9wZXJ0eX0tJHt0aW1lc3RhbXB9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5zLnNldChjb2x1bW5zKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dFByZWZlcmVuY2VzLmNvbHVtbk9yZGVyID0gY29sdW1ucy5tYXAoZWwgPT4gZWwuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zYXZlTGF5b3V0UHJlZmVyZW5jZXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2F2ZUxheW91dFByZWZlcmVuY2VzKCkge1xuICAgICAgICBpZiAodGhpcy5kZXNjcmlwdG9yKCkubW9kZWwudHlwZU5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxTdG9yYWdlU2VydmljZS5zZXRJdGVtKHRoaXMuY21wVHlwZU5hbWUsIHRoaXMubG9jYWxzdG9yYWdlS2V5LCB0aGlzLmxheW91dFByZWZlcmVuY2VzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3Vic2NyaWJlVG9RdWVyeUlucHV0KCkge1xuICAgICAgICB0aGlzLnJlc3VsdFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcblxuICAgICAgICBpZiAoIXRoaXMucmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlc3VsdFN1YnNjcmlwdGlvbiA9IHRoaXMucmVzdWx0LnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZGF0YS5zZXQocmVzPy5kYXRhID8/IFtdKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmNvdW50LnNldChyZXM/LnRvdGFsQ291bnQgPz8gMCk7XG4gICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3Vic2NyaWJlVG9JdGVtc0lucHV0KCkge1xuICAgICAgICB0aGlzLml0ZW1zU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuXG4gICAgICAgIGlmICghdGhpcy5pdGVtcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pdGVtc1N1YnNjcmlwdGlvbiA9IHRoaXMuaXRlbXMuc3Vic2NyaWJlKHFyID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmRhdGEuc2V0KHFyKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmNvdW50LnNldChxci5sZW5ndGgpO1xuICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNldCBjb2x1bW4gb3JkZXIgYW5kIGNvbHVtbiB2aXNpYmlsaXR5IHRvIGRlZmF1bHQgc2V0dGluZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVzZXREZWZhdWx0TGF5b3V0KCkge1xuICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IHRoaXMuZGVzY3JpcHRvcigpLmNvbHVtbnMubWFwKGNvbCA9PiAoe2lkOiBgJHtjb2wucHJvcGVydHl9LSR7dGltZXN0YW1wfWAsIGRlc2NyaXB0b3I6IGNvbCwgZGlzYWJsZWQ6ICFjb2wuaXNUb2dnbGVhYmxlLCBpc1Zpc2libGU6IGNvbC5pc1Zpc2libGV9KSk7XG4gICAgICAgIHRoaXMuY29sdW1ucy5zZXQoY29sdW1ucyk7XG4gICAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3IoKS5tb2RlbC50eXBlTmFtZSkge1xuICAgICAgICAgICAgdGhpcy5sb2NhbFN0b3JhZ2VTZXJ2aWNlLnJlbW92ZUl0ZW0odGhpcy5jbXBUeXBlTmFtZSwgdGhpcy5sb2NhbHN0b3JhZ2VLZXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sYXlvdXRQcmVmZXJlbmNlcyA9IHt9O1xuICAgIH1cbn1cbiIsIjxkaXYgW3N0eWxlLmhlaWdodF09XCJ0YWJsZUZ1bGxIZWlnaHRPZmZzZXQoKSA/ICdjYWxjKDEwMHZoIC0gJyArIHRhYmxlRnVsbEhlaWdodE9mZnNldCgpICsgJ3B4KScgOiBudWxsXCI+XG4gICAgPCEtLSBNVVNUIE5PVCB1c2Ugb2JzZXJ2YWJsZSBmb3IgdmFsdWUgd2hlbiB1c2luZyB2aXJ0dWFsIHNjcm9sbCAtIGRvZXMgbm90IHdvcmsgZm9yIHNvbWUgcmVhc29uIC0tPlxuICAgIEBpZiAoIXVzZVF1ZXJ5UGFyYW1zIHx8IHVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQoKSkge1xuICAgICAgICA8cC10YWJsZVxuICAgICAgICAgICAgW3ZhbHVlXT1cImRhdGFMaXN0U2VydmljZS5kYXRhKClcIlxuICAgICAgICAgICAgW2RhdGFLZXldPVwiZGVzY3JpcHRvcigpLnRyYWNrUHJvcGVydHlcIlxuICAgICAgICAgICAgW2xhenldPVwiaXNMYXp5KClcIlxuICAgICAgICAgICAgW2xvYWRpbmddPVwiZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcoKVwiXG4gICAgICAgICAgICBbcGFnaW5hdG9yXT1cImlzUGFnaW5hdGlvbigpICYmICFpbmZpbml0ZVNjcm9sbCgpXCJcbiAgICAgICAgICAgIFtyb3dzXT1cImluZmluaXRlU2Nyb2xsKCkgPyAyMCA6IGRhdGFMaXN0U2VydmljZS5yb3dzKClcIlxuICAgICAgICAgICAgW2ZpcnN0XT1cImluZmluaXRlU2Nyb2xsKCkgPyAwIDogZGF0YUxpc3RTZXJ2aWNlLm9mZnNldCgpXCJcbiAgICAgICAgICAgIFt0b3RhbFJlY29yZHNdPVwiZGF0YUxpc3RTZXJ2aWNlLmNvdW50KClcIlxuICAgICAgICAgICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJpbmZpbml0ZVNjcm9sbCgpID8gdW5kZWZpbmVkIDogZGF0YUxpc3RTZXJ2aWNlLnJvd3NQZXJQYWdlT3B0aW9ucygpXCJcbiAgICAgICAgICAgIFtzaG93Q3VycmVudFBhZ2VSZXBvcnRdPVwiIWluZmluaXRlU2Nyb2xsKClcIlxuICAgICAgICAgICAgW2N1cnJlbnRQYWdlUmVwb3J0VGVtcGxhdGVdPVwiJ21uZ1RhYmxlLnBhZ2luYXRpb25Nc2cnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIFttdWx0aVNvcnRNZXRhXT1cImRhdGFMaXN0U2VydmljZS5zb3J0TWV0YSgpXCJcbiAgICAgICAgICAgIFtmaWx0ZXJzXT1cImRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhKClcIlxuICAgICAgICAgICAgW2dsb2JhbEZpbHRlckZpZWxkc109XCJkYXRhTGlzdFNlcnZpY2UuZ2xvYmFsRmlsdGVyRmllbGRzKClcIlxuICAgICAgICAgICAgc29ydE1vZGU9XCJtdWx0aXBsZVwiXG4gICAgICAgICAgICBbc2VsZWN0aW9uXT1cIltdXCJcbiAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwib25TZWxlY3Rpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICBbc2VsZWN0aW9uTW9kZV09XCJzZWxlY3Rpb25FbmFibGVkID8gc2VsZWN0aW9uTW9kZSA6IG51bGxcIlxuICAgICAgICAgICAgW3Njcm9sbGFibGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbdmlydHVhbFNjcm9sbF09XCJpbmZpbml0ZVNjcm9sbCgpXCJcbiAgICAgICAgICAgIFt2aXJ0dWFsU2Nyb2xsSXRlbVNpemVdPVwicm93SGVpZ2h0KClcIlxuICAgICAgICAgICAgc2Nyb2xsSGVpZ2h0PVwiZmxleFwiXG4gICAgICAgICAgICBbcm93SG92ZXJdPVwiZGVzY3JpcHRvcigpLmhhc0hvdmVyXCJcbiAgICAgICAgICAgIFtzdHlsZUNsYXNzXT1cImNsYXNzTmFtZSgpXCJcbiAgICAgICAgICAgIFtyZXNpemFibGVDb2x1bW5zXT1cImRlc2NyaXB0b3IoKS5oYXNSZXNpemFibGVDb2x1bW5zXCJcbiAgICAgICAgICAgIFtjb2x1bW5SZXNpemVNb2RlXT1cImRlc2NyaXB0b3IoKS5jb2x1bW5SZXNpemVNb2RlID8/ICdleHBhbmQnXCJcbiAgICAgICAgICAgIFtyZW9yZGVyYWJsZUNvbHVtbnNdPVwiYXJlQ29sdW1uc1Jlb3JkZXJhYmxlKClcIlxuICAgICAgICAgICAgcGFnaW5hdG9yRHJvcGRvd25BcHBlbmRUbz1cImJvZHlcIlxuICAgICAgICAgICAgW2NvbHVtbnNdPVwidmlzaWJsZUNvbHVtbnMoKVwiXG4gICAgICAgICAgICAob25Db2xSZXNpemUpPVwib25UYWJsZUNvbHVtblJlc2l6ZSgkZXZlbnQpXCJcbiAgICAgICAgICAgIChvbkNvbFJlb3JkZXIpPVwib25Db2x1bW5SZW9yZGVyKCRldmVudClcIlxuICAgICAgICAgICAgKG9uTGF6eUxvYWQpPVwib25UYWJsZUxhenlMb2FkKCRldmVudClcIlxuICAgICAgICAgICAgKG9uU29ydCk9XCJvblRhYmxlU29ydCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChvbkZpbHRlcik9XCJvblRhYmxlRmlsdGVyKCRldmVudClcIj5cbiAgICAgICAgICAgIEBpZiAoY2FwdGlvblRlbXBsYXRlKCkgfHwgY2FwdGlvbkNvbXBvbmVudCB8fCBkZXNjcmlwdG9yKCkudGl0bGUpIHtcbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiY2FwdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKGNhcHRpb25UZW1wbGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY2FwdGlvblRlbXBsYXRlKClcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY2FwdGlvbkNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbW5nQ29tcG9uZW50XT1cImNhcHRpb25Db21wb25lbnRcIiAoaW5zdGFuY2VDcmVhdGVkKT1cImNhcHRpb25DbXBJbnN0RXZlbnRFbWl0dGVyLm5leHQoJGV2ZW50KVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxoNSBjbGFzcz1cInAtMCBtLTBcIj57eyBkZXNjcmlwdG9yKCkudGl0bGUgfX08L2g1PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIj5cbiAgICAgICAgICAgICAgICBAaWYgKCFkZXNjcmlwdG9yKCkuaGlkZUhlYWRlcikge1xuICAgICAgICAgICAgICAgICAgICA8dHIgY2xhc3M9XCJtbmctdGFibGUtaGVhZGVyXCIgW2NsYXNzXT1cImRlc2NyaXB0b3IoKS5oZWFkZXJDbGFzc05hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uTW9kZSA9PT0gJ211bHRpcGxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC10YWJsZUhlYWRlckNoZWNrYm94PjwvcC10YWJsZUhlYWRlckNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFdlIG5lZWQgdGhlIGxpbmUgYmVsb3csIGJlY2F1c2Ugb3RoZXJ3aXNlIHAtdGFibGVSYWRpb0J1dHRvbiBzaGlmdHMgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMgaW4gdGFibGUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cIm1pbi13aWR0aDogMzZweFwiIHBGcm96ZW5Db2x1bW4gW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuc2VsZWN0aW9uQ29sdW1uRnJvemVuID8/IHRydWVcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjbGFzcz1cImNvbC0xXCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cInRydWVcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoY29sIG9mIHZpc2libGVDb2x1bW5zKCk7IHRyYWNrIGNvbC5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc29ydGFibGVDb2x1bW5USFRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbC5kZXNjcmlwdG9yLnRpdGxlID8/IChjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eSB8IG1uZ0kxOG5Qcm9wZXJ0eTogZGVzY3JpcHRvcigpLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtc29ydEljb24gW2ZpZWxkXT1cImNvbC5kZXNjcmlwdG9yLnByb3BlcnR5XCI+PC9wLXNvcnRJY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9uU29ydGFibGVDb2x1bW5USFRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb2wuZGVzY3JpcHRvci50aXRsZSA/PyAoY29sLmRlc2NyaXB0b3IucHJvcGVydHkgfCBtbmdJMThuUHJvcGVydHk6IGRlc2NyaXB0b3IoKS5tb2RlbCkgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sLmRlc2NyaXB0b3IuaXNSZW9yZGVyYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBSZXNpemFibGVDb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBSZW9yZGVyYWJsZUNvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lkXT1cImNvbC5kZXNjcmlwdG9yLnByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwU29ydGFibGVDb2x1bW5dPVwiY29sLnNvcnQ/LnByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwU29ydGFibGVDb2x1bW5EaXNhYmxlZF09XCIhY29sLnNvcnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCA/IGNvbC53aWR0aCArICdweCcgOiBjb2wuZGVzY3JpcHRvci53aWR0aCArICclJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbC53aWR0aCA/IG51bGwgOiBjb2wuZGVzY3JpcHRvci5taW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbC53aWR0aCA/PyBjb2wuZGVzY3JpcHRvci5tYXhXaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiY29sLmRlc2NyaXB0b3IuaGVhZGVyQ2xhc3NOYW1lIHwgbW5nVGFibGVDb2x1bW5GaWx0ZXJDbGFzczogY29sLmZpbHRlciA6IGhhc0NvbHVtbkZpbHRlcnMoKSAmJiAhY29sLndpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY29sLnNvcnQgPyBzb3J0YWJsZUNvbHVtblRIVGVtcGxhdGUgOiBub25Tb3J0YWJsZUNvbHVtblRIVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUmVzaXphYmxlQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiY29sLmRlc2NyaXB0b3IucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbl09XCJjb2wuc29ydD8ucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbkRpc2FibGVkXT1cIiFjb2wuc29ydFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoID8gY29sLndpZHRoICsgJ3B4JyA6IGNvbC5kZXNjcmlwdG9yLndpZHRoICsgJyUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5kZXNjcmlwdG9yLm1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJjb2wuZGVzY3JpcHRvci5oZWFkZXJDbGFzc05hbWUgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2wuc29ydCA/IHNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZSA6IG5vblNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaGFzTGFzdENvbHVtbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uTGFzdE1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEZyb3plbkNvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5hY3Rpb25Db2x1bW5Gcm96ZW4gPz8gYXJlQ29sdW1uc1RvZ2dsZWFibGUoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduRnJvemVuPVwicmlnaHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbHVtbi1jdXN0b20tbGFzdCB0ZXh0LXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZGVzY3JpcHRvcigpLmhhc1Jlc2l6YWJsZUNvbHVtbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLW11bHRpU2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2NvbHVtblRvZ2dsZU11bHRpc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVDbGFzcz1cInAtYnV0dG9uLXByaW1hcnkgbW5nLXRhYmxlLWNvbHVtbnMtbXVsdGlzZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZFRvPVwiYm9keVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUtleT1cImlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJsZWZ0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJvcGRvd25JY29uPVwicGkgcGktc2xpZGVycy1oXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsdGVyXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJjb2x1bW5zKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInZpc2libGVDb2x1bW5zKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCInbW5nVGFibGUuYWRqdXN0VGFibGUnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzcGxheVNlbGVjdGVkTGFiZWxdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvbkNvbHVtblRvZ2dsZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImZpbHRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jaGVja2JveCBwLWNvbXBvbmVudCBtbC0xXCIgW25nQ2xhc3NdPVwieydwLWNoZWNrYm94LWRpc2FibGVkJzogIWFyZUNvbHVtbnNUb2dnbGVhYmxlfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtaGlkZGVuLWFjY2Vzc2libGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZG9ubHk9XCJyZWFkb25seVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImNvbHVtblRvZ2dsZU11bHRpc2VsZWN0LmFsbFNlbGVjdGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cImNvbHVtblRvZ2dsZU11bHRpc2VsZWN0Lm9uSGVhZGVyQ2hlY2tib3hGb2N1cygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJsdXIpPVwiY29sdW1uVG9nZ2xlTXVsdGlzZWxlY3Qub25IZWFkZXJDaGVja2JveEJsdXIoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlkb3duLnNwYWNlKT1cImNvbHVtblRvZ2dsZU11bHRpc2VsZWN0Lm9uVG9nZ2xlQWxsKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIWFyZUNvbHVtbnNUb2dnbGVhYmxlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1jaGVja2JveC1ib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvbGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1jaGVja2VkXT1cImNvbHVtblRvZ2dsZU11bHRpc2VsZWN0LmFsbFNlbGVjdGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwLWhpZ2hsaWdodCc6IGFueUNvbHVtblZpc2libGUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkNvbHVtblRvZ2dsZUFsbCgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwLWNoZWNrYm94LWljb25cIiBbbmdDbGFzc109XCJ7J3BpIHBpLWNoZWNrJzogYW55Q29sdW1uVmlzaWJsZSgpfVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktcmVwbGF5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQ2xhc3M9XCJwLWJ1dHRvbi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BUb29sdGlwXT1cIidtbmdUYWJsZS5yZXNldExheW91dCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwibGVmdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVzZXREZWZhdWx0TGF5b3V0KClcIj48L3AtYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIGxldC1pdGVtIHBUZW1wbGF0ZT1cIml0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgaXRlbS5kZXNjcmlwdG9yLnRpdGxlID8/IChpdGVtLmRlc2NyaXB0b3IucHJvcGVydHkgfCBtbmdJMThuUHJvcGVydHk6IGRlc2NyaXB0b3IoKS5tb2RlbCkgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wLW11bHRpU2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGlmIChoYXNDb2x1bW5GaWx0ZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwibW5nLWNvbHVtbi1maWx0ZXItcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFdlIG5lZWQgdGhlIGxpbmUgYmVsb3csIGJlY2F1c2Ugb3RoZXJ3aXNlIHAtdGFibGVSYWRpb0J1dHRvbiBzaGlmdHMgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMgaW4gdGFibGUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHNlbGVjdGlvbkVuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKGNvbCBvZiB2aXNpYmxlQ29sdW1ucygpOyB0cmFjayBjb2wuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cImNvbC5maWx0ZXI/LmNvbHVtbkNsYXNzTmFtZSB8IG1uZ1RhYmxlQ29sdW1uRmlsdGVyQ2xhc3M6IGNvbC5maWx0ZXIgOiBoYXNDb2x1bW5GaWx0ZXJzKCkgJiYgIWNvbC53aWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJjb2wud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJjb2wud2lkdGggPyBudWxsIDogY29sLmZpbHRlcj8uY29sdW1uV2lkdGggPz8gY29sLmRlc2NyaXB0b3Iud2lkdGggPz8gbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5maWx0ZXI/LmNvbHVtbk1pbldpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2wud2lkdGggPz8gY29sLmRlc2NyaXB0b3IubWF4V2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChjb2wuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bW5nLXRhYmxlLWNvbHVtbi1maWx0ZXItZnVsbCBbZGVzY3JpcHRvcl09XCJjb2wuZmlsdGVyXCI+PC9tbmctdGFibGUtY29sdW1uLWZpbHRlci1mdWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaGFzTGFzdENvbHVtbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiY29sdW1uLWN1c3RvbS1sYXN0XCIgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2x1bW5MYXN0TWluV2lkdGhcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiYm9keVwiIGxldC1pdGVtIGxldC1pZHg9XCJyb3dJbmRleFwiIGxldC1leHBhbmRlZD1cImV4cGFuZGVkXCI+XG4gICAgICAgICAgICAgICAgPHRyXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwicm93SGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZGVzY3JpcHRvcigpLnJvd0NsYXNzTmFtZSB8IG1uZ0NsYXNzTWFwOiBkZXNjcmlwdG9yKCkucm93Q2xhc3NOYW1lTWFwRm4gOiBpdGVtIHwgbW5nTG9jYWxlRGVmYXVsdFJvd0NsYXNzOiBkZXNjcmlwdG9yKCkgOiBpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25Nb2RlID09PSAnbXVsdGlwbGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5zZWxlY3Rpb25Db2x1bW5Gcm96ZW4gPz8gdHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC10YWJsZUNoZWNrYm94IFt2YWx1ZV09XCJpdGVtXCI+PC9wLXRhYmxlQ2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cIm1pbi13aWR0aDogMzZweFwiIHBGcm96ZW5Db2x1bW4gW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuc2VsZWN0aW9uQ29sdW1uRnJvemVuID8/IHRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFibGVSYWRpb0J1dHRvbiBbdmFsdWVdPVwiaXRlbVwiPjwvcC10YWJsZVJhZGlvQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKCFkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZVByb3BlcnR5IHx8IGl0ZW1bZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGVQcm9wZXJ0eSFdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BSb3dUb2dnbGVyXT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi10ZXh0IHAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tcGxhaW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ljb25dPVwiZXhwYW5kZWQgPyAncGkgcGktY2hldnJvbi1kb3duJyA6ICdwaSBwaS1jaGV2cm9uLXJpZ2h0J1wiPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGZvciAoY29sIG9mIHZpc2libGVDb2x1bW5zKCk7IHRyYWNrIGNvbC5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2VsbENsaWNrKCRldmVudCwgY29sLmRlc2NyaXB0b3IsIGl0ZW0sIGlkeClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmRlc2NyaXB0b3IuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG1uZ0NsYXNzTWFwOiBjb2wuZGVzY3JpcHRvci5jbGFzc05hbWVNYXBGbiA6IGl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgbW5nVGFibGVDb2x1bW5GaWx0ZXJDbGFzczogY29sLmZpbHRlciA6IGhhc0NvbHVtbkZpbHRlcnMoKSAmJiAhY29sLndpZHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY2xpY2thYmxlXT1cImNlbGxDbGlja0V2ZW50RW1pdHRlci5vYnNlcnZlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCA/IGNvbC53aWR0aCArICdweCcgOiBjb2wuZGVzY3JpcHRvci53aWR0aCArICclJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2wud2lkdGggPyBudWxsIDogY29sLmRlc2NyaXB0b3IubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5kZXNjcmlwdG9yLnRpdGxlID8/IChjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eSB8IG1uZ0kxOG5Qcm9wZXJ0eTogZGVzY3JpcHRvcigpLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bW5nLXRhYmxlLWNvbHVtbi12YWx1ZSBbZGVzY3JpcHRvcl09XCJjb2wuZGVzY3JpcHRvclwiIFtpdGVtXT1cIml0ZW1cIj48L21uZy10YWJsZS1jb2x1bW4tdmFsdWU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoaGFzTGFzdENvbHVtbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbHVtbi1jdXN0b20tbGFzdCBqdXN0aWZ5LWNvbnRlbnQtZW5kIHRleHQtcmlnaHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uTGFzdE1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuYWN0aW9uQ29sdW1uRnJvemVuID8/IHRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduRnJvemVuPVwicmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGNvbHVtbkN1c3RvbUxhc3RUZW1wbGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2x1bW5DdXN0b21MYXN0VGVtcGxhdGUoKTsgY29udGV4dDoge3Jvd0l0ZW06IGl0ZW0sIHJvd0luZGV4OiBpZHh9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFttbmdDb21wb25lbnRdPVwiY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudFwiIChpbnN0YW5jZUNyZWF0ZWQpPVwiY29sdW1uQ3VzdG9tTGFzdENtcEluc3RFdmVudEVtaXR0ZXIubmV4dCgkZXZlbnQpXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgQGlmIChkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZSkge1xuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJyb3dleHBhbnNpb25cIiBsZXQtaXRlbT5cbiAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLTFcIj48L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIFtjb2xTcGFuXT1cImRlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlQ29sU3BhblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJyb3dFeHBhbmRUZW1wbGF0ZSgpOyBjb250ZXh0OiB7cm93SXRlbTogaXRlbX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJsb2FkaW5naWNvblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sdW1uIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5sb2FkaW5nSWNvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGkgW2NsYXNzXT1cIid0ZXh0LXdoaXRlIHRleHQtNHhsIHBpLXNwaW4gJyArIGRlc2NyaXB0b3IoKS5sb2FkaW5nSWNvblwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5sb2FkaW5nVGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQgdGV4dC13aGl0ZSB0ZXh0LWxnIGZvbnQtc2VtaWJvbGRcIiBbbmdDbGFzc109XCJ7J210LTMnOiBkZXNjcmlwdG9yKCkubG9hZGluZ0ljb259XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZGVzY3JpcHRvcigpLmxvYWRpbmdUZXh0ID8/ICcnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJsb2FkaW5nYm9keVwiPlxuICAgICAgICAgICAgICAgIDx0ciBbc3R5bGUuaGVpZ2h0LnB4XT1cInJvd0hlaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJ2aXNpYmxlQ29sdW1ucygpLmxlbmd0aCArIChoYXNMYXN0Q29sdW1uKCkgPyAxIDogMCkgKyAoc2VsZWN0aW9uRW5hYmxlZCA/IDEgOiAwKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvYWRpbmctdGV4dFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtc2tlbGV0b24gW25nU3R5bGVdPVwie3dpZHRoOiAnMTAwJSd9XCI+PC9wLXNrZWxldG9uPlxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImVtcHR5bWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgIDx0ciBbc3R5bGUuaGVpZ2h0LnB4XT1cInJvd0hlaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJ2aXNpYmxlQ29sdW1ucygpLmxlbmd0aCArIChoYXNMYXN0Q29sdW1uKCkgPyAxIDogMCkgKyAoc2VsZWN0aW9uRW5hYmxlZCA/IDEgOiAwKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgJ21uZ1RhYmxlLm5vSXRlbXMnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICBAaWYgKGZvb3RlclRlbXBsYXRlKCkpIHtcbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwic3VtbWFyeVwiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9vdGVyVGVtcGxhdGUoKTsgY29udGV4dDoge2RhdGE6IGRhdGFMaXN0U2VydmljZS5kYXRhKCksIHRvdGFsQ291bnQ6IGRhdGFMaXN0U2VydmljZS5jb3VudCgpfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICB9XG4gICAgICAgIDwvcC10YWJsZT5cbiAgICB9XG48L2Rpdj5cbiJdfQ==
563
+ ], providers: [DataListService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [style.height]=\"tableFullHeightOffset() ? 'calc(100vh - ' + tableFullHeightOffset() + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams() || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination() && !infiniteScroll()\"\n [rows]=\"infiniteScroll() ? 20 : dataListService.rows()\"\n [first]=\"infiniteScroll() ? 0 : dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"infiniteScroll() ? undefined : dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"!infiniteScroll()\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll()\"\n [virtualScrollItemSize]=\"rowHeight()\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\">\n @if (captionTemplate() || captionComponent() || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent()) {\n <div [mngComponent]=\"captionComponent()\" (instanceCreated)=\"captionComponentInstance.emit($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [style.height.px]=\"rowHeight()\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent()) {\n <div [mngComponent]=\"columnCustomLastComponent()\" (instanceCreated)=\"columnCustomLastComponentInstance.emit($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled() ? 1 : 0)\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"visibleColumns().length + (hasLastColumn() ? 1 : 0) + (selectionEnabled() ? 1 : 0)\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n" }]
564
+ }], ctorParameters: () => [] });
565
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDOUUsT0FBTyxFQUNILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUtSLGVBQWUsRUFDZixRQUFRLEVBQ1IsZUFBZSxFQUNmLE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEVBQ04sU0FBUyxFQUNULFlBQVksRUFDZixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsb0JBQW9CLEVBQUUsWUFBWSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQVUsTUFBTSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFbEksT0FBTyxFQUFDLGVBQWUsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3RFLE9BQU8sRUFBaUIsY0FBYyxFQUFXLE1BQU0sYUFBYSxDQUFDO0FBQ3JFLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1QyxPQUFPLEVBQXlCLGlCQUFpQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDOUUsT0FBTyxFQUFDLEtBQUssRUFBK0MsV0FBVyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzlGLE9BQU8s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QkFBMEI7d0JBQzFCLFdBQVc7d0JBQ1gsaUJBQWlCO3dCQUNqQixZQUFZO3dCQUNaLGFBQWE7d0JBQ2IsZUFBZTt3QkFDZixXQUFXO3FCQUNkLGFBQ1UsQ0FBQyxlQUFlLENBQUMsbUJBQ1gsdUJBQXVCLENBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QXN5bmNQaXBlLCBOZ0NsYXNzLCBOZ1N0eWxlLCBOZ1RlbXBsYXRlT3V0bGV0fSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgSW5qZWN0b3IsXG4gICAgT25EZXN0cm95LFxuICAgIFNpZ25hbCxcbiAgICBUZW1wbGF0ZVJlZixcbiAgICBUeXBlLFxuICAgIGFmdGVyTmV4dFJlbmRlcixcbiAgICBjb21wdXRlZCxcbiAgICBjb250ZW50Q2hpbGRyZW4sXG4gICAgZWZmZWN0LFxuICAgIGluamVjdCxcbiAgICBpbnB1dCxcbiAgICBvdXRwdXQsXG4gICAgc2lnbmFsLFxuICAgIHZpZXdDaGlsZCxcbiAgICB2aWV3Q2hpbGRyZW5cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge291dHB1dEZyb21PYnNlcnZhYmxlLCB0b09ic2VydmFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7Rm9ybXNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7QWN0aXZhdGVkUm91dGUsIE5hdmlnYXRpb25DYW5jZWwsIE5hdmlnYXRpb25FbmQsIE5hdmlnYXRpb25FcnJvciwgTmF2aWdhdGlvblN0YXJ0LCBQYXJhbXMsIFJvdXRlcn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcblxuaW1wb3J0IHtUcmFuc2xhdGVNb2R1bGUsIFRyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtGaWx0ZXJNZXRhZGF0YSwgTWVzc2FnZVNlcnZpY2UsIFNvcnRNZXRhfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQge0J1dHRvbk1vZHVsZX0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHtNdWx0aVNlbGVjdENoYW5nZUV2ZW50LCBNdWx0aVNlbGVjdE1vZHVsZX0gZnJvbSAncHJpbWVuZy9tdWx0aXNlbGVjdCc7XG5pbXBvcnQge1RhYmxlLCBUYWJsZUNvbHVtblJlb3JkZXJFdmVudCwgVGFibGVMYXp5TG9hZEV2ZW50LCBUYWJsZU1vZHVsZX0gZnJvbSAncHJpbWVuZy90YWJsZSc7XG5pbXBvcnQge1Rvb2x0aXBNb2R1bGV9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5pbXBvcnQge05FVkVSLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGNvbWJpbmVMYXRlc3QsIG9mLCBzd2l0Y2hNYXB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtmaWx0ZXJ9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgICBDbGFzc01hcFBpcGUsXG4gICAgQ29tbW9uc1NlcnZpY2UsXG4gICAgQ29tcG9uZW50RGlyZWN0aXZlLFxuICAgIERhdGFMaXN0UGFyYW1zLFxuICAgIERhdGFMaXN0UmVzdWx0LFxuICAgIEZpbHRlck1hdGNoTW9kZSxcbiAgICBJMThuUHJvcGVydHlQaXBlLFxuICAgIExvY2FsU3RvcmFnZVNlcnZpY2UsXG4gICAgTG9nZ2VyU2VydmljZSxcbiAgICBUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICBib29sZWFuT3JVbmRlZmluZWRBdHRyaWJ1dGUsXG4gICAgdG9PYnNlcnZhYmxlIGFzIGNvbW1vbnNUb09ic2VydmFibGUsXG4gICAgZGF0YUxpc3RQYXJhbXNUb1VybFF1ZXJ5LFxuICAgIGZpbmRUZW1wbGF0ZUJ5TmFtZSxcbiAgICBmcm9tU3Vic2NyaWJlRXJyb3IsXG4gICAgZnJvbVRhYmxlTG9hZFRvRGF0YUxpc3RQYXJhbXMsXG4gICAgZnJvbVVybFF1ZXJ5VG9EYXRhTGlzdFBhcmFtcyxcbiAgICBnZXRFcnJvckxvZ0xldmVsLFxuICAgIG1lcmdlRGF0YUxpc3RQYXJhbXNXaXRoRGVmYXVsdHNcbn0gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy9jb3JlJztcbmltcG9ydCB7RmlsdGVyTG9va3VwRGVzY3JpcHRvciwgRmlsdGVyVHlwZUVudW19IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvZmlsdGVyJztcbmltcG9ydCB7XG4gICAgQ29sdW1uRGVzY3JpcHRvcixcbiAgICBJVGFibGVEYXRhUHJvdmlkZXIsXG4gICAgVGFibGVDZWxsQ2xpY2tFdmVudCxcbiAgICBUYWJsZURlc2NyaXB0b3JJbnN0LFxuICAgIFRhYmxlRHluYW1pY0Rlc2NyaXB0b3JJbnN0LFxuICAgIFRhYmxlTGF5b3V0UHJlZmVyZW5jZXMsXG4gICAgVGFibGVMb2FkRXZlbnQsXG4gICAgVGFibGVQYWdpbmF0aW9uTW9kZUVudW0sXG4gICAgVGFibGVTaXplRW51bSxcbiAgICB0YWJsZURlc2NyaXB0b3Jcbn0gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy90YWJsZS9hcGknO1xuXG5pbXBvcnQge3RhYmxlTm90aWZpY2F0aW9uRXJyb3J9IGZyb20gJy4uLy4uL2hlbHBlcnMvbm90aWZpY2F0aW9uJztcbmltcG9ydCB7Z2VuZXJhdGVUYWJsZUxheW91dFByZWZzS2V5fSBmcm9tICcuLi8uLi9oZWxwZXJzL3RhYmxlLWxheW91dC1wcmVmcyc7XG5pbXBvcnQge0NvbHVtbldpdGhQcmVmZXJlbmNlc30gZnJvbSAnLi4vLi4vbW9kZWxzL2NvbHVtbi1wcmVmZXJlbmNlcy5tb2RlbCc7XG5pbXBvcnQge0xvY2FsZURlZmF1bHRSb3dDbGFzc1BpcGV9IGZyb20gJy4uLy4uL3BpcGVzL2xvY2FsZS1kZWZhdWx0LXJvdy1jbGFzcy5waXBlJztcbmltcG9ydCB7VGFibGVDb2x1bW5GaWx0ZXJDbGFzc1BpcGV9IGZyb20gJy4uLy4uL3BpcGVzL3RhYmxlLWNvbHVtbi1maWx0ZXItY2xhc3MucGlwZSc7XG5pbXBvcnQge0RhdGFMaXN0U2VydmljZX0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGF0YS1saXN0LnNlcnZpY2UnO1xuaW1wb3J0IHtUYWJsZUNvbHVtbkZpbHRlckZ1bGxDb21wb25lbnR9IGZyb20gJy4uL2NvbHVtbi1maWx0ZXItZnVsbC9jb2x1bW4tZmlsdGVyLWZ1bGwuY29tcG9uZW50JztcbmltcG9ydCB7VGFibGVDb2x1bW5WYWx1ZUNvbXBvbmVudH0gZnJvbSAnLi4vY29sdW1uLXZhbHVlL2NvbHVtbi12YWx1ZS5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHNlbGVjdG9yOiAnbW5nLXRhYmxlJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQXN5bmNQaXBlLFxuICAgICAgICBDb21wb25lbnREaXJlY3RpdmUsXG4gICAgICAgIEkxOG5Qcm9wZXJ0eVBpcGUsXG4gICAgICAgIE5nQ2xhc3MsXG4gICAgICAgIE5nU3R5bGUsXG4gICAgICAgIE5nVGVtcGxhdGVPdXRsZXQsXG4gICAgICAgIFRhYmxlQ29sdW1uVmFsdWVDb21wb25lbnQsXG4gICAgICAgIENsYXNzTWFwUGlwZSxcbiAgICAgICAgTG9jYWxlRGVmYXVsdFJvd0NsYXNzUGlwZSxcbiAgICAgICAgVGFibGVDb2x1bW5GaWx0ZXJGdWxsQ29tcG9uZW50LFxuICAgICAgICBUYWJsZUNvbHVtbkZpbHRlckNsYXNzUGlwZSxcbiAgICAgICAgVGFibGVNb2R1bGUsXG4gICAgICAgIE11bHRpU2VsZWN0TW9kdWxlLFxuICAgICAgICBCdXR0b25Nb2R1bGUsXG4gICAgICAgIFRvb2x0aXBNb2R1bGUsXG4gICAgICAgIFRyYW5zbGF0ZU1vZHVsZSxcbiAgICAgICAgRm9ybXNNb2R1bGVcbiAgICBdLFxuICAgIHByb3ZpZGVyczogW0RhdGFMaXN0U2VydmljZV0sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgVGFibGVDb21wb25lbnQ8SXRlbSA9IGFueSwgU2VydmljZSA9IHVuZGVmaW5lZCwgU29ydHMgPSBhbnksIEZpbHRlcnMgZXh0ZW5kcyBrZXlvZiBhbnkgPSBhbnk+IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgY21wVHlwZU5hbWUgPSAnVGFibGVDb21wb25lbnQnO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXIgPSBpbmplY3QoTG9nZ2VyU2VydmljZSkuY3JlYXRlKHRoaXMuY21wVHlwZU5hbWUpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaW5qZWN0b3IgPSBpbmplY3QoSW5qZWN0b3IpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyID0gaW5qZWN0KFJvdXRlcik7XG4gICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZSA9IGluamVjdChBY3RpdmF0ZWRSb3V0ZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSB0cmFuc2xhdGUgPSBpbmplY3QoVHJhbnNsYXRlU2VydmljZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBtZXNzYWdlU2VydmljZSA9IGluamVjdChNZXNzYWdlU2VydmljZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBjb21tb25zID0gaW5qZWN0KENvbW1vbnNTZXJ2aWNlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvY2FsU3RvcmFnZVNlcnZpY2UgPSBpbmplY3QoTG9jYWxTdG9yYWdlU2VydmljZSk7XG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGFMaXN0U2VydmljZSA9IGluamVjdChEYXRhTGlzdFNlcnZpY2U8SXRlbT4pO1xuXG4gICAgLy8gbWV0YWRhdGEgaW5wdXRcbiAgICBwdWJsaWMgZGVzY3JpcHRvcklucHV0ID0gaW5wdXQucmVxdWlyZWQ8VGFibGVEZXNjcmlwdG9ySW5zdDxJdGVtLCBTb3J0cywgRmlsdGVycz4+KHthbGlhczogJ2Rlc2NyaXB0b3InfSk7XG5cbiAgICAvLyBkYXRhIHNvdXJjZSBpbnB1dHNcbiAgICBwdWJsaWMgaXRlbXMgPSBpbnB1dDxJdGVtW10+KCk7XG4gICAgcHVibGljIHJlc3VsdCA9IGlucHV0PERhdGFMaXN0UmVzdWx0PEl0ZW0+PigpO1xuICAgIHB1YmxpYyBsb2FkaW5nSW5wdXQgPSBpbnB1dCh1bmRlZmluZWQsIHthbGlhczogJ2xvYWRpbmcnLCB0cmFuc2Zvcm06IGJvb2xlYW5PclVuZGVmaW5lZEF0dHJpYnV0ZX0pO1xuICAgIHB1YmxpYyBkYXRhUHJvdmlkZXIgPSBpbnB1dDxJVGFibGVEYXRhUHJvdmlkZXI8SXRlbSwgU2VydmljZSwgU29ydHMsIEZpbHRlcnM+PigpO1xuXG4gICAgLy8gZXh0cmEgZmVhdHVyZXMgaW5wdXRcbiAgICBwdWJsaWMgdXNlUXVlcnlQYXJhbXNJbnB1dCA9IGlucHV0KGZhbHNlLCB7YWxpYXM6ICd1c2VRdWVyeVBhcmFtcyd9KTtcbiAgICBwdWJsaWMgY2VsbENsaWNrRW5hYmxlZCA9IGlucHV0KHRydWUpO1xuICAgIHB1YmxpYyBzZWxlY3Rpb25Nb2RlID0gaW5wdXQ8J3NpbmdsZScgfCAnbXVsdGlwbGUnPignbXVsdGlwbGUnKTtcbiAgICBwdWJsaWMgc2VsZWN0aW9uRW5hYmxlZCA9IGlucHV0KGZhbHNlKTtcblxuICAgIC8vIHN0eWxpbmdcbiAgICBwdWJsaWMgY29sdW1uTGFzdE1pbldpZHRoID0gaW5wdXQ8bnVtYmVyPigpO1xuXG4gICAgLy8gY29tcG9uZW50IGlucHV0c1xuICAgIHB1YmxpYyBjYXB0aW9uQ29tcG9uZW50ID0gaW5wdXQ8VHlwZTxhbnk+PigpO1xuICAgIHB1YmxpYyBjb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50ID0gaW5wdXQ8VHlwZTxhbnk+PigpO1xuICAgIHB1YmxpYyBnbG9iYWxGaWx0ZXJGaWVsZHNJbnB1dCA9IGlucHV0PHN0cmluZ1tdIHwgdW5kZWZpbmVkPih1bmRlZmluZWQsIHthbGlhczogJ2dsb2JhbEZpbHRlckZpZWxkcyd9KTtcblxuICAgIC8vIGNlbGwgY2xpY2tcbiAgICBwcml2YXRlIGNlbGxDbGlja1N1YmplY3QgPSBuZXcgU3ViamVjdDxUYWJsZUNlbGxDbGlja0V2ZW50PEl0ZW0+PigpO1xuICAgIHB1YmxpYyBpc0NlbGxDbGlja09ic2VydmVkID0gc2lnbmFsKHRoaXMuY2VsbENsaWNrU3ViamVjdC5vYnNlcnZlZCk7XG4gICAgcHVibGljIGlzQ2VsbENsaWNrRW5hYmxlZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY2VsbENsaWNrRW5hYmxlZCgpICYmIHRoaXMuaXNDZWxsQ2xpY2tPYnNlcnZlZCgpKTtcblxuICAgIC8vIGV2ZW50IG91dHB1dHNcbiAgICBwdWJsaWMgdGFibGVMb2FkID0gb3V0cHV0PFRhYmxlTG9hZEV2ZW50PigpO1xuICAgIHB1YmxpYyBjZWxsQ2xpY2sgPSBvdXRwdXRGcm9tT2JzZXJ2YWJsZSh0aGlzLmNlbGxDbGlja1N1YmplY3QpO1xuICAgIHB1YmxpYyBzZWxlY3Rpb25DaGFuZ2UgPSBvdXRwdXQ8QXJyYXk8SXRlbT4+KCk7XG4gICAgcHVibGljIGNhcHRpb25Db21wb25lbnRJbnN0YW5jZSA9IG91dHB1dDxhbnk+KCk7XG4gICAgcHVibGljIGNvbHVtbkN1c3RvbUxhc3RDb21wb25lbnRJbnN0YW5jZSA9IG91dHB1dDxhbnk+KCk7XG5cbiAgICAvLyBjb250ZW50IGFuZCB2aWV3IHF1ZXJpZXNcbiAgICBwdWJsaWMgdGVtcGxhdGVzID0gY29udGVudENoaWxkcmVuKFRlbXBsYXRlRGlyZWN0aXZlKTtcbiAgICBwdWJsaWMgY29tcG9uZW50cyA9IHZpZXdDaGlsZHJlbihDb21wb25lbnREaXJlY3RpdmU8YW55Pik7XG4gICAgcHVibGljIHByaW1lVGFibGUgPSB2aWV3Q2hpbGQucmVxdWlyZWQoVGFibGUpO1xuXG4gICAgLy8gdGVtcGxhdGVzXG4gICAgcHVibGljIGNhcHRpb25UZW1wbGF0ZTogU2lnbmFsPFRlbXBsYXRlUmVmPGFueT4gfCBudWxsPiA9IGNvbXB1dGVkKCgpID0+IGZpbmRUZW1wbGF0ZUJ5TmFtZShbLi4udGhpcy50ZW1wbGF0ZXMoKV0sICdjYXB0aW9uJykpO1xuICAgIHB1YmxpYyBjb2x1bW5DdXN0b21MYXN0VGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAnY29sdW1uQ3VzdG9tTGFzdCcpKTtcbiAgICBwdWJsaWMgZm9vdGVyVGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAnZm9vdGVyJykpO1xuICAgIHB1YmxpYyByb3dFeHBhbmRUZW1wbGF0ZTogU2lnbmFsPFRlbXBsYXRlUmVmPGFueT4gfCBudWxsPiA9IGNvbXB1dGVkKCgpID0+IGZpbmRUZW1wbGF0ZUJ5TmFtZShbLi4udGhpcy50ZW1wbGF0ZXMoKV0sICdyb3dFeHBhbmRDb250ZW50JykpO1xuXG4gICAgLy8gZGF0YSBwcm92aWRlciBhbmQgaXRlbXNcbiAgICBwdWJsaWMgdXNlUXVlcnlQYXJhbXMgPSBjb21wdXRlZCgoKSA9PiAodGhpcy5wYWdpbmF0aW9uTW9kZSgpID09PSBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bS5JbmZpbml0ZVNjcm9sbCA/IGZhbHNlIDogdGhpcy51c2VRdWVyeVBhcmFtc0lucHV0KCkpKTtcbiAgICBwdWJsaWMgaXNMYXp5ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kYXRhUHJvdmlkZXIoKT8uaXNMYXp5ID09PSB0cnVlKTtcbiAgICBwdWJsaWMgaXNQYWdpbmF0aW9uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5wYWdpbmF0aW9uTW9kZSgpID09PSBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bS5QYWdpbmF0aW9uKTtcbiAgICBwdWJsaWMgdXNlUXVlcnlQYXJhbXNJbml0aWFsaXplZCA9IHNpZ25hbChmYWxzZSk7XG5cbiAgICAvLyB2aXN1YWxcbiAgICBwcml2YXRlIHBhZ2luYXRpb25Nb2RlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuZGVzY3JpcHRvcigpLnBhZ2luYXRpb25Nb2RlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgLy8gZGVzY3JpcHRvciBjaG9pY2UgaXMgdGhlIG1vc3Qgc3Ryb25nIC0gaWYgZGVmaW5lZCwgdXNlIHRoaXMgdmFsdWVcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlc2NyaXB0b3IoKS5wYWdpbmF0aW9uTW9kZTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5kYXRhUHJvdmlkZXIoKSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIC8vIHdoZW4gZGF0YSBwcm92aWRlciBpcyB1c2VkLCB1c2UgcGFnaW5hdGlvblxuICAgICAgICAgICAgcmV0dXJuIFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLlBhZ2luYXRpb247XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uTm9uZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHB1YmxpYyBpbmZpbml0ZVNjcm9sbCA9IGNvbXB1dGVkKCgpID0+IHRoaXMucGFnaW5hdGlvbk1vZGUoKSA9PT0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uSW5maW5pdGVTY3JvbGwpO1xuICAgIHB1YmxpYyBjbGFzc05hbWUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGxldCBjbGFzc05hbWUgPSB0aGlzLmRlc2NyaXB0b3IoKS5jbGFzc05hbWUgPz8gJyc7XG4gICAgICAgIHN3aXRjaCAodGhpcy5kZXNjcmlwdG9yKCkuc2l6ZSkge1xuICAgICAgICAgICAgY2FzZSBUYWJsZVNpemVFbnVtLlNtYWxsOlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZSArPSAnIHAtZGF0YXRhYmxlLXNtJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVGFibGVTaXplRW51bS5MYXJnZTpcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gJyBwLWRhdGF0YWJsZS1sZyc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGVzY3JpcHRvcigpLmhhc0dyaWRsaW5lcykge1xuICAgICAgICAgICAgY2xhc3NOYW1lICs9ICcgcC1kYXRhdGFibGUtZ3JpZGxpbmVzJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2xhc3NOYW1lO1xuICAgIH0pO1xuICAgIHB1YmxpYyB0YWJsZUZ1bGxIZWlnaHRPZmZzZXQgPSBjb21wdXRlZCgoKSA9PiAodGhpcy5wYWdpbmF0aW9uTW9kZSgpID09PSBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bS5JbmZpbml0ZVNjcm9sbCA/IHRoaXMuZGVzY3JpcHRvcigpLnRhYmxlRnVsbEhlaWdodE9mZnNldCA/PyAzMTUgOiB1bmRlZmluZWQpKTtcbiAgICBwdWJsaWMgcm93SGVpZ2h0ID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMucGFnaW5hdGlvbk1vZGUoKSA9PT0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uSW5maW5pdGVTY3JvbGwgPyB0aGlzLmRlc2NyaXB0b3IoKS5yb3dIZWlnaHQgPz8gNDUgOiB1bmRlZmluZWQpKTtcblxuICAgIC8vIGRhdGEgcHJvdmlkZXJcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlclNlcnZpY2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGFQcm92aWRlciA9IHRoaXMuZGF0YVByb3ZpZGVyKCk7XG4gICAgICAgIHJldHVybiBkYXRhUHJvdmlkZXI/LnNlcnZpY2VUeXBlID8gdGhpcy5pbmplY3Rvci5nZXQ8YW55PihkYXRhUHJvdmlkZXIuc2VydmljZVR5cGUpIDogbnVsbDtcbiAgICB9KTtcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnQ/OiBUYWJsZUxhenlMb2FkRXZlbnQ7XG4gICAgcHJpdmF0ZSBsYXRlc3RMYXp5TG9hZEV2ZW50VmVyc2lvbiA9IDA7XG4gICAgcHJpdmF0ZSBsYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHM/OiBEYXRhTGlzdFBhcmFtcztcbiAgICBwcml2YXRlIGxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0c1ZlcnNpb24gPSAwO1xuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gICAgLy8gZGVzY3JpcHRvcnNcbiAgICBwdWJsaWMgZGVzY3JpcHRvciA9IHNpZ25hbDxUYWJsZURlc2NyaXB0b3JJbnN0PGFueSwgYW55LCBhbnk+Pih0YWJsZURlc2NyaXB0b3I8c3RyaW5nLCBzdHJpbmcsIHN0cmluZz4oKSk7XG4gICAgcHJpdmF0ZSBsb2NhbHN0b3JhZ2VLZXkgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3IoKTtcbiAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3IubW9kZWwudHlwZU5hbWUgfHwgZGVzY3JpcHRvci5tb2RlbC5pMThuQmFzZUtleVxuICAgICAgICAgICAgPyBnZW5lcmF0ZVRhYmxlTGF5b3V0UHJlZnNLZXkoZGVzY3JpcHRvci5tb2RlbC50eXBlTmFtZSA/PyBkZXNjcmlwdG9yLm1vZGVsLmkxOG5CYXNlS2V5LCB0aGlzLnJvdXRlci51cmwsIGRlc2NyaXB0b3IuaWRlbnRpZmllcilcbiAgICAgICAgICAgIDogbnVsbDtcbiAgICB9KTtcbiAgICBwcml2YXRlIGxheW91dFByZWZzU2F2ZUNudCA9IHNpZ25hbCgwKTtcbiAgICBwcml2YXRlIGxheW91dFByZWZlcmVuY2VzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBsc0tleSA9IHRoaXMubG9jYWxzdG9yYWdlS2V5KCk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgICAgY29uc3QgY250ID0gdGhpcy5sYXlvdXRQcmVmc1NhdmVDbnQoKTsgLy8gbmVlZGVkIHRvIGZvcmNlIHVwZGF0ZXMgb24gdXNlciBjaGFuZ2VzXG4gICAgICAgIGNvbnN0IGxheW91dFByZWZzID0gbHNLZXkgPyB0aGlzLmxvY2FsU3RvcmFnZVNlcnZpY2UuZ2V0SXRlbTxUYWJsZUxheW91dFByZWZlcmVuY2VzPih0aGlzLmNtcFR5cGVOYW1lLCBsc0tleSkgOiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiBsYXlvdXRQcmVmcyA/PyB7Y29sdW1uV2lkdGhzOiB7fX07XG4gICAgfSk7XG4gICAgcHVibGljIGNvbHVtbnMgPSBjb21wdXRlZDxDb2x1bW5XaXRoUHJlZmVyZW5jZXNbXT4oKCkgPT4gdGhpcy5jb21wdXRDb2x1bW5zV2l0aExheW91dCgpKTtcbiAgICBwdWJsaWMgdmlzaWJsZUNvbHVtbnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbHVtbnMoKS5maWx0ZXIoY29sID0+IGNvbC5pc1Zpc2libGUpKTtcblxuICAgIC8vIGZpbHRlciwgc29ydFxuICAgIHB1YmxpYyBoYXNDb2x1bW5GaWx0ZXJzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5maWx0ZXJEZXNjcmlwdG9ycygpLmxlbmd0aCA+IDApO1xuICAgIHByaXZhdGUgZmlsdGVyRGVzY3JpcHRvcnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmRlc2NyaXB0b3IoKS5maWx0ZXJzKTtcbiAgICBwcml2YXRlIGRlZmF1bHRQYXJhbXMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbXB1dGVEZWZhdWx0RGF0YUxpc3RQYXJhbXMoKSk7XG4gICAgcHJpdmF0ZSBpc0ZpbHRlckNoYW5nZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIGlzU29ydENoYW5nZWQgPSBmYWxzZTtcblxuICAgIHB1YmxpYyBhbnlDb2x1bW5WaXNpYmxlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy52aXNpYmxlQ29sdW1ucygpLmxlbmd0aCA+IDApO1xuICAgIHB1YmxpYyBoYXNDdXN0b21MYXN0Q29sdW1uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50IHx8IHRoaXMuY29sdW1uQ3VzdG9tTGFzdFRlbXBsYXRlKCkpO1xuICAgIHB1YmxpYyBoYXNMYXN0Q29sdW1uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5oYXNDdXN0b21MYXN0Q29sdW1uKCkgfHwgdGhpcy5hcmVDb2x1bW5zVG9nZ2xlYWJsZSgpIHx8IHRoaXMuYXJlQ29sdW1uc1Jlb3JkZXJhYmxlKCkpO1xuXG4gICAgLy8gbGF5b3V0IHByZWZzXG4gICAgcHVibGljIGFyZUNvbHVtbnNSZW9yZGVyYWJsZSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVzY3JpcHRvcigpLmNvbHVtbnMuc29tZSh2YWx1ZSA9PiB2YWx1ZS5pc1Jlb3JkZXJhYmxlKSk7XG4gICAgcHVibGljIGFyZUNvbHVtbnNUb2dnbGVhYmxlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kZXNjcmlwdG9yKCkuY29sdW1ucy5zb21lKHZhbHVlID0+IHZhbHVlLmlzVG9nZ2xlYWJsZSkpO1xuXG4gICAgLy8gb3RoZXJcbiAgICBwcml2YXRlIHJvdXRlcklzTmF2aWdhdGlvbk91dHNpZGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3IoKTtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkZXNjcmlwdG9yLnJvd3NQZXJQYWdlT3B0aW9ucykgJiYgZGVzY3JpcHRvci5yb3dzUGVyUGFnZU9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMuc2V0KGRlc2NyaXB0b3Iucm93c1BlclBhZ2VPcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3IuZGVmYXVsdE51bVJvd3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cy5zZXQoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMoKS5pbmNsdWRlcyhkZXNjcmlwdG9yLmRlZmF1bHROdW1Sb3dzKSA/IGRlc2NyaXB0b3IuZGVmYXVsdE51bVJvd3MgOiB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMoKVswXVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvYWRpbmcgPSB0aGlzLmxvYWRpbmdJbnB1dCgpO1xuICAgICAgICAgICAgICAgIGlmIChsb2FkaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQobG9hZGluZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBlZmZlY3QoXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5yZXN1bHQoKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZGF0YS5zZXQocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5jb3VudC5zZXQocmVzdWx0LnRvdGFsQ291bnQgPz8gcmVzdWx0LmRhdGEubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9hZGluZyA9IHRoaXMubG9hZGluZ0lucHV0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkaW5nID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSBzZXQgaWYgaW5wdXQgaXMgbm90IGRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucmVzdWx0KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zKCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSB1bmRlZmluZWQgJiYgaXRlbXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5kYXRhLnNldChpdGVtcyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmNvdW50LnNldChpdGVtcy5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2FkaW5nID0gdGhpcy5sb2FkaW5nSW5wdXQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWRpbmcgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IHNldCBpZiBpbnB1dCBpcyBub3QgZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBlZmZlY3QoXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZ2xvYmFsRmlsdGVyRmllbGRzLnNldCh0aGlzLmdsb2JhbEZpbHRlckZpZWxkc0lucHV0KCkgPz8gdGhpcy5jb2x1bW5zKCkubWFwKGMgPT4gYy5kZXNjcmlwdG9yLnByb3BlcnR5KSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge2FsbG93U2lnbmFsV3JpdGVzOiB0cnVlfVxuICAgICAgICApO1xuXG4gICAgICAgIGFmdGVyTmV4dFJlbmRlcigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmlzQ2VsbENsaWNrT2JzZXJ2ZWQuc2V0KHRoaXMuY2VsbENsaWNrU3ViamVjdC5vYnNlcnZlZCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRvT2JzZXJ2YWJsZSh0aGlzLmRhdGFQcm92aWRlcilcbiAgICAgICAgICAgIC5waXBlKHN3aXRjaE1hcChkcCA9PiBkcD8uZ2V0QWxsUmVsb2FkJCA/PyBvZih7fSkpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgbmV4dDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbWJpbmVMYXRlc3QoW3RvT2JzZXJ2YWJsZSh0aGlzLmRlc2NyaXB0b3JJbnB1dCksIHRvT2JzZXJ2YWJsZSh0aGlzLmRhdGFQcm92aWRlciksIHRvT2JzZXJ2YWJsZSh0aGlzLnVzZVF1ZXJ5UGFyYW1zKV0pXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAvLyBkYXRhUHJvdmlkZXIgaXMgbmVlZGVkIHRvIGVuc3VyZSBjb3JyZWN0IG9yZGVyIG9mIGV4ZWN1dGlvbiBhbmQgcmVsb2FkXG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoW2Rlc2NyaXB0b3JJbnB1dCwgZGF0YVByb3ZpZGVyLCB1c2VRdWVyeVBhcmFtc10pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3JJbnB1dCAhPT0gdGhpcy5kZXNjcmlwdG9yKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRvci5zZXQoZGVzY3JpcHRvcklucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodXNlUXVlcnlQYXJhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyaWdnZXIgdGFibGUgbG9hZHMgZnJvbSByb3V0ZSB1cGRhdGVzXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yb3V0ZS5xdWVyeVBhcmFtcztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHFwID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocXAgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gbG9hZCBkYXRhIGltbWVkaWF0ZWx5IGJ5IGNyZWF0aW5nIGRlZmF1bHQgc29ydHMgYW5kIGZpbHRlcnMgKHByaW1lbmcgd2lsbCB0cmlnZ2VyIG9uTGF6eUxvYWQgZXZlbnQgb24gc29ydCZmaWx0ZXIgbWV0YWRhdGEgY2hhbmdlKVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0U29ydCA9IHRoaXMuY3JlYXRlU29ydE1ldGEodGhpcy5kZWZhdWx0UGFyYW1zKCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlZmF1bHRTb3J0IHx8IGRlZmF1bHRTb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNvcnRNZXRhLnNldChkZWZhdWx0U29ydCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0RmlsdGVyID0gdGhpcy5jcmVhdGVGaWx0ZXJNZXRhKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkZWZhdWx0RmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhLnNldChkZWZhdWx0RmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIoe30pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZFRhYmxlRnJvbVJvdXRlVXBkYXRlKHFwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB0b09ic2VydmFibGUodGhpcy51c2VRdWVyeVBhcmFtcylcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCh1c2VRcCA9PiAodXNlUXAgPyB0aGlzLnJvdXRlci5ldmVudHMgOiBORVZFUikpLFxuICAgICAgICAgICAgICAgIGZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgZSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgKGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uU3RhcnQgJiYgZS51cmwuc3BsaXQoJz8nKVswXS5zcGxpdCgnIycpWzBdICE9PSB0aGlzLnJvdXRlci51cmwuc3BsaXQoJz8nKVswXS5zcGxpdCgnIycpWzBdKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uQ2FuY2VsIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVycm9yXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZShlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlcklzTmF2aWdhdGlvbk91dHNpZGVJblByb2dyZXNzID0gZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25TdGFydDtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbG9hZChlbWl0RXZlbnQgPSBmYWxzZSwgcmVzZXRQYXJhbXMgPSBmYWxzZSkge1xuICAgICAgICBjb25zdCBwYXJhbXNXaXRoRGVmYXVsdHM6IERhdGFMaXN0UGFyYW1zID1cbiAgICAgICAgICAgIHJlc2V0UGFyYW1zIHx8ICF0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cyA/IHRoaXMuZGVmYXVsdFBhcmFtcygpIDogbWVyZ2VEYXRhTGlzdFBhcmFtc1dpdGhEZWZhdWx0cyh0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cywgdGhpcy5kZWZhdWx0UGFyYW1zKCkpO1xuICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIocGFyYW1zV2l0aERlZmF1bHRzLCBlbWl0RXZlbnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblRhYmxlTGF6eUxvYWQoZXZlbnQ6IFRhYmxlTGF6eUxvYWRFdmVudCkge1xuICAgICAgICB0aGlzLmRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnQgPSBldmVudDtcbiAgICAgICAgdGhpcy5sYXRlc3RMYXp5TG9hZEV2ZW50VmVyc2lvbisrO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IGZyb21UYWJsZUxvYWRUb0RhdGFMaXN0UGFyYW1zKGV2ZW50KTtcblxuICAgICAgICBpZiAodGhpcy51c2VRdWVyeVBhcmFtcygpKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucm91dGVySXNOYXZpZ2F0aW9uT3V0c2lkZUluUHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGNoZWNrIGlzIG5lY2Vzc2FyeTogZnJvbSBzb21lIHJlYXNvbiwgcHJpbWVORyBjb21taXRzIG9uZSBsYXN0IGxhenkgbG9hZCBldmVudCB3aGVuZXZlciBhbnkgYW5ndWxhciByb3V0ZXIgbmF2aWdhdGlvbiBvY2N1cnNcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXSwge1xuICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlLFxuICAgICAgICAgICAgICAgICAgICByZXBsYWNlVXJsOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeVBhcmFtczogZGF0YUxpc3RQYXJhbXNUb1VybFF1ZXJ5KHBhcmFtcywgdGhpcy5kZWZhdWx0UGFyYW1zKCkpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIobWVyZ2VEYXRhTGlzdFBhcmFtc1dpdGhEZWZhdWx0cyhwYXJhbXMsIHRoaXMuZGVmYXVsdFBhcmFtcygpKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgcHVibGljIG9uVGFibGVTb3J0KGV2ZW50OiBhbnkpIHtcbiAgICAgICAgdGhpcy5pc1NvcnRDaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgcHVibGljIG9uVGFibGVGaWx0ZXIoZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLmlzRmlsdGVyQ2hhbmdlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ2VsbENsaWNrKGV2ZW50OiBFdmVudCwgY29sOiBDb2x1bW5EZXNjcmlwdG9yPGFueSwgSXRlbT4sIGl0ZW06IEl0ZW0sIGlkeDogbnVtYmVyKSB7XG4gICAgICAgIGlmICghdGhpcy5pc0NlbGxDbGlja0VuYWJsZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRhYmxlRXZlbnQ6IFRhYmxlQ2VsbENsaWNrRXZlbnQ8SXRlbT4gPSB7XG4gICAgICAgICAgICBjb2x1bW46IGNvbCxcbiAgICAgICAgICAgIHJvd0l0ZW06IGl0ZW0sXG4gICAgICAgICAgICByb3dJbmRleDogaWR4LFxuICAgICAgICAgICAgZXZlbnQ6IGV2ZW50XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY2VsbENsaWNrU3ViamVjdC5uZXh0KHRhYmxlRXZlbnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblNlbGVjdGlvbkNoYW5nZShldmVudDogQXJyYXk8SXRlbT4pIHtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdChldmVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIGlzIGNhbGxlZCBvbiBjb2x1bW4gcmVzaXplXG4gICAgICogQHBhcmFtIGVsZW1lbnQgZXZlbnQncyBlbGVtZW50XG4gICAgICovXG4gICAgcHVibGljIG9uVGFibGVDb2x1bW5SZXNpemUoe2VsZW1lbnR9OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZmllbGRJZDogc3RyaW5nID0gZWxlbWVudC5pZDtcbiAgICAgICAgY29uc3Qgd2lkdGg6IG51bWJlciA9IGVsZW1lbnQub2Zmc2V0V2lkdGg7XG5cbiAgICAgICAgY29uc3QgbGF5b3V0UHJlZnMgPSB0aGlzLmxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgICAgIGNvbnN0IGNvbCA9IHRoaXMuY29sdW1ucygpLmZpbmQoZWwgPT4gZWwuZGVzY3JpcHRvci5wcm9wZXJ0eSA9PT0gZmllbGRJZCk7XG4gICAgICAgIGlmIChjb2wpIGNvbC53aWR0aCA9IHdpZHRoO1xuICAgICAgICBpZiAoIWxheW91dFByZWZzLmNvbHVtbldpZHRocykgbGF5b3V0UHJlZnMuY29sdW1uV2lkdGhzID0ge307XG5cbiAgICAgICAgbGF5b3V0UHJlZnMuY29sdW1uV2lkdGhzW2ZpZWxkSWRdID0gd2lkdGg7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKGxheW91dFByZWZzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIocGFyYW1zV2l0aERlZmF1bHRzOiBEYXRhTGlzdFBhcmFtcywgZW1pdEV2ZW50ID0gdHJ1ZSkge1xuICAgICAgICBjb25zdCBkYXRhUHJvdmlkZXIgPSB0aGlzLmRhdGFQcm92aWRlcigpO1xuICAgICAgICBpZiAoIWRhdGFQcm92aWRlciB8fCBwYXJhbXNXaXRoRGVmYXVsdHMubGltaXQgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5sb2FkaW5nLnNldCh0cnVlKTtcblxuICAgICAgICB0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cyA9IHBhcmFtc1dpdGhEZWZhdWx0cztcbiAgICAgICAgdGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHNWZXJzaW9uKys7XG5cbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24gPSBjb21tb25zVG9PYnNlcnZhYmxlKFxuICAgICAgICAgICAgZGF0YVByb3ZpZGVyLmdldEFsbChcbiAgICAgICAgICAgICAgICBwYXJhbXNXaXRoRGVmYXVsdHMgYXMgRGF0YUxpc3RQYXJhbXM8U29ydHMsIEZpbHRlcnM+LFxuICAgICAgICAgICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU2VydmljZSgpLFxuICAgICAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRvcigpLmlzTG9jYWxpemVkID8gdGhpcy5jb21tb25zLmFwcERhdGFMb2NhbGUoKSA/PyB1bmRlZmluZWQgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIClcbiAgICAgICAgKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgbmV4dDogcmVzID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkZXNjcmlwdG9ySW5wdXQgPSB0aGlzLmRlc2NyaXB0b3JJbnB1dCgpO1xuICAgICAgICAgICAgICAgIGlmIChkZXNjcmlwdG9ySW5wdXQgaW5zdGFuY2VvZiBUYWJsZUR5bmFtaWNEZXNjcmlwdG9ySW5zdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc2NyaXB0b3Iuc2V0KGRlc2NyaXB0b3JJbnB1dC50b1RhYmxlRGVzY3JpcHRvckZyb21EYXRhKHJlcykpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmluZmluaXRlU2Nyb2xsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5kYXRhTGlzdFNlcnZpY2UuZGF0YSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0ZpbHRlckNoYW5nZWQgfHwgdGhpcy5pc1NvcnRDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zLnNwbGljZShwYXJhbXNXaXRoRGVmYXVsdHMhLm9mZnNldCA/PyAwLCBwYXJhbXNXaXRoRGVmYXVsdHMhLmxpbWl0ID8/IHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnJvd3MoKSwgLi4uKHJlcz8uZGF0YSA/PyBbXSkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5kYXRhLnNldChpdGVtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZGF0YS5zZXQocmVzPy5kYXRhID8/IFtdKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5jb3VudC5zZXQocmVzPy50b3RhbENvdW50ID8/IDApOyAvLyBjb3VudCBpcyBub3QgcmVhbGx5IGltcG9ydGFudCBoZXJlXG5cbiAgICAgICAgICAgICAgICB0aGlzLmlzRmlsdGVyQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuaXNTb3J0Q2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICAgICAgICB0YWJsZU5vdGlmaWNhdGlvbkVycm9yKHRoaXMudHJhbnNsYXRlLCB0aGlzLmRlc2NyaXB0b3IoKSwgZXJyLCB0aGlzLm1lc3NhZ2VTZXJ2aWNlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5kYXRhLnNldChbXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuY291bnQuc2V0KDApO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gZnJvbVN1YnNjcmliZUVycm9yKGVyciwgJ1RhYmxlQ29tcG9uZW50RXJyb3InLCB7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5UGFyYW06IHBhcmFtc1dpdGhEZWZhdWx0c1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhlcnJvciwgZ2V0RXJyb3JMb2dMZXZlbChlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoZW1pdEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCB0YWJsZUV2ZW50OiBUYWJsZUxvYWRFdmVudCA9IHtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbEV2ZW50OiB0aGlzLmRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnQsXG4gICAgICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXNXaXRoRGVmYXVsdHNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnRhYmxlTG9hZC5lbWl0KHRhYmxlRXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkVGFibGVGcm9tUm91dGVVcGRhdGUodXJsUGFyYW1zOiBQYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zV2l0aERlZmF1bHRzID0gbWVyZ2VEYXRhTGlzdFBhcmFtc1dpdGhEZWZhdWx0cyhmcm9tVXJsUXVlcnlUb0RhdGFMaXN0UGFyYW1zKHVybFBhcmFtcyksIHRoaXMuZGVmYXVsdFBhcmFtcygpKTtcbiAgICAgICAgaWYgKHRoaXMubGF0ZXN0TGF6eUxvYWRFdmVudFZlcnNpb24gPCB0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0c1ZlcnNpb24gKyAxKSB7XG4gICAgICAgICAgICAvLyB1cGRhdGUgb25seSBpZiBuZXcgdmVyc2lvbiBmcm9tIHF1ZXJ5IHBhcmFtcyB3aWxsIGJlIGhpZ2hlclxuICAgICAgICAgICAgdGhpcy51cGRhdGVQcmltZVNvcnRBbmRGaWx0ZXIocGFyYW1zV2l0aERlZmF1bHRzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQuc2V0KHRydWUpO1xuICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIocGFyYW1zV2l0aERlZmF1bHRzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVByaW1lU29ydEFuZEZpbHRlcihwYXJhbXNXaXRoRGVmYXVsdHM6IERhdGFMaXN0UGFyYW1zKSB7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNvcnRNZXRhLnNldCh0aGlzLmNyZWF0ZVNvcnRNZXRhKHBhcmFtc1dpdGhEZWZhdWx0cykpO1xuICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhLnNldCh0aGlzLmNyZWF0ZUZpbHRlck1ldGEocGFyYW1zV2l0aERlZmF1bHRzKSk7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnJvd3Muc2V0KHBhcmFtc1dpdGhEZWZhdWx0cz8ubGltaXQgPz8gdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cygpKTtcbiAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uub2Zmc2V0LnNldChwYXJhbXNXaXRoRGVmYXVsdHM/Lm9mZnNldCA/PyAwKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZUZpbHRlck1ldGEocGFyYW1zV2l0aERlZmF1bHRzPzogRGF0YUxpc3RQYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcHJpbWVGaWx0ZXJNZXRhOiB7W3M6IHN0cmluZ106IEZpbHRlck1ldGFkYXRhfSA9IHt9O1xuICAgICAgICAvLyBpZiBhbnkgZmlsdGVyIGlzIHByZXNlbnQsIG5vIGRlZmF1bHQgZmlsdGVycyBzaG91bGQgYmUgYXBwbGllZCFcbiAgICAgICAgaWYgKHBhcmFtc1dpdGhEZWZhdWx0cz8uZmlsdGVycykge1xuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXMocGFyYW1zV2l0aERlZmF1bHRzLmZpbHRlcnMpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgICAgIHByaW1lRmlsdGVyTWV0YVtrZXldID0ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZTogdmFsdWUubWF0Y2hNb2RlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHByaW1lRmlsdGVyTWV0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVNvcnRNZXRhKHBhcmFtc1dpdGhEZWZhdWx0cz86IERhdGFMaXN0UGFyYW1zKTogU29ydE1ldGFbXSB8IG51bGwge1xuICAgICAgICBpZiAocGFyYW1zV2l0aERlZmF1bHRzPy5zb3J0ICE9PSB1bmRlZmluZWQgJiYgQXJyYXkuaXNBcnJheShwYXJhbXNXaXRoRGVmYXVsdHM/LnNvcnQpICYmIHBhcmFtc1dpdGhEZWZhdWx0cz8uc29ydC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyYW1zV2l0aERlZmF1bHRzPy5zb3J0Lm1hcChcbiAgICAgICAgICAgICAgICBzID0+XG4gICAgICAgICAgICAgICAgICAgIDxTb3J0TWV0YT57XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWVsZDogcy5wcm9wZXJ0eSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyOiBzLmFzY2VuZGluZyA/IDEgOiAtMVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uVG9nZ2xlKGV2ZW50OiBNdWx0aVNlbGVjdENoYW5nZUV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGxheW91dFByZWZzID0gdGhpcy5sYXlvdXRQcmVmZXJlbmNlcygpO1xuICAgICAgICBjb25zdCBzZWxlY3RlZENvbHVtbnMgPSAoZXZlbnQudmFsdWUgYXMgQ29sdW1uV2l0aFByZWZlcmVuY2VzW10pLm1hcCh2ID0+IHYuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgIGNvbnN0IGhpZGRlbkNvbHVtbnMgPSB0aGlzLmNvbHVtbnMoKVxuICAgICAgICAgICAgLmZpbHRlcihjID0+IHNlbGVjdGVkQ29sdW1ucy5pbmRleE9mKGMuZGVzY3JpcHRvci5wcm9wZXJ0eSkgPCAwKVxuICAgICAgICAgICAgLm1hcChjID0+IGMuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgIGxheW91dFByZWZzLmNvbHVtbkhpZGRlbiA9IGhpZGRlbkNvbHVtbnM7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKGxheW91dFByZWZzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Db2x1bW5Ub2dnbGVBbGwoKSB7XG4gICAgICAgIGNvbnN0IGxheW91dFByZWZzID0gdGhpcy5sYXlvdXRQcmVmZXJlbmNlcygpO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gWy4uLnRoaXMuY29sdW1ucygpXTtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gIXRoaXMuY29sdW1ucygpLnNvbWUoYyA9PiBjLmlzVmlzaWJsZSk7XG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIGNvbHVtbnMpIHtcbiAgICAgICAgICAgIGlmIChpc1Zpc2libGUgIT09IGNvbC5pc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgICBjb2wuaXNWaXNpYmxlID0gaXNWaXNpYmxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxheW91dFByZWZzLmNvbHVtbkhpZGRlbiA9IGNvbHVtbnMuZmlsdGVyKGMgPT4gIWMuaXNWaXNpYmxlKS5tYXAoYyA9PiBjLmRlc2NyaXB0b3IucHJvcGVydHkpO1xuICAgICAgICB0aGlzLnNhdmVMYXlvdXRQcmVmZXJlbmNlcyhsYXlvdXRQcmVmcyk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uUmVvcmRlcihldmVudDogVGFibGVDb2x1bW5SZW9yZGVyRXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmRyb3BJbmRleCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmRyb3BJbmRleCA+PSAwICYmIGV2ZW50LmRyYWdJbmRleCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmRyYWdJbmRleCA+PSAwICYmIGV2ZW50LmRyb3BJbmRleCAhPT0gZXZlbnQuZHJhZ0luZGV4KSB7XG4gICAgICAgICAgICBjb25zdCBldmVudERyb3BJbmRleCA9IGV2ZW50LmRyb3BJbmRleDtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RHJhZ0luZGV4ID0gZXZlbnQuZHJhZ0luZGV4O1xuICAgICAgICAgICAgY29uc3QgcHJldlZpc2libGVDb2x1bW5zID0gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKGMgPT4gYy5pc1Zpc2libGUpO1xuICAgICAgICAgICAgY29uc3QgY29sQXREcm9wID0gcHJldlZpc2libGVDb2x1bW5zW2V2ZW50RHJvcEluZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGNvbEF0RHJhZyA9IHByZXZWaXNpYmxlQ29sdW1uc1tldmVudERyYWdJbmRleF07XG4gICAgICAgICAgICBjb25zdCBjb2xBdERyb3BJbmRleCA9IHRoaXMuY29sdW1ucygpLmZpbmRJbmRleChlbCA9PiBlbC5pZCA9PT0gY29sQXREcm9wLmlkKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbEF0RHJhZ0luZGV4ID0gdGhpcy5jb2x1bW5zKCkuZmluZEluZGV4KGVsID0+IGVsLmlkID09PSBjb2xBdERyYWcuaWQpO1xuXG4gICAgICAgICAgICBpZiAoY29sQXREcm9wSW5kZXggPiAtMSAmJiBjb2xBdERyYWdJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNvbHVtbnMgPSBbLi4udGhpcy5jb2x1bW5zKCldO1xuICAgICAgICAgICAgICAgIGNvbHVtbnMuc3BsaWNlKGNvbEF0RHJhZ0luZGV4LCAxKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkcm9wSW5kZXggPSBjb2x1bW5zLmZpbmRJbmRleChlbCA9PiBlbC5pZCA9PT0gY29sQXREcm9wLmlkKSArIChldmVudERyb3BJbmRleCA+IGV2ZW50RHJhZ0luZGV4ID8gMSA6IDApO1xuICAgICAgICAgICAgICAgIGNvbHVtbnMgPSBbLi4uY29sdW1ucy5zbGljZSgwLCBkcm9wSW5kZXgpLCBjb2xBdERyYWcsIC4uLmNvbHVtbnMuc2xpY2UoZHJvcEluZGV4KV07XG4gICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0UHJlZnMgPSB0aGlzLmxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgICAgICAgICAgICAgbGF5b3V0UHJlZnMuY29sdW1uT3JkZXIgPSBjb2x1bW5zLm1hcChlbCA9PiBlbC5kZXNjcmlwdG9yLnByb3BlcnR5KTtcbiAgICAgICAgICAgICAgICB0aGlzLnNhdmVMYXlvdXRQcmVmZXJlbmNlcyhsYXlvdXRQcmVmcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNhdmVMYXlvdXRQcmVmZXJlbmNlcyhsYXlvdXRQcmVmczogVGFibGVMYXlvdXRQcmVmZXJlbmNlcykge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmxvY2Fsc3RvcmFnZUtleSgpO1xuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICB0aGlzLmxvY2FsU3RvcmFnZVNlcnZpY2Uuc2V0SXRlbSh0aGlzLmNtcFR5cGVOYW1lLCBrZXksIGxheW91dFByZWZzKTtcbiAgICAgICAgICAgIHRoaXMubGF5b3V0UHJlZnNTYXZlQ250LnVwZGF0ZSh2ID0+IHYgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY29tcHV0ZURlZmF1bHREYXRhTGlzdFBhcmFtcygpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zOiBEYXRhTGlzdFBhcmFtcyA9IHtcbiAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgIGxpbWl0OiB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMoKVswXSxcbiAgICAgICAgICAgIHNvcnQ6IHRoaXMuZGVzY3JpcHRvcigpXG4gICAgICAgICAgICAgICAgLnNvcnRzLmZpbHRlcihzID0+IHMuZGVmYXVsdElzRW5hYmxlZClcbiAgICAgICAgICAgICAgICAubWFwKHMgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6IHMucHJvcGVydHksXG4gICAgICAgICAgICAgICAgICAgIGFzY2VuZGluZzogcy5kZWZhdWx0SXNBc2NlbmRpbmdcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICBmaWx0ZXJzOiB7fVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMoKVxuICAgICAgICAgICAgLmZpbHRlcihkID0+IGQuaGFzRGVmYXVsdFZhbHVlKVxuICAgICAgICAgICAgLmZvckVhY2goZiA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IG1hdGNoTW9kZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gZi5kZWZhdWx0TWF0Y2hNb2RlO1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2hNb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZi5maWx0ZXJUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLlN0cmluZzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuQ29udGFpbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLkxvb2t1cDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRmlsdGVyVHlwZUVudW0uTG9va3VwRW51bToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvb2t1cEZpbHRlciA9IGYgYXMgRmlsdGVyTG9va3VwRGVzY3JpcHRvcjxhbnksIEl0ZW0+O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb29rdXBGaWx0ZXIubXVsdGlzZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkluO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFtYXRjaE1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkVxdWFscztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZi5tYXRjaE1vZGVzICYmICFmLm1hdGNoTW9kZXM/LmluY2x1ZGVzKG1hdGNoTW9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gZi5tYXRjaE1vZGVzWzBdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZTogYW55IHwgYW55W10gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gWy4uLnZhbHVlXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGYuZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gZi5wcm9wZXJ0eTtcbiAgICAgICAgICAgICAgICBwYXJhbXMuZmlsdGVycyFbcHJvcGVydHldID0ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZTogbWF0Y2hNb2RlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBwYXJhbXM7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRDb2x1bW5zV2l0aExheW91dCgpIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHRoaXMuZGVzY3JpcHRvcigpO1xuICAgICAgICBjb25zdCBsYXlvdXRQcmVmcyA9IHRoaXMubGF5b3V0UHJlZmVyZW5jZXMoKTtcblxuICAgICAgICAvLyBpbml0aWFsaXplIGNvbHVtbnMgd2l0aCBhZGRpdGlvbmFsIHByb3BlcnRpZXNcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGNvbnN0IGNvbHVtbnM6IENvbHVtbldpdGhQcmVmZXJlbmNlc1tdID0gZGVzY3JpcHRvci5jb2x1bW5zLm1hcChjb2wgPT4gKHtcbiAgICAgICAgICAgIGlkOiBgJHtjb2wucHJvcGVydHl9LSR7dGltZXN0YW1wfWAsXG4gICAgICAgICAgICBkZXNjcmlwdG9yOiBjb2wsXG4gICAgICAgICAgICBmaWx0ZXI6IGRlc2NyaXB0b3IuZmlsdGVycy5maW5kKGYgPT4gZi5zaG93T25Db2x1bW4gPT09IGNvbC5wcm9wZXJ0eSksXG4gICAgICAgICAgICBzb3J0OiBkZXNjcmlwdG9yLnNvcnRzLmZpbmQoZiA9PiBmLnNob3dPbkNvbHVtbiA9PT0gY29sLnByb3BlcnR5KSxcbiAgICAgICAgICAgIGRpc2FibGVkOiAhY29sLmlzVG9nZ2xlYWJsZSxcbiAgICAgICAgICAgIGlzVmlzaWJsZTogbGF5b3V0UHJlZnMuY29sdW1uSGlkZGVuID8gIWxheW91dFByZWZzLmNvbHVtbkhpZGRlbi5pbmNsdWRlcyhjb2wucHJvcGVydHkpIDogY29sLmlzVmlzaWJsZSxcbiAgICAgICAgICAgIHdpZHRoOiBsYXlvdXRQcmVmcy5jb2x1bW5XaWR0aHM/Lltjb2wucHJvcGVydHldXG4gICAgICAgIH0pKTtcblxuICAgICAgICBpZiAobGF5b3V0UHJlZnMuY29sdW1uT3JkZXIpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGF5b3V0UHJlZnMuY29sdW1uT3JkZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xOYW1lID0gbGF5b3V0UHJlZnMuY29sdW1uT3JkZXJbaV07XG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2l0aFByZWZzID0gY29sdW1ucy5maW5kKGVsID0+IGVsLmRlc2NyaXB0b3IucHJvcGVydHkgPT09IGNvbE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChjb2xXaXRoUHJlZnMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sV2l0aFByZWZzLm9yZGVySWR4ID0gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29sdW1ucy5zb3J0KChhLCBiKSA9PiAoYS5vcmRlcklkeCAhPT0gdW5kZWZpbmVkICYmIGIub3JkZXJJZHggIT09IHVuZGVmaW5lZCA/IGEub3JkZXJJZHggLSBiLm9yZGVySWR4IDogMCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2V0IGNvbHVtbiBvcmRlciBhbmQgY29sdW1uIHZpc2liaWxpdHkgdG8gZGVmYXVsdCBzZXR0aW5nc1xuICAgICAqL1xuICAgIHB1YmxpYyByZXNldERlZmF1bHRMYXlvdXQoKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMubG9jYWxzdG9yYWdlS2V5KCk7XG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxTdG9yYWdlU2VydmljZS5yZW1vdmVJdGVtKHRoaXMuY21wVHlwZU5hbWUsIGtleSk7XG4gICAgICAgICAgICB0aGlzLmxheW91dFByZWZzU2F2ZUNudC51cGRhdGUodiA9PiB2ICsgMSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCI8ZGl2IFtzdHlsZS5oZWlnaHRdPVwidGFibGVGdWxsSGVpZ2h0T2Zmc2V0KCkgPyAnY2FsYygxMDB2aCAtICcgKyB0YWJsZUZ1bGxIZWlnaHRPZmZzZXQoKSArICdweCknIDogbnVsbFwiPlxuICAgIDwhLS0gTVVTVCBOT1QgdXNlIG9ic2VydmFibGUgZm9yIHZhbHVlIHdoZW4gdXNpbmcgdmlydHVhbCBzY3JvbGwgLSBkb2VzIG5vdCB3b3JrIGZvciBzb21lIHJlYXNvbiAtLT5cbiAgICBAaWYgKCF1c2VRdWVyeVBhcmFtcygpIHx8IHVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQoKSkge1xuICAgICAgICA8cC10YWJsZVxuICAgICAgICAgICAgW3ZhbHVlXT1cImRhdGFMaXN0U2VydmljZS5kYXRhKClcIlxuICAgICAgICAgICAgW2RhdGFLZXldPVwiZGVzY3JpcHRvcigpLnRyYWNrUHJvcGVydHlcIlxuICAgICAgICAgICAgW2xhenldPVwiaXNMYXp5KClcIlxuICAgICAgICAgICAgW2xvYWRpbmddPVwiZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcoKVwiXG4gICAgICAgICAgICBbcGFnaW5hdG9yXT1cImlzUGFnaW5hdGlvbigpICYmICFpbmZpbml0ZVNjcm9sbCgpXCJcbiAgICAgICAgICAgIFtyb3dzXT1cImluZmluaXRlU2Nyb2xsKCkgPyAyMCA6IGRhdGFMaXN0U2VydmljZS5yb3dzKClcIlxuICAgICAgICAgICAgW2ZpcnN0XT1cImluZmluaXRlU2Nyb2xsKCkgPyAwIDogZGF0YUxpc3RTZXJ2aWNlLm9mZnNldCgpXCJcbiAgICAgICAgICAgIFt0b3RhbFJlY29yZHNdPVwiZGF0YUxpc3RTZXJ2aWNlLmNvdW50KClcIlxuICAgICAgICAgICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJpbmZpbml0ZVNjcm9sbCgpID8gdW5kZWZpbmVkIDogZGF0YUxpc3RTZXJ2aWNlLnJvd3NQZXJQYWdlT3B0aW9ucygpXCJcbiAgICAgICAgICAgIFtzaG93Q3VycmVudFBhZ2VSZXBvcnRdPVwiIWluZmluaXRlU2Nyb2xsKClcIlxuICAgICAgICAgICAgW2N1cnJlbnRQYWdlUmVwb3J0VGVtcGxhdGVdPVwiJ21uZ1RhYmxlLnBhZ2luYXRpb25Nc2cnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIFttdWx0aVNvcnRNZXRhXT1cImRhdGFMaXN0U2VydmljZS5zb3J0TWV0YSgpXCJcbiAgICAgICAgICAgIFtmaWx0ZXJzXT1cImRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhKClcIlxuICAgICAgICAgICAgW2dsb2JhbEZpbHRlckZpZWxkc109XCJkYXRhTGlzdFNlcnZpY2UuZ2xvYmFsRmlsdGVyRmllbGRzKClcIlxuICAgICAgICAgICAgc29ydE1vZGU9XCJtdWx0aXBsZVwiXG4gICAgICAgICAgICBbc2VsZWN0aW9uXT1cIltdXCJcbiAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwib25TZWxlY3Rpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICBbc2VsZWN0aW9uTW9kZV09XCJzZWxlY3Rpb25FbmFibGVkKCkgPyBzZWxlY3Rpb25Nb2RlKCkgOiBudWxsXCJcbiAgICAgICAgICAgIFtzY3JvbGxhYmxlXT1cInRydWVcIlxuICAgICAgICAgICAgW3ZpcnR1YWxTY3JvbGxdPVwiaW5maW5pdGVTY3JvbGwoKVwiXG4gICAgICAgICAgICBbdmlydHVhbFNjcm9sbEl0ZW1TaXplXT1cInJvd0hlaWdodCgpXCJcbiAgICAgICAgICAgIHNjcm9sbEhlaWdodD1cImZsZXhcIlxuICAgICAgICAgICAgW3Jvd0hvdmVyXT1cImRlc2NyaXB0b3IoKS5oYXNIb3ZlclwiXG4gICAgICAgICAgICBbc3R5bGVDbGFzc109XCJjbGFzc05hbWUoKVwiXG4gICAgICAgICAgICBbcmVzaXphYmxlQ29sdW1uc109XCJkZXNjcmlwdG9yKCkuaGFzUmVzaXphYmxlQ29sdW1uc1wiXG4gICAgICAgICAgICBbY29sdW1uUmVzaXplTW9kZV09XCJkZXNjcmlwdG9yKCkuY29sdW1uUmVzaXplTW9kZSA/PyAnZXhwYW5kJ1wiXG4gICAgICAgICAgICBbcmVvcmRlcmFibGVDb2x1bW5zXT1cImFyZUNvbHVtbnNSZW9yZGVyYWJsZSgpXCJcbiAgICAgICAgICAgIHBhZ2luYXRvckRyb3Bkb3duQXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgIFtjb2x1bW5zXT1cInZpc2libGVDb2x1bW5zKClcIlxuICAgICAgICAgICAgKG9uQ29sUmVzaXplKT1cIm9uVGFibGVDb2x1bW5SZXNpemUoJGV2ZW50KVwiXG4gICAgICAgICAgICAob25Db2xSZW9yZGVyKT1cIm9uQ29sdW1uUmVvcmRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgIChvbkxhenlMb2FkKT1cIm9uVGFibGVMYXp5TG9hZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChvblNvcnQpPVwib25UYWJsZVNvcnQoJGV2ZW50KVwiXG4gICAgICAgICAgICAob25GaWx0ZXIpPVwib25UYWJsZUZpbHRlcigkZXZlbnQpXCI+XG4gICAgICAgICAgICBAaWYgKGNhcHRpb25UZW1wbGF0ZSgpIHx8IGNhcHRpb25Db21wb25lbnQoKSB8fCBkZXNjcmlwdG9yKCkudGl0bGUpIHtcbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiY2FwdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKGNhcHRpb25UZW1wbGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY2FwdGlvblRlbXBsYXRlKClcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY2FwdGlvbkNvbXBvbmVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFttbmdDb21wb25lbnRdPVwiY2FwdGlvbkNvbXBvbmVudCgpXCIgKGluc3RhbmNlQ3JlYXRlZCk9XCJjYXB0aW9uQ29tcG9uZW50SW5zdGFuY2UuZW1pdCgkZXZlbnQpXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGg1IGNsYXNzPVwicC0wIG0tMFwiPnt7IGRlc2NyaXB0b3IoKS50aXRsZSB9fTwvaDU+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImhlYWRlclwiPlxuICAgICAgICAgICAgICAgIEBpZiAoIWRlc2NyaXB0b3IoKS5oaWRlSGVhZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cIm1uZy10YWJsZS1oZWFkZXJcIiBbY2xhc3NdPVwiZGVzY3JpcHRvcigpLmhlYWRlckNsYXNzTmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25FbmFibGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHNlbGVjdGlvbk1vZGUoKSA9PT0gJ211bHRpcGxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC10YWJsZUhlYWRlckNoZWNrYm94PjwvcC10YWJsZUhlYWRlckNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFdlIG5lZWQgdGhlIGxpbmUgYmVsb3csIGJlY2F1c2Ugb3RoZXJ3aXNlIHAtdGFibGVSYWRpb0J1dHRvbiBzaGlmdHMgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMgaW4gdGFibGUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cIm1pbi13aWR0aDogMzZweFwiIHBGcm96ZW5Db2x1bW4gW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuc2VsZWN0aW9uQ29sdW1uRnJvemVuID8/IHRydWVcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjbGFzcz1cImNvbC0xXCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cInRydWVcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoY29sIG9mIHZpc2libGVDb2x1bW5zKCk7IHRyYWNrIGNvbC5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc29ydGFibGVDb2x1bW5USFRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbC5kZXNjcmlwdG9yLnRpdGxlID8/IChjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eSB8IG1uZ0kxOG5Qcm9wZXJ0eTogZGVzY3JpcHRvcigpLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtc29ydEljb24gW2ZpZWxkXT1cImNvbC5kZXNjcmlwdG9yLnByb3BlcnR5XCI+PC9wLXNvcnRJY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9uU29ydGFibGVDb2x1bW5USFRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb2wuZGVzY3JpcHRvci50aXRsZSA/PyAoY29sLmRlc2NyaXB0b3IucHJvcGVydHkgfCBtbmdJMThuUHJvcGVydHk6IGRlc2NyaXB0b3IoKS5tb2RlbCkgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sLmRlc2NyaXB0b3IuaXNSZW9yZGVyYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBSZXNpemFibGVDb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBSZW9yZGVyYWJsZUNvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lkXT1cImNvbC5kZXNjcmlwdG9yLnByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwU29ydGFibGVDb2x1bW5dPVwiY29sLnNvcnQ/LnByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwU29ydGFibGVDb2x1bW5EaXNhYmxlZF09XCIhY29sLnNvcnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCA/IGNvbC53aWR0aCArICdweCcgOiBjb2wuZGVzY3JpcHRvci53aWR0aCArICclJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbC53aWR0aCA/IG51bGwgOiBjb2wuZGVzY3JpcHRvci5taW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbC53aWR0aCA/PyBjb2wuZGVzY3JpcHRvci5tYXhXaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiY29sLmRlc2NyaXB0b3IuaGVhZGVyQ2xhc3NOYW1lIHwgbW5nVGFibGVDb2x1bW5GaWx0ZXJDbGFzczogY29sLmZpbHRlciA6IGhhc0NvbHVtbkZpbHRlcnMoKSAmJiAhY29sLndpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY29sLnNvcnQgPyBzb3J0YWJsZUNvbHVtblRIVGVtcGxhdGUgOiBub25Tb3J0YWJsZUNvbHVtblRIVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUmVzaXphYmxlQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiY29sLmRlc2NyaXB0b3IucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbl09XCJjb2wuc29ydD8ucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbkRpc2FibGVkXT1cIiFjb2wuc29ydFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoID8gY29sLndpZHRoICsgJ3B4JyA6IGNvbC5kZXNjcmlwdG9yLndpZHRoICsgJyUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5kZXNjcmlwdG9yLm1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJjb2wuZGVzY3JpcHRvci5oZWFkZXJDbGFzc05hbWUgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2wuc29ydCA/IHNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZSA6IG5vblNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaGFzTGFzdENvbHVtbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uTGFzdE1pbldpZHRoKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLmFjdGlvbkNvbHVtbkZyb3plbiA/PyBhcmVDb2x1bW5zVG9nZ2xlYWJsZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ25Gcm96ZW49XCJyaWdodFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sdW1uLWN1c3RvbS1sYXN0IHRleHQtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChkZXNjcmlwdG9yKCkuaGFzUmVzaXphYmxlQ29sdW1ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjY29sdW1uVG9nZ2xlTXVsdGlzZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUNsYXNzPVwicC1idXR0b24tcHJpbWFyeSBtbmctdGFibGUtY29sdW1ucy1tdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhS2V5PVwiaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImxlZnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcm9wZG93bkljb249XCJwaSBwaS1zbGlkZXJzLWhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWx0ZXJdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cImNvbHVtbnMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmlzaWJsZUNvbHVtbnMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BUb29sdGlwXT1cIidtbmdUYWJsZS5hZGp1c3RUYWJsZScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5U2VsZWN0ZWRMYWJlbF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uQ29sdW1uVG9nZ2xlKCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZmlsdGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNoZWNrYm94IHAtY29tcG9uZW50IG1sLTFcIiBbbmdDbGFzc109XCJ7J3AtY2hlY2tib3gtZGlzYWJsZWQnOiAhYXJlQ29sdW1uc1RvZ2dsZWFibGV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1oaWRkZW4tYWNjZXNzaWJsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkb25seT1cInJlYWRvbmx5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiY29sdW1uVG9nZ2xlTXVsdGlzZWxlY3QuYWxsU2VsZWN0ZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwiY29sdW1uVG9nZ2xlTXVsdGlzZWxlY3Qub25IZWFkZXJDaGVja2JveEZvY3VzKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYmx1cik9XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5vbkhlYWRlckNoZWNrYm94Qmx1cigpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uc3BhY2UpPVwiY29sdW1uVG9nZ2xlTXVsdGlzZWxlY3Qub25Ub2dnbGVBbGwoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhYXJlQ29sdW1uc1RvZ2dsZWFibGVcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLWNoZWNrYm94LWJveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9sZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWNoZWNrZWRdPVwiY29sdW1uVG9nZ2xlTXVsdGlzZWxlY3QuYWxsU2VsZWN0ZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3AtaGlnaGxpZ2h0JzogYW55Q29sdW1uVmlzaWJsZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ29sdW1uVG9nZ2xlQWxsKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInAtY2hlY2tib3gtaWNvblwiIFtuZ0NsYXNzXT1cInsncGkgcGktY2hlY2snOiBhbnlDb2x1bW5WaXNpYmxlKCl9XCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1idXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1yZXBsYXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVDbGFzcz1cInAtYnV0dG9uLXNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwiJ21uZ1RhYmxlLnJlc2V0TGF5b3V0JyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJsZWZ0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXNldERlZmF1bHRMYXlvdXQoKVwiPjwvcC1idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbGV0LWl0ZW0gcFRlbXBsYXRlPVwiaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLmRlc2NyaXB0b3IudGl0bGUgPz8gKGl0ZW0uZGVzY3JpcHRvci5wcm9wZXJ0eSB8IG1uZ0kxOG5Qcm9wZXJ0eTogZGVzY3JpcHRvcigpLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBAaWYgKGhhc0NvbHVtbkZpbHRlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICA8dHIgY2xhc3M9XCJtbmctY29sdW1uLWZpbHRlci1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gV2UgbmVlZCB0aGUgbGluZSBiZWxvdywgYmVjYXVzZSBvdGhlcndpc2UgcC10YWJsZVJhZGlvQnV0dG9uIHNoaWZ0cyB0aGUgcmVzdCBvZiB0aGUgY29sdW1ucyBpbiB0YWJsZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5zZWxlY3Rpb25Db2x1bW5Gcm96ZW4gPz8gdHJ1ZVwiPjwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJjb2wuZmlsdGVyPy5jb2x1bW5DbGFzc05hbWUgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLiVdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5maWx0ZXI/LmNvbHVtbldpZHRoID8/IGNvbC5kZXNjcmlwdG9yLndpZHRoID8/IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbC53aWR0aCA/IG51bGwgOiBjb2wuZmlsdGVyPy5jb2x1bW5NaW5XaWR0aCA/PyBjb2wuZGVzY3JpcHRvci5taW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sLmZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1uZy10YWJsZS1jb2x1bW4tZmlsdGVyLWZ1bGwgW2Rlc2NyaXB0b3JdPVwiY29sLmZpbHRlclwiPjwvbW5nLXRhYmxlLWNvbHVtbi1maWx0ZXItZnVsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGhhc0xhc3RDb2x1bW4oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbHVtbi1jdXN0b20tbGFzdFwiIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uTGFzdE1pbldpZHRoKClcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiYm9keVwiIGxldC1pdGVtIGxldC1pZHg9XCJyb3dJbmRleFwiIGxldC1leHBhbmRlZD1cImV4cGFuZGVkXCI+XG4gICAgICAgICAgICAgICAgPHRyXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwicm93SGVpZ2h0KClcIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJkZXNjcmlwdG9yKCkucm93Q2xhc3NOYW1lIHwgbW5nQ2xhc3NNYXA6IGRlc2NyaXB0b3IoKS5yb3dDbGFzc05hbWVNYXBGbiA6IGl0ZW0gfCBtbmdMb2NhbGVEZWZhdWx0Um93Q2xhc3M6IGRlc2NyaXB0b3IoKSA6IGl0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25FbmFibGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uTW9kZSgpID09PSAnbXVsdGlwbGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5zZWxlY3Rpb25Db2x1bW5Gcm96ZW4gPz8gdHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC10YWJsZUNoZWNrYm94IFt2YWx1ZV09XCJpdGVtXCI+PC9wLXRhYmxlQ2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cIm1pbi13aWR0aDogMzZweFwiIHBGcm96ZW5Db2x1bW4gW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuc2VsZWN0aW9uQ29sdW1uRnJvemVuID8/IHRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFibGVSYWRpb0J1dHRvbiBbdmFsdWVdPVwiaXRlbVwiPjwvcC10YWJsZVJhZGlvQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKCFkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZVByb3BlcnR5IHx8IGl0ZW1bZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGVQcm9wZXJ0eSFdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BSb3dUb2dnbGVyXT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi10ZXh0IHAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tcGxhaW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ljb25dPVwiZXhwYW5kZWQgPyAncGkgcGktY2hldnJvbi1kb3duJyA6ICdwaSBwaS1jaGV2cm9uLXJpZ2h0J1wiPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGZvciAoY29sIG9mIHZpc2libGVDb2x1bW5zKCk7IHRyYWNrIGNvbC5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2VsbENsaWNrKCRldmVudCwgY29sLmRlc2NyaXB0b3IsIGl0ZW0sIGlkeClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmRlc2NyaXB0b3IuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG1uZ0NsYXNzTWFwOiBjb2wuZGVzY3JpcHRvci5jbGFzc05hbWVNYXBGbiA6IGl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgbW5nVGFibGVDb2x1bW5GaWx0ZXJDbGFzczogY29sLmZpbHRlciA6IGhhc0NvbHVtbkZpbHRlcnMoKSAmJiAhY29sLndpZHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY2xpY2thYmxlXT1cImlzQ2VsbENsaWNrRW5hYmxlZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoID8gY29sLndpZHRoICsgJ3B4JyA6IGNvbC5kZXNjcmlwdG9yLndpZHRoICsgJyUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbC53aWR0aCA/IG51bGwgOiBjb2wuZGVzY3JpcHRvci5taW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2wud2lkdGggPz8gY29sLmRlc2NyaXB0b3IubWF4V2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInAtY29sdW1uLXRpdGxlXCI+e3sgY29sLmRlc2NyaXB0b3IudGl0bGUgPz8gKGNvbC5kZXNjcmlwdG9yLnByb3BlcnR5IHwgbW5nSTE4blByb3BlcnR5OiBkZXNjcmlwdG9yKCkubW9kZWwpIHwgdHJhbnNsYXRlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtbmctdGFibGUtY29sdW1uLXZhbHVlIFtkZXNjcmlwdG9yXT1cImNvbC5kZXNjcmlwdG9yXCIgW2l0ZW1dPVwiaXRlbVwiPjwvbW5nLXRhYmxlLWNvbHVtbi12YWx1ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChoYXNMYXN0Q29sdW1uKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sdW1uLWN1c3RvbS1sYXN0IGp1c3RpZnktY29udGVudC1lbmQgdGV4dC1yaWdodFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2x1bW5MYXN0TWluV2lkdGgoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcEZyb3plbkNvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLmFjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlnbkZyb3plbj1cInJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChjb2x1bW5DdXN0b21MYXN0VGVtcGxhdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY29sdW1uQ3VzdG9tTGFzdFRlbXBsYXRlKCk7IGNvbnRleHQ6IHtyb3dJdGVtOiBpdGVtLCByb3dJbmRleDogaWR4fVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGNvbHVtbkN1c3RvbUxhc3RDb21wb25lbnQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFttbmdDb21wb25lbnRdPVwiY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudCgpXCIgKGluc3RhbmNlQ3JlYXRlZCk9XCJjb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50SW5zdGFuY2UuZW1pdCgkZXZlbnQpXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgQGlmIChkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZSkge1xuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJyb3dleHBhbnNpb25cIiBsZXQtaXRlbT5cbiAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLTFcIj48L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIFtjb2xTcGFuXT1cImRlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlQ29sU3BhblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJyb3dFeHBhbmRUZW1wbGF0ZSgpOyBjb250ZXh0OiB7cm93SXRlbTogaXRlbX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJsb2FkaW5naWNvblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sdW1uIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5sb2FkaW5nSWNvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGkgW2NsYXNzXT1cIid0ZXh0LXdoaXRlIHRleHQtNHhsIHBpLXNwaW4gJyArIGRlc2NyaXB0b3IoKS5sb2FkaW5nSWNvblwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5sb2FkaW5nVGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQgdGV4dC13aGl0ZSB0ZXh0LWxnIGZvbnQtc2VtaWJvbGRcIiBbbmdDbGFzc109XCJ7J210LTMnOiBkZXNjcmlwdG9yKCkubG9hZGluZ0ljb259XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZGVzY3JpcHRvcigpLmxvYWRpbmdUZXh0ID8/ICcnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJsb2FkaW5nYm9keVwiPlxuICAgICAgICAgICAgICAgIDx0ciBbc3R5bGUuaGVpZ2h0LnB4XT1cInJvd0hlaWdodCgpXCI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cInZpc2libGVDb2x1bW5zKCkubGVuZ3RoICsgKGhhc0xhc3RDb2x1bW4oKSA/IDEgOiAwKSArIChzZWxlY3Rpb25FbmFibGVkKCkgPyAxIDogMClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nLXRleHRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLXNrZWxldG9uIFtuZ1N0eWxlXT1cInt3aWR0aDogJzEwMCUnfVwiPjwvcC1za2VsZXRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJlbXB0eW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICA8dHIgW3N0eWxlLmhlaWdodC5weF09XCJyb3dIZWlnaHQoKVwiPlxuICAgICAgICAgICAgICAgICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJ2aXNpYmxlQ29sdW1ucygpLmxlbmd0aCArIChoYXNMYXN0Q29sdW1uKCkgPyAxIDogMCkgKyAoc2VsZWN0aW9uRW5hYmxlZCgpID8gMSA6IDApXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyAnbW5nVGFibGUubm9JdGVtcycgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIEBpZiAoZm9vdGVyVGVtcGxhdGUoKSkge1xuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJzdW1tYXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJmb290ZXJUZW1wbGF0ZSgpOyBjb250ZXh0OiB7ZGF0YTogZGF0YUxpc3RTZXJ2aWNlLmRhdGEoKSwgdG90YWxDb3VudDogZGF0YUxpc3RTZXJ2aWNlLmNvdW50KCl9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9wLXRhYmxlPlxuICAgIH1cbjwvZGl2PlxuIl19