@aquera/ngx-smart-table 0.0.17-alpha → 0.0.19-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{fesm2020 → fesm2022}/aquera-ngx-smart-table.mjs +1579 -2101
- package/fesm2022/aquera-ngx-smart-table.mjs.map +1 -0
- package/package.json +8 -16
- package/types/aquera-ngx-smart-table.d.ts +5909 -0
- package/aquera-ngx-smart-table.d.ts +0 -5
- package/esm2020/aquera-ngx-smart-table.mjs +0 -5
- package/esm2020/lib/builder/components/builder-preview/builder-preview.component.mjs +0 -63
- package/esm2020/lib/builder/components/builder-toolbar/builder-toolbar.component.mjs +0 -115
- package/esm2020/lib/builder/components/column-editor/column-editor.component.mjs +0 -206
- package/esm2020/lib/builder/components/column-list/column-list.component.mjs +0 -125
- package/esm2020/lib/builder/components/definition-builder/definition-builder.component.mjs +0 -105
- package/esm2020/lib/builder/components/table-config-editor/table-config-editor.component.mjs +0 -132
- package/esm2020/lib/builder/definition-builder.module.mjs +0 -70
- package/esm2020/lib/builder/models/builder-state.interface.mjs +0 -5
- package/esm2020/lib/builder/services/definition-builder.service.mjs +0 -251
- package/esm2020/lib/builder/services/definition-export.service.mjs +0 -167
- package/esm2020/lib/builder/services/definition-import.service.mjs +0 -193
- package/esm2020/lib/builder/services/sample-data-generator.service.mjs +0 -126
- package/esm2020/lib/builder/utils/config-validator.util.mjs +0 -165
- package/esm2020/lib/builder/utils/typescript-generator.util.mjs +0 -206
- package/esm2020/lib/editors/index.mjs +0 -9
- package/esm2020/lib/editors/nile-autocomplete-editor.mjs +0 -228
- package/esm2020/lib/editors/nile-calendar-editor.mjs +0 -211
- package/esm2020/lib/editors/nile-date-picker-editor.mjs +0 -188
- package/esm2020/lib/editors/nile-input-editor.mjs +0 -235
- package/esm2020/lib/editors/nile-select-editor.mjs +0 -498
- package/esm2020/lib/factories/column-config.factory.mjs +0 -231
- package/esm2020/lib/models/autosave-config.interface.mjs +0 -8
- package/esm2020/lib/models/base-column-config.class.mjs +0 -253
- package/esm2020/lib/models/cell-strategies.interface.mjs +0 -6
- package/esm2020/lib/models/cell-types.mjs +0 -147
- package/esm2020/lib/models/column-action.interface.mjs +0 -6
- package/esm2020/lib/models/column-config.interface.mjs +0 -43
- package/esm2020/lib/models/column-config.utils.mjs +0 -101
- package/esm2020/lib/models/row-action.interface.mjs +0 -5
- package/esm2020/lib/models/row-validator.interface.mjs +0 -2
- package/esm2020/lib/models/schema-validation.interface.mjs +0 -2
- package/esm2020/lib/models/sheet-action.interface.mjs +0 -5
- package/esm2020/lib/models/sheet-config.interface.mjs +0 -5
- package/esm2020/lib/models/table-config.interface.mjs +0 -107
- package/esm2020/lib/models/table-validator.interface.mjs +0 -2
- package/esm2020/lib/models/workbook-action.interface.mjs +0 -5
- package/esm2020/lib/models/workbook-config.interface.mjs +0 -5
- package/esm2020/lib/renderer/components/st-add-column-button/st-add-column-button.component.mjs +0 -24
- package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +0 -397
- package/esm2020/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.mjs +0 -103
- package/esm2020/lib/renderer/components/st-column-filter/st-column-filter.component.mjs +0 -383
- package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +0 -232
- package/esm2020/lib/renderer/components/st-column-visibility/st-column-visibility.component.mjs +0 -97
- package/esm2020/lib/renderer/components/st-header/st-header.component.mjs +0 -157
- package/esm2020/lib/renderer/components/st-pagination/st-pagination.component.mjs +0 -87
- package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +0 -167
- package/esm2020/lib/renderer/components/st-sheet/st-sheet.component.mjs +0 -165
- package/esm2020/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.mjs +0 -112
- package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +0 -1453
- package/esm2020/lib/renderer/components/st-table-actions/st-table-actions.component.mjs +0 -169
- package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +0 -581
- package/esm2020/lib/renderer/directives/click-outside.directive.mjs +0 -28
- package/esm2020/lib/renderer/directives/st-column-resize.directive.mjs +0 -108
- package/esm2020/lib/renderer/directives/st-keyboard-navigation.directive.mjs +0 -83
- package/esm2020/lib/renderer/models/cell-state.interface.mjs +0 -66
- package/esm2020/lib/renderer/models/cell.class.mjs +0 -389
- package/esm2020/lib/renderer/models/row-validation-state.interface.mjs +0 -7
- package/esm2020/lib/renderer/models/sheet-state.class.mjs +0 -90
- package/esm2020/lib/renderer/models/sheet-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/table-state.class.mjs +0 -871
- package/esm2020/lib/renderer/models/table-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/table-types.mjs +0 -29
- package/esm2020/lib/renderer/models/table-validation-state.interface.mjs +0 -7
- package/esm2020/lib/renderer/models/workbook-state.class.mjs +0 -174
- package/esm2020/lib/renderer/models/workbook-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/z-index.enum.mjs +0 -55
- package/esm2020/lib/schemas/table-config.schema.mjs +0 -472
- package/esm2020/lib/services/autosave.service.mjs +0 -92
- package/esm2020/lib/services/custom-validation-rules.util.mjs +0 -124
- package/esm2020/lib/services/json-schema-validator.service.mjs +0 -216
- package/esm2020/lib/services/row-validation.service.mjs +0 -42
- package/esm2020/lib/services/validation-logger.service.mjs +0 -177
- package/esm2020/lib/services/virtual-scroll.service.mjs +0 -52
- package/esm2020/lib/shared/shared-table-components.module.mjs +0 -35
- package/esm2020/lib/smart-table.module.mjs +0 -124
- package/esm2020/lib/strategies/default-editors.mjs +0 -433
- package/esm2020/lib/strategies/default-formatters.mjs +0 -238
- package/esm2020/lib/strategies/default-validators.mjs +0 -327
- package/esm2020/public-api.mjs +0 -146
- package/fesm2015/aquera-ngx-smart-table.mjs +0 -12347
- package/fesm2015/aquera-ngx-smart-table.mjs.map +0 -1
- package/fesm2020/aquera-ngx-smart-table.mjs.map +0 -1
- package/lib/builder/components/builder-preview/builder-preview.component.d.ts +0 -31
- package/lib/builder/components/builder-toolbar/builder-toolbar.component.d.ts +0 -53
- package/lib/builder/components/column-editor/column-editor.component.d.ts +0 -69
- package/lib/builder/components/column-list/column-list.component.d.ts +0 -65
- package/lib/builder/components/definition-builder/definition-builder.component.d.ts +0 -58
- package/lib/builder/components/table-config-editor/table-config-editor.component.d.ts +0 -32
- package/lib/builder/definition-builder.module.d.ts +0 -15
- package/lib/builder/models/builder-state.interface.d.ts +0 -93
- package/lib/builder/services/definition-builder.service.d.ts +0 -80
- package/lib/builder/services/definition-export.service.d.ts +0 -59
- package/lib/builder/services/definition-import.service.d.ts +0 -31
- package/lib/builder/services/sample-data-generator.service.d.ts +0 -41
- package/lib/builder/utils/config-validator.util.d.ts +0 -32
- package/lib/builder/utils/typescript-generator.util.d.ts +0 -29
- package/lib/editors/index.d.ts +0 -8
- package/lib/editors/nile-autocomplete-editor.d.ts +0 -102
- package/lib/editors/nile-calendar-editor.d.ts +0 -88
- package/lib/editors/nile-date-picker-editor.d.ts +0 -97
- package/lib/editors/nile-input-editor.d.ts +0 -67
- package/lib/editors/nile-select-editor.d.ts +0 -113
- package/lib/factories/column-config.factory.d.ts +0 -73
- package/lib/models/autosave-config.interface.d.ts +0 -23
- package/lib/models/base-column-config.class.d.ts +0 -115
- package/lib/models/cell-strategies.interface.d.ts +0 -188
- package/lib/models/cell-types.d.ts +0 -337
- package/lib/models/column-action.interface.d.ts +0 -86
- package/lib/models/column-config.interface.d.ts +0 -272
- package/lib/models/column-config.utils.d.ts +0 -37
- package/lib/models/row-action.interface.d.ts +0 -86
- package/lib/models/row-validator.interface.d.ts +0 -37
- package/lib/models/schema-validation.interface.d.ts +0 -42
- package/lib/models/sheet-action.interface.d.ts +0 -59
- package/lib/models/sheet-config.interface.d.ts +0 -41
- package/lib/models/table-config.interface.d.ts +0 -251
- package/lib/models/table-validator.interface.d.ts +0 -40
- package/lib/models/workbook-action.interface.d.ts +0 -95
- package/lib/models/workbook-config.interface.d.ts +0 -107
- package/lib/renderer/components/st-add-column-button/st-add-column-button.component.d.ts +0 -9
- package/lib/renderer/components/st-cell/st-cell.component.d.ts +0 -69
- package/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.d.ts +0 -39
- package/lib/renderer/components/st-column-filter/st-column-filter.component.d.ts +0 -139
- package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +0 -81
- package/lib/renderer/components/st-column-visibility/st-column-visibility.component.d.ts +0 -44
- package/lib/renderer/components/st-header/st-header.component.d.ts +0 -93
- package/lib/renderer/components/st-pagination/st-pagination.component.d.ts +0 -42
- package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +0 -67
- package/lib/renderer/components/st-sheet/st-sheet.component.d.ts +0 -98
- package/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.d.ts +0 -58
- package/lib/renderer/components/st-table/st-table.component.d.ts +0 -380
- package/lib/renderer/components/st-table-actions/st-table-actions.component.d.ts +0 -77
- package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +0 -275
- package/lib/renderer/directives/click-outside.directive.d.ts +0 -10
- package/lib/renderer/directives/st-column-resize.directive.d.ts +0 -44
- package/lib/renderer/directives/st-keyboard-navigation.directive.d.ts +0 -19
- package/lib/renderer/models/cell-state.interface.d.ts +0 -118
- package/lib/renderer/models/cell.class.d.ts +0 -174
- package/lib/renderer/models/row-validation-state.interface.d.ts +0 -27
- package/lib/renderer/models/sheet-state.class.d.ts +0 -67
- package/lib/renderer/models/sheet-state.interface.d.ts +0 -55
- package/lib/renderer/models/table-state.class.d.ts +0 -320
- package/lib/renderer/models/table-state.interface.d.ts +0 -18
- package/lib/renderer/models/table-types.d.ts +0 -228
- package/lib/renderer/models/table-validation-state.interface.d.ts +0 -34
- package/lib/renderer/models/workbook-state.class.d.ts +0 -117
- package/lib/renderer/models/workbook-state.interface.d.ts +0 -71
- package/lib/renderer/models/z-index.enum.d.ts +0 -44
- package/lib/schemas/table-config.schema.d.ts +0 -455
- package/lib/services/autosave.service.d.ts +0 -73
- package/lib/services/custom-validation-rules.util.d.ts +0 -12
- package/lib/services/json-schema-validator.service.d.ts +0 -49
- package/lib/services/row-validation.service.d.ts +0 -17
- package/lib/services/validation-logger.service.d.ts +0 -87
- package/lib/services/virtual-scroll.service.d.ts +0 -44
- package/lib/shared/shared-table-components.module.d.ts +0 -9
- package/lib/smart-table.module.d.ts +0 -26
- package/lib/strategies/default-editors.d.ts +0 -109
- package/lib/strategies/default-formatters.d.ts +0 -116
- package/lib/strategies/default-validators.d.ts +0 -113
- package/public-api.d.ts +0 -70
- package/src/lib/builder/README.md +0 -30
- package/src/lib/editors/README.md +0 -303
- package/src/lib/renderer/components/st-column-filter/README.md +0 -286
|
@@ -1,871 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TableState - Reactive state management for table operations
|
|
3
|
-
* Event-driven architecture: tracks state, emits events, consumer handles async data operations
|
|
4
|
-
*/
|
|
5
|
-
import { BehaviorSubject, Subject } from 'rxjs';
|
|
6
|
-
import { map, distinctUntilChanged } from 'rxjs/operators';
|
|
7
|
-
import { SortDirection, FilterOperator } from './table-types';
|
|
8
|
-
import { NavigationDirection } from '../../models/cell-types';
|
|
9
|
-
/**
|
|
10
|
-
* TableState class - Column-driven, event-emitting state management
|
|
11
|
-
* NO data manipulation - only state tracking and event emission
|
|
12
|
-
*/
|
|
13
|
-
export class TableState {
|
|
14
|
-
/**
|
|
15
|
-
* Constructor
|
|
16
|
-
* @param columns Reference to columns array
|
|
17
|
-
* @param config Initial configuration
|
|
18
|
-
*/
|
|
19
|
-
constructor(columns, config) {
|
|
20
|
-
// Row number column width for sticky offset calculation
|
|
21
|
-
this._rowNumberWidth = 0;
|
|
22
|
-
// Settings column width for sticky offset calculation
|
|
23
|
-
this._settingsColumnWidth = 0;
|
|
24
|
-
// Pending focus position after a new row is added
|
|
25
|
-
// Set when requestAddRow is emitted, cleared when focus is applied
|
|
26
|
-
this._pendingFocusAfterRowAdd = null;
|
|
27
|
-
// Dimensions for boundary checking
|
|
28
|
-
this._rowCount = 0;
|
|
29
|
-
this._columnCount = 0;
|
|
30
|
-
this._columns = columns;
|
|
31
|
-
this._initialConfig = {
|
|
32
|
-
initialPage: config?.initialPage ?? 0,
|
|
33
|
-
pageSize: config?.pageSize ?? 25
|
|
34
|
-
};
|
|
35
|
-
// Initialize pagination state
|
|
36
|
-
this._pagination$ = new BehaviorSubject({
|
|
37
|
-
currentPage: this._initialConfig.initialPage,
|
|
38
|
-
pageSize: this._initialConfig.pageSize,
|
|
39
|
-
totalItems: 0,
|
|
40
|
-
totalPages: 0
|
|
41
|
-
});
|
|
42
|
-
// Initialize state change subject
|
|
43
|
-
this._stateChange$ = new Subject();
|
|
44
|
-
// Initialize focus and editing position tracking
|
|
45
|
-
this._focusedCellPosition$ = new BehaviorSubject(null);
|
|
46
|
-
this.focusedCellPosition$ = this._focusedCellPosition$.asObservable();
|
|
47
|
-
this._editingCellPosition$ = new BehaviorSubject(null);
|
|
48
|
-
this.editingCellPosition$ = this._editingCellPosition$.asObservable();
|
|
49
|
-
// Initialize validation state
|
|
50
|
-
this._tableValidationState$ = new BehaviorSubject({
|
|
51
|
-
isValid: true,
|
|
52
|
-
totalRows: 0,
|
|
53
|
-
validRows: 0,
|
|
54
|
-
invalidRows: 0,
|
|
55
|
-
rowStates: new Map(),
|
|
56
|
-
lastUpdated: new Date()
|
|
57
|
-
});
|
|
58
|
-
this.tableValidationState$ = this._tableValidationState$.asObservable();
|
|
59
|
-
// Initialize request add row subject
|
|
60
|
-
this._requestAddRow$ = new Subject();
|
|
61
|
-
this.requestAddRow$ = this._requestAddRow$.asObservable();
|
|
62
|
-
this._columnCount = columns.filter(c => c.visible !== false).length;
|
|
63
|
-
// Setup observables
|
|
64
|
-
this.paginationChange$ = this._pagination$.asObservable().pipe(distinctUntilChanged((a, b) => a.currentPage === b.currentPage &&
|
|
65
|
-
a.pageSize === b.pageSize &&
|
|
66
|
-
a.totalItems === b.totalItems));
|
|
67
|
-
this.state$ = this._pagination$.pipe(map(() => this.buildStateSnapshot()));
|
|
68
|
-
this.stateChange$ = this._stateChange$.asObservable();
|
|
69
|
-
// Clear focus/editing on pagination changes
|
|
70
|
-
this.paginationChange$.subscribe(() => {
|
|
71
|
-
this.clearFocus();
|
|
72
|
-
this.clearEditingCell();
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
// ============================================================================
|
|
76
|
-
// STATE ACCESS METHODS
|
|
77
|
-
// ============================================================================
|
|
78
|
-
/**
|
|
79
|
-
* Get current state snapshot
|
|
80
|
-
*/
|
|
81
|
-
getState() {
|
|
82
|
-
return this.buildStateSnapshot();
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Get current pagination state
|
|
86
|
-
*/
|
|
87
|
-
getPagination() {
|
|
88
|
-
return { ...this._pagination$.value };
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Get columns with sorting enabled
|
|
92
|
-
*/
|
|
93
|
-
getSortedColumns() {
|
|
94
|
-
return this._columns.filter(col => col.sortEnabled === true);
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Get columns with filtering enabled
|
|
98
|
-
*/
|
|
99
|
-
getFilteredColumns() {
|
|
100
|
-
return this._columns.filter(col => col.filterConfig?.enabled === true);
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Get current columns reference
|
|
104
|
-
*/
|
|
105
|
-
getColumns() {
|
|
106
|
-
return this._columns;
|
|
107
|
-
}
|
|
108
|
-
// ============================================================================
|
|
109
|
-
// PAGINATION METHODS
|
|
110
|
-
// ============================================================================
|
|
111
|
-
/**
|
|
112
|
-
* Set current page
|
|
113
|
-
* @param page Page number (0-indexed)
|
|
114
|
-
*/
|
|
115
|
-
setPage(page) {
|
|
116
|
-
const currentState = this._pagination$.value;
|
|
117
|
-
if (page < 0 || page >= currentState.totalPages) {
|
|
118
|
-
console.warn(`Invalid page number: ${page}. Valid range: 0-${currentState.totalPages - 1}`);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
this._pagination$.next({
|
|
122
|
-
...currentState,
|
|
123
|
-
currentPage: page
|
|
124
|
-
});
|
|
125
|
-
this.emitStateChange('pagination');
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Set page size
|
|
129
|
-
* @param size Number of items per page
|
|
130
|
-
*/
|
|
131
|
-
setPageSize(size) {
|
|
132
|
-
if (size <= 0) {
|
|
133
|
-
console.warn(`Invalid page size: ${size}. Must be greater than 0.`);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const currentState = this._pagination$.value;
|
|
137
|
-
const newTotalPages = this.calculateTotalPages(currentState.totalItems, size);
|
|
138
|
-
this._pagination$.next({
|
|
139
|
-
currentPage: 0,
|
|
140
|
-
pageSize: size,
|
|
141
|
-
totalItems: currentState.totalItems,
|
|
142
|
-
totalPages: newTotalPages
|
|
143
|
-
});
|
|
144
|
-
this.emitStateChange('pagination');
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Set total items (called after API response)
|
|
148
|
-
* @param total Total number of items
|
|
149
|
-
*/
|
|
150
|
-
setTotalItems(total) {
|
|
151
|
-
const currentState = this._pagination$.value;
|
|
152
|
-
const newTotalPages = this.calculateTotalPages(total, currentState.pageSize);
|
|
153
|
-
this._pagination$.next({
|
|
154
|
-
...currentState,
|
|
155
|
-
totalItems: total,
|
|
156
|
-
totalPages: newTotalPages
|
|
157
|
-
});
|
|
158
|
-
// Don't emit state change here - this is called after data load
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Go to next page
|
|
162
|
-
*/
|
|
163
|
-
nextPage() {
|
|
164
|
-
const currentState = this._pagination$.value;
|
|
165
|
-
if (this.hasNextPage()) {
|
|
166
|
-
this.setPage(currentState.currentPage + 1);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Go to previous page
|
|
171
|
-
*/
|
|
172
|
-
previousPage() {
|
|
173
|
-
const currentState = this._pagination$.value;
|
|
174
|
-
if (this.hasPreviousPage()) {
|
|
175
|
-
this.setPage(currentState.currentPage - 1);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Go to first page
|
|
180
|
-
*/
|
|
181
|
-
firstPage() {
|
|
182
|
-
this.setPage(0);
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Go to last page
|
|
186
|
-
*/
|
|
187
|
-
lastPage() {
|
|
188
|
-
const currentState = this._pagination$.value;
|
|
189
|
-
if (currentState.totalPages > 0) {
|
|
190
|
-
this.setPage(currentState.totalPages - 1);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Check if there is a next page
|
|
195
|
-
*/
|
|
196
|
-
hasNextPage() {
|
|
197
|
-
const currentState = this._pagination$.value;
|
|
198
|
-
return currentState.currentPage < currentState.totalPages - 1;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Check if there is a previous page
|
|
202
|
-
*/
|
|
203
|
-
hasPreviousPage() {
|
|
204
|
-
const currentState = this._pagination$.value;
|
|
205
|
-
return currentState.currentPage > 0;
|
|
206
|
-
}
|
|
207
|
-
// ============================================================================
|
|
208
|
-
// SORTING METHODS (operate on column configs)
|
|
209
|
-
// ============================================================================
|
|
210
|
-
/**
|
|
211
|
-
* Set sort on a column (clears other sorts)
|
|
212
|
-
* @param columnKey Column key
|
|
213
|
-
* @param direction Sort direction
|
|
214
|
-
*/
|
|
215
|
-
setSortOnColumn(columnKey, direction) {
|
|
216
|
-
const column = this.findColumn(columnKey);
|
|
217
|
-
if (!column) {
|
|
218
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
if (column.sortable === false) {
|
|
222
|
-
console.warn(`Column ${columnKey} is not sortable`);
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
// Clear all other sorts
|
|
226
|
-
this._columns.forEach(col => {
|
|
227
|
-
if (col.key !== columnKey) {
|
|
228
|
-
col.sortDirection = SortDirection.NONE;
|
|
229
|
-
col.sortEnabled = false;
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
// Set sort on target column
|
|
233
|
-
column.sortDirection = direction;
|
|
234
|
-
column.sortEnabled = direction !== SortDirection.NONE;
|
|
235
|
-
this.emitStateChange('sorting');
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Add sort to a column (for multi-column sorting)
|
|
239
|
-
* @param columnKey Column key
|
|
240
|
-
* @param direction Sort direction
|
|
241
|
-
*/
|
|
242
|
-
addSortToColumn(columnKey, direction) {
|
|
243
|
-
const column = this.findColumn(columnKey);
|
|
244
|
-
if (!column) {
|
|
245
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (column.sortable === false) {
|
|
249
|
-
console.warn(`Column ${columnKey} is not sortable`);
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
column.sortDirection = direction;
|
|
253
|
-
column.sortEnabled = direction !== SortDirection.NONE;
|
|
254
|
-
this.emitStateChange('sorting');
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Toggle sort on a column (cycles through none -> asc -> desc -> none)
|
|
258
|
-
* @param columnKey Column key
|
|
259
|
-
*/
|
|
260
|
-
toggleSortOnColumn(columnKey) {
|
|
261
|
-
const column = this.findColumn(columnKey);
|
|
262
|
-
if (!column) {
|
|
263
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
if (column.sortable === false) {
|
|
267
|
-
console.warn(`Column ${columnKey} is not sortable`);
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
const currentDirection = column.sortDirection || SortDirection.NONE;
|
|
271
|
-
let newDirection;
|
|
272
|
-
switch (currentDirection) {
|
|
273
|
-
case SortDirection.NONE:
|
|
274
|
-
newDirection = SortDirection.ASC;
|
|
275
|
-
break;
|
|
276
|
-
case SortDirection.ASC:
|
|
277
|
-
newDirection = SortDirection.DESC;
|
|
278
|
-
break;
|
|
279
|
-
case SortDirection.DESC:
|
|
280
|
-
newDirection = SortDirection.NONE;
|
|
281
|
-
break;
|
|
282
|
-
default:
|
|
283
|
-
newDirection = SortDirection.ASC;
|
|
284
|
-
}
|
|
285
|
-
column.sortDirection = newDirection;
|
|
286
|
-
column.sortEnabled = newDirection !== SortDirection.NONE;
|
|
287
|
-
this.clearFocus();
|
|
288
|
-
this.clearEditingCell();
|
|
289
|
-
this.emitStateChange('sorting');
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Clear all sorting
|
|
293
|
-
*/
|
|
294
|
-
clearAllSorting() {
|
|
295
|
-
this._columns.forEach(col => {
|
|
296
|
-
col.sortDirection = SortDirection.NONE;
|
|
297
|
-
col.sortEnabled = false;
|
|
298
|
-
});
|
|
299
|
-
this.clearFocus();
|
|
300
|
-
this.clearEditingCell();
|
|
301
|
-
this.emitStateChange('sorting');
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Get sort configuration for a column
|
|
305
|
-
* @param columnKey Column key
|
|
306
|
-
* @returns Sort configuration or null
|
|
307
|
-
*/
|
|
308
|
-
getSortForColumn(columnKey) {
|
|
309
|
-
const column = this.findColumn(columnKey);
|
|
310
|
-
if (!column) {
|
|
311
|
-
return null;
|
|
312
|
-
}
|
|
313
|
-
return {
|
|
314
|
-
direction: column.sortDirection || SortDirection.NONE,
|
|
315
|
-
enabled: column.sortEnabled || false
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
// ============================================================================
|
|
319
|
-
// FILTERING METHODS (operate on column configs)
|
|
320
|
-
// ============================================================================
|
|
321
|
-
/**
|
|
322
|
-
* Set filter on a column
|
|
323
|
-
* @param columnKey Column key
|
|
324
|
-
* @param operator Filter operator
|
|
325
|
-
* @param value Filter value
|
|
326
|
-
*/
|
|
327
|
-
setFilterOnColumn(columnKey, operator, value) {
|
|
328
|
-
const column = this.findColumn(columnKey);
|
|
329
|
-
if (!column) {
|
|
330
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
if (column.filterable === false) {
|
|
334
|
-
console.warn(`Column ${columnKey} is not filterable`);
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
// Initialize filterConfig if it doesn't exist
|
|
338
|
-
if (!column.filterConfig) {
|
|
339
|
-
column.filterConfig = {};
|
|
340
|
-
}
|
|
341
|
-
column.filterConfig.operator = operator;
|
|
342
|
-
column.filterConfig.value = value;
|
|
343
|
-
column.filterConfig.enabled = true;
|
|
344
|
-
this.clearFocus();
|
|
345
|
-
this.clearEditingCell();
|
|
346
|
-
this.emitStateChange('filtering');
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Clear filter on a column
|
|
350
|
-
* @param columnKey Column key
|
|
351
|
-
*/
|
|
352
|
-
clearFilterOnColumn(columnKey) {
|
|
353
|
-
const column = this.findColumn(columnKey);
|
|
354
|
-
if (!column) {
|
|
355
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
// Initialize filterConfig if it doesn't exist (for consistency with setFilterOnColumn)
|
|
359
|
-
if (!column.filterConfig) {
|
|
360
|
-
column.filterConfig = {};
|
|
361
|
-
}
|
|
362
|
-
column.filterConfig.value = undefined;
|
|
363
|
-
column.filterConfig.enabled = false;
|
|
364
|
-
this.clearFocus();
|
|
365
|
-
this.clearEditingCell();
|
|
366
|
-
this.emitStateChange('filtering');
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* Clear all filters
|
|
370
|
-
*/
|
|
371
|
-
clearAllFilters() {
|
|
372
|
-
this._columns.forEach(col => {
|
|
373
|
-
// Initialize filterConfig if it doesn't exist (for consistency with setFilterOnColumn)
|
|
374
|
-
if (!col.filterConfig) {
|
|
375
|
-
col.filterConfig = {};
|
|
376
|
-
}
|
|
377
|
-
col.filterConfig.value = undefined;
|
|
378
|
-
col.filterConfig.enabled = false;
|
|
379
|
-
});
|
|
380
|
-
this.clearFocus();
|
|
381
|
-
this.clearEditingCell();
|
|
382
|
-
this.emitStateChange('filtering');
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Set filter enabled state
|
|
386
|
-
* @param columnKey Column key
|
|
387
|
-
* @param enabled Whether filter is enabled
|
|
388
|
-
*/
|
|
389
|
-
setFilterEnabled(columnKey, enabled) {
|
|
390
|
-
const column = this.findColumn(columnKey);
|
|
391
|
-
if (!column) {
|
|
392
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
// Initialize filterConfig if it doesn't exist
|
|
396
|
-
if (!column.filterConfig) {
|
|
397
|
-
column.filterConfig = {};
|
|
398
|
-
}
|
|
399
|
-
column.filterConfig.enabled = enabled;
|
|
400
|
-
this.emitStateChange('filtering');
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Get filter configuration for a column
|
|
404
|
-
* @param columnKey Column key
|
|
405
|
-
* @returns Filter configuration or null
|
|
406
|
-
*/
|
|
407
|
-
getFilterForColumn(columnKey) {
|
|
408
|
-
const column = this.findColumn(columnKey);
|
|
409
|
-
if (!column) {
|
|
410
|
-
return null;
|
|
411
|
-
}
|
|
412
|
-
return {
|
|
413
|
-
operator: column.filterConfig?.operator || FilterOperator.CONTAINS,
|
|
414
|
-
value: column.filterConfig?.value,
|
|
415
|
-
enabled: column.filterConfig?.enabled || false
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
// ============================================================================
|
|
419
|
-
// STICKY COLUMN MANAGEMENT
|
|
420
|
-
// ============================================================================
|
|
421
|
-
/**
|
|
422
|
-
* Get sticky columns grouped by position
|
|
423
|
-
* @returns Object with left and right sticky column keys
|
|
424
|
-
*/
|
|
425
|
-
getStickyColumns() {
|
|
426
|
-
const left = this._columns
|
|
427
|
-
.filter(col => col.sticky === 'left')
|
|
428
|
-
.map(col => col.key);
|
|
429
|
-
const right = this._columns
|
|
430
|
-
.filter(col => col.sticky === 'right')
|
|
431
|
-
.map(col => col.key);
|
|
432
|
-
return { left, right };
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Set sticky position for a column
|
|
436
|
-
* @param columnKey Column key
|
|
437
|
-
* @param position Sticky position ('left', 'right', or false)
|
|
438
|
-
*/
|
|
439
|
-
setStickyColumn(columnKey, position) {
|
|
440
|
-
const column = this.findColumn(columnKey);
|
|
441
|
-
if (!column) {
|
|
442
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
column.sticky = position;
|
|
446
|
-
this.calculateStickyOffsets();
|
|
447
|
-
this.emitStateChange('column-config');
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Calculate sticky offsets for all sticky columns
|
|
451
|
-
* This calculates cumulative widths for positioning
|
|
452
|
-
* @param rowNumberWidth Optional width of row number column to account for in left offset
|
|
453
|
-
* @param settingsColumnWidth Optional width of settings column to account for in right offset
|
|
454
|
-
*/
|
|
455
|
-
calculateStickyOffsets(rowNumberWidth, settingsColumnWidth) {
|
|
456
|
-
// Update stored row number width if provided
|
|
457
|
-
if (rowNumberWidth !== undefined) {
|
|
458
|
-
this._rowNumberWidth = rowNumberWidth;
|
|
459
|
-
}
|
|
460
|
-
// Update stored settings column width if provided
|
|
461
|
-
if (settingsColumnWidth !== undefined) {
|
|
462
|
-
this._settingsColumnWidth = settingsColumnWidth;
|
|
463
|
-
}
|
|
464
|
-
// Calculate left sticky offsets
|
|
465
|
-
// Account for row number column width
|
|
466
|
-
let leftOffset = this._rowNumberWidth;
|
|
467
|
-
this._columns.forEach(col => {
|
|
468
|
-
if (col.sticky === 'left') {
|
|
469
|
-
col.stickyOffset = leftOffset;
|
|
470
|
-
leftOffset += col.width || 100;
|
|
471
|
-
}
|
|
472
|
-
});
|
|
473
|
-
// Calculate right sticky offsets
|
|
474
|
-
// Account for settings column width (row actions column)
|
|
475
|
-
let rightOffset = this._settingsColumnWidth;
|
|
476
|
-
for (let i = this._columns.length - 1; i >= 0; i--) {
|
|
477
|
-
const col = this._columns[i];
|
|
478
|
-
if (col.sticky === 'right') {
|
|
479
|
-
col.stickyOffset = rightOffset;
|
|
480
|
-
rightOffset += col.width || 100;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
// ============================================================================
|
|
485
|
-
// COLUMN MANAGEMENT
|
|
486
|
-
// ============================================================================
|
|
487
|
-
/**
|
|
488
|
-
* Update columns reference
|
|
489
|
-
* @param columns New columns array
|
|
490
|
-
*/
|
|
491
|
-
updateColumns(columns) {
|
|
492
|
-
this._columns = columns;
|
|
493
|
-
this.calculateStickyOffsets();
|
|
494
|
-
this.emitStateChange('column-config');
|
|
495
|
-
}
|
|
496
|
-
// ============================================================================
|
|
497
|
-
// COLUMN VISIBILITY METHODS
|
|
498
|
-
// ============================================================================
|
|
499
|
-
/**
|
|
500
|
-
* Toggle visibility of a column
|
|
501
|
-
* @param columnKey Column key
|
|
502
|
-
*/
|
|
503
|
-
toggleColumnVisibility(columnKey) {
|
|
504
|
-
const column = this.findColumn(columnKey);
|
|
505
|
-
if (!column) {
|
|
506
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
// Check if column is hideable
|
|
510
|
-
if (column.hideable === false) {
|
|
511
|
-
console.warn(`Column ${columnKey} cannot be hidden (hideable is false)`);
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
const currentVisibility = column.visible !== false; // Default to true if not set
|
|
515
|
-
column.visible = !currentVisibility;
|
|
516
|
-
this.emitStateChange('column-visibility');
|
|
517
|
-
}
|
|
518
|
-
/**
|
|
519
|
-
* Set visibility of a column
|
|
520
|
-
* @param columnKey Column key
|
|
521
|
-
* @param visible Whether column should be visible
|
|
522
|
-
*/
|
|
523
|
-
setColumnVisibility(columnKey, visible) {
|
|
524
|
-
const column = this.findColumn(columnKey);
|
|
525
|
-
if (!column) {
|
|
526
|
-
console.warn(`Column not found: ${columnKey}`);
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
// Check if column is hideable (only when trying to hide)
|
|
530
|
-
if (!visible && column.hideable === false) {
|
|
531
|
-
console.warn(`Column ${columnKey} cannot be hidden (hideable is false)`);
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
column.visible = visible;
|
|
535
|
-
this.emitStateChange('column-visibility');
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Get all visible columns
|
|
539
|
-
* @returns Array of visible column configs
|
|
540
|
-
*/
|
|
541
|
-
getVisibleColumns() {
|
|
542
|
-
return this._columns.filter(col => col.visible !== false); // Default to true if not set
|
|
543
|
-
}
|
|
544
|
-
/**
|
|
545
|
-
* Get visibility state for all columns
|
|
546
|
-
* @returns Array of column visibility info
|
|
547
|
-
*/
|
|
548
|
-
getAllColumnsVisibility() {
|
|
549
|
-
return this._columns.map(col => ({
|
|
550
|
-
key: col.key,
|
|
551
|
-
header: col.header || col.key,
|
|
552
|
-
visible: col.visible !== false,
|
|
553
|
-
hideable: col.hideable !== false // Default to true if not set
|
|
554
|
-
}));
|
|
555
|
-
}
|
|
556
|
-
// ============================================================================
|
|
557
|
-
// KEYBOARD NAVIGATION & FOCUS MANAGEMENT
|
|
558
|
-
// ============================================================================
|
|
559
|
-
/**
|
|
560
|
-
* Set table dimensions for navigation boundaries
|
|
561
|
-
*/
|
|
562
|
-
setDimensions(rowCount, columnCount) {
|
|
563
|
-
const previousRowCount = this._rowCount;
|
|
564
|
-
this._rowCount = rowCount;
|
|
565
|
-
this._columnCount = columnCount;
|
|
566
|
-
// Update total rows in validation state
|
|
567
|
-
this.setValidationRowCount(rowCount);
|
|
568
|
-
// Check if a new row was added and we have a pending focus
|
|
569
|
-
if (this._pendingFocusAfterRowAdd && rowCount > previousRowCount) {
|
|
570
|
-
const { columnIndex } = this._pendingFocusAfterRowAdd;
|
|
571
|
-
// Focus the last row (newly added) at the pending column
|
|
572
|
-
const newRowIndex = rowCount - 1;
|
|
573
|
-
this._pendingFocusAfterRowAdd = null; // Clear pending focus
|
|
574
|
-
// Delay focus to ensure DOM is updated
|
|
575
|
-
setTimeout(() => {
|
|
576
|
-
this.focusCell(newRowIndex, columnIndex);
|
|
577
|
-
}, 0);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* Focus a cell by position
|
|
582
|
-
*/
|
|
583
|
-
focusCell(rowIndex, columnIndex) {
|
|
584
|
-
if (rowIndex < 0 || rowIndex >= this._rowCount)
|
|
585
|
-
return;
|
|
586
|
-
if (columnIndex < 0 || columnIndex >= this._columnCount)
|
|
587
|
-
return;
|
|
588
|
-
this._focusedCellPosition$.next({ rowIndex, columnIndex });
|
|
589
|
-
this.emitStateChange('cell-focus');
|
|
590
|
-
}
|
|
591
|
-
/**
|
|
592
|
-
* Get currently focused position
|
|
593
|
-
*/
|
|
594
|
-
getFocusedPosition() {
|
|
595
|
-
return this._focusedCellPosition$.value;
|
|
596
|
-
}
|
|
597
|
-
/**
|
|
598
|
-
* Notify that a cell entered edit mode
|
|
599
|
-
*/
|
|
600
|
-
setEditingCell(rowIndex, columnIndex) {
|
|
601
|
-
this._editingCellPosition$.next({ rowIndex, columnIndex });
|
|
602
|
-
this.emitStateChange('cell-edit-start');
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Notify that edit mode ended
|
|
606
|
-
*/
|
|
607
|
-
clearEditingCell() {
|
|
608
|
-
this._editingCellPosition$.next(null);
|
|
609
|
-
this.emitStateChange('cell-edit-end');
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Check if any cell is currently editing
|
|
613
|
-
*/
|
|
614
|
-
isAnyCellEditing() {
|
|
615
|
-
return this._editingCellPosition$.value !== null;
|
|
616
|
-
}
|
|
617
|
-
/**
|
|
618
|
-
* Get currently editing position
|
|
619
|
-
*/
|
|
620
|
-
getEditingPosition() {
|
|
621
|
-
return this._editingCellPosition$.value;
|
|
622
|
-
}
|
|
623
|
-
/**
|
|
624
|
-
* Move focus in a direction using NavigationDirection enum
|
|
625
|
-
* @param direction The navigation direction
|
|
626
|
-
* @param addRowOnNavigatePastEnd If true, emits requestAddRow when navigating past last row
|
|
627
|
-
*/
|
|
628
|
-
moveFocus(direction, addRowOnNavigatePastEnd = false) {
|
|
629
|
-
// Block navigation if any cell is editing
|
|
630
|
-
if (this.isAnyCellEditing()) {
|
|
631
|
-
return false;
|
|
632
|
-
}
|
|
633
|
-
const current = this._focusedCellPosition$.value;
|
|
634
|
-
if (!current)
|
|
635
|
-
return false;
|
|
636
|
-
let newRow = current.rowIndex;
|
|
637
|
-
let newCol = current.columnIndex;
|
|
638
|
-
// Use NavigationDirection enum values
|
|
639
|
-
switch (direction) {
|
|
640
|
-
case NavigationDirection.UP:
|
|
641
|
-
newRow--;
|
|
642
|
-
break;
|
|
643
|
-
case NavigationDirection.DOWN:
|
|
644
|
-
newRow++;
|
|
645
|
-
break;
|
|
646
|
-
case NavigationDirection.LEFT:
|
|
647
|
-
newCol--;
|
|
648
|
-
break;
|
|
649
|
-
case NavigationDirection.RIGHT:
|
|
650
|
-
newCol++;
|
|
651
|
-
break;
|
|
652
|
-
}
|
|
653
|
-
// Check if navigating past last row (arrow down at bottom)
|
|
654
|
-
if (direction === NavigationDirection.DOWN && newRow >= this._rowCount) {
|
|
655
|
-
if (addRowOnNavigatePastEnd) {
|
|
656
|
-
// Store pending focus for when the new row is added
|
|
657
|
-
this._pendingFocusAfterRowAdd = { columnIndex: current.columnIndex };
|
|
658
|
-
// Emit request to add a new row, keeping the same column for focus
|
|
659
|
-
this._requestAddRow$.next({ focusColumn: current.columnIndex });
|
|
660
|
-
}
|
|
661
|
-
return false;
|
|
662
|
-
}
|
|
663
|
-
if (newRow < 0 || newRow >= this._rowCount)
|
|
664
|
-
return false;
|
|
665
|
-
if (newCol < 0 || newCol >= this._columnCount)
|
|
666
|
-
return false;
|
|
667
|
-
this.focusCell(newRow, newCol);
|
|
668
|
-
return true;
|
|
669
|
-
}
|
|
670
|
-
/**
|
|
671
|
-
* Clear focus
|
|
672
|
-
*/
|
|
673
|
-
clearFocus() {
|
|
674
|
-
this._focusedCellPosition$.next(null);
|
|
675
|
-
this.emitStateChange('cell-focus');
|
|
676
|
-
}
|
|
677
|
-
/**
|
|
678
|
-
* Check if navigation is active
|
|
679
|
-
*/
|
|
680
|
-
isNavigationActive() {
|
|
681
|
-
return this._focusedCellPosition$.value !== null;
|
|
682
|
-
}
|
|
683
|
-
// ============================================================================
|
|
684
|
-
// VALIDATION STATE METHODS
|
|
685
|
-
// ============================================================================
|
|
686
|
-
/**
|
|
687
|
-
* Update cell validation and accumulate into row/table validation state
|
|
688
|
-
* Only stores invalid states - valid rows are automatically removed
|
|
689
|
-
*/
|
|
690
|
-
updateCellValidation(rowIndex, columnKey, isValid, error) {
|
|
691
|
-
const currentState = this._tableValidationState$.value;
|
|
692
|
-
const rowStates = new Map(currentState.rowStates);
|
|
693
|
-
// Get existing row state (only exists if row has errors)
|
|
694
|
-
let rowState = rowStates.get(rowIndex);
|
|
695
|
-
if (!isValid && error) {
|
|
696
|
-
// Cell is invalid - add or update error
|
|
697
|
-
if (!rowState) {
|
|
698
|
-
// Create new row state for this invalid row
|
|
699
|
-
rowState = {
|
|
700
|
-
rowIndex,
|
|
701
|
-
isValid: false,
|
|
702
|
-
invalidCellCount: 1,
|
|
703
|
-
cellErrors: new Map([[columnKey, error]]),
|
|
704
|
-
lastValidated: new Date()
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
else {
|
|
708
|
-
// Update existing row state
|
|
709
|
-
const cellErrors = new Map(rowState.cellErrors);
|
|
710
|
-
cellErrors.set(columnKey, error);
|
|
711
|
-
rowState = {
|
|
712
|
-
rowIndex,
|
|
713
|
-
isValid: false,
|
|
714
|
-
invalidCellCount: cellErrors.size,
|
|
715
|
-
cellErrors,
|
|
716
|
-
lastValidated: new Date()
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
|
-
rowStates.set(rowIndex, rowState);
|
|
720
|
-
}
|
|
721
|
-
else {
|
|
722
|
-
// Cell is valid - remove error if it exists
|
|
723
|
-
if (rowState) {
|
|
724
|
-
const cellErrors = new Map(rowState.cellErrors);
|
|
725
|
-
cellErrors.delete(columnKey);
|
|
726
|
-
if (cellErrors.size === 0) {
|
|
727
|
-
// No more errors in this row - remove row state completely
|
|
728
|
-
rowStates.delete(rowIndex);
|
|
729
|
-
}
|
|
730
|
-
else {
|
|
731
|
-
// Still has other errors - update row state
|
|
732
|
-
rowState = {
|
|
733
|
-
rowIndex,
|
|
734
|
-
isValid: false,
|
|
735
|
-
invalidCellCount: cellErrors.size,
|
|
736
|
-
cellErrors,
|
|
737
|
-
lastValidated: new Date()
|
|
738
|
-
};
|
|
739
|
-
rowStates.set(rowIndex, rowState);
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
// If rowState doesn't exist, cell was already valid - do nothing
|
|
743
|
-
}
|
|
744
|
-
// Recalculate table state
|
|
745
|
-
// All rows in rowStates map are invalid by definition
|
|
746
|
-
const invalidRows = rowStates.size;
|
|
747
|
-
const newTableState = {
|
|
748
|
-
isValid: invalidRows === 0,
|
|
749
|
-
totalRows: currentState.totalRows,
|
|
750
|
-
validRows: currentState.totalRows - invalidRows,
|
|
751
|
-
invalidRows,
|
|
752
|
-
rowStates,
|
|
753
|
-
lastUpdated: new Date()
|
|
754
|
-
};
|
|
755
|
-
// Emit new state
|
|
756
|
-
this._tableValidationState$.next(newTableState);
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* Get current table validation state
|
|
760
|
-
*/
|
|
761
|
-
getTableValidationState() {
|
|
762
|
-
return this._tableValidationState$.value;
|
|
763
|
-
}
|
|
764
|
-
/**
|
|
765
|
-
* Set total rows for validation state tracking
|
|
766
|
-
*/
|
|
767
|
-
setValidationRowCount(totalRows) {
|
|
768
|
-
const currentState = this._tableValidationState$.value;
|
|
769
|
-
this._tableValidationState$.next({
|
|
770
|
-
...currentState,
|
|
771
|
-
totalRows,
|
|
772
|
-
lastUpdated: new Date()
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
// ============================================================================
|
|
776
|
-
// STATE RESET
|
|
777
|
-
// ============================================================================
|
|
778
|
-
/**
|
|
779
|
-
* Reset to initial configuration
|
|
780
|
-
*/
|
|
781
|
-
reset() {
|
|
782
|
-
this.resetPagination();
|
|
783
|
-
this.resetAllSorting();
|
|
784
|
-
this.resetAllFilters();
|
|
785
|
-
}
|
|
786
|
-
/**
|
|
787
|
-
* Reset pagination only
|
|
788
|
-
*/
|
|
789
|
-
resetPagination() {
|
|
790
|
-
this._pagination$.next({
|
|
791
|
-
currentPage: this._initialConfig.initialPage,
|
|
792
|
-
pageSize: this._initialConfig.pageSize,
|
|
793
|
-
totalItems: 0,
|
|
794
|
-
totalPages: 0
|
|
795
|
-
});
|
|
796
|
-
this.emitStateChange('pagination');
|
|
797
|
-
}
|
|
798
|
-
/**
|
|
799
|
-
* Reset all column sorts
|
|
800
|
-
*/
|
|
801
|
-
resetAllSorting() {
|
|
802
|
-
this.clearAllSorting();
|
|
803
|
-
}
|
|
804
|
-
/**
|
|
805
|
-
* Reset all column filters
|
|
806
|
-
*/
|
|
807
|
-
resetAllFilters() {
|
|
808
|
-
this.clearAllFilters();
|
|
809
|
-
}
|
|
810
|
-
// ============================================================================
|
|
811
|
-
// INTERNAL METHODS
|
|
812
|
-
// ============================================================================
|
|
813
|
-
/**
|
|
814
|
-
* Find a column by key
|
|
815
|
-
* @param columnKey Column key
|
|
816
|
-
* @returns Column config or undefined
|
|
817
|
-
*/
|
|
818
|
-
findColumn(columnKey) {
|
|
819
|
-
return this._columns.find(col => col.key === columnKey);
|
|
820
|
-
}
|
|
821
|
-
/**
|
|
822
|
-
* Calculate total pages
|
|
823
|
-
* @param totalItems Total number of items
|
|
824
|
-
* @param pageSize Page size
|
|
825
|
-
* @returns Total number of pages
|
|
826
|
-
*/
|
|
827
|
-
calculateTotalPages(totalItems = 0, pageSize = 25) {
|
|
828
|
-
if (totalItems === 0 || pageSize === 0) {
|
|
829
|
-
return 0;
|
|
830
|
-
}
|
|
831
|
-
return Math.ceil(totalItems / pageSize);
|
|
832
|
-
}
|
|
833
|
-
/**
|
|
834
|
-
* Emit state change event
|
|
835
|
-
* @param type Type of change
|
|
836
|
-
*/
|
|
837
|
-
emitStateChange(type) {
|
|
838
|
-
const state = this.buildStateSnapshot();
|
|
839
|
-
this._stateChange$.next({
|
|
840
|
-
type,
|
|
841
|
-
state
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
|
-
/**
|
|
845
|
-
* Build state snapshot from current state
|
|
846
|
-
* @returns State snapshot
|
|
847
|
-
*/
|
|
848
|
-
buildStateSnapshot() {
|
|
849
|
-
return {
|
|
850
|
-
pagination: this.getPagination(),
|
|
851
|
-
// Build full sort state with direction and priority
|
|
852
|
-
sortedColumns: this._columns
|
|
853
|
-
.filter(col => col.sortEnabled === true)
|
|
854
|
-
.map((col, index) => ({
|
|
855
|
-
columnKey: col.key,
|
|
856
|
-
direction: col.sortDirection || SortDirection.NONE,
|
|
857
|
-
priority: index // Sort order based on enablement order
|
|
858
|
-
})),
|
|
859
|
-
// Build full filter state with operator and value
|
|
860
|
-
filteredColumns: this._columns
|
|
861
|
-
.filter(col => col.filterConfig?.enabled === true)
|
|
862
|
-
.map(col => ({
|
|
863
|
-
columnKey: col.key,
|
|
864
|
-
operator: col.filterConfig?.operator || FilterOperator.CONTAINS,
|
|
865
|
-
value: col.filterConfig?.value,
|
|
866
|
-
enabled: true
|
|
867
|
-
}))
|
|
868
|
-
};
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtc3RhdGUuY2xhc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zbWFydC10YWJsZS9zcmMvbGliL3JlbmRlcmVyL21vZGVscy90YWJsZS1zdGF0ZS5jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsZUFBZSxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1RCxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0QsT0FBTyxFQUVMLGFBQWEsRUFDYixjQUFjLEVBSWYsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFJOUQ7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUEwRHJCOzs7O09BSUc7SUFDSCxZQUFZLE9BQTRCLEVBQUUsTUFBeUI7UUFsRG5FLHdEQUF3RDtRQUNoRCxvQkFBZSxHQUFXLENBQUMsQ0FBQztRQUVwQyxzREFBc0Q7UUFDOUMseUJBQW9CLEdBQVcsQ0FBQyxDQUFDO1FBa0J6QyxrREFBa0Q7UUFDbEQsbUVBQW1FO1FBQzNELDZCQUF3QixHQUFtQyxJQUFJLENBQUM7UUFFeEUsbUNBQW1DO1FBQzNCLGNBQVMsR0FBVyxDQUFDLENBQUM7UUFDdEIsaUJBQVksR0FBVyxDQUFDLENBQUM7UUF1Qi9CLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxjQUFjLEdBQUc7WUFDcEIsV0FBVyxFQUFFLE1BQU0sRUFBRSxXQUFXLElBQUksQ0FBQztZQUNyQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsSUFBSSxFQUFFO1NBQ2pDLENBQUM7UUFFRiw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLGVBQWUsQ0FBa0I7WUFDdkQsV0FBVyxFQUFFLElB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QUMsYUFBYSxDQUFDLElBQUksQ0FBQztZQUN0QixJQUFJO1lBQ0osS0FBSztTQUNOLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSyxrQkFBa0I7UUFDeEIsT0FBTztZQUNMLFVBQVUsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBRWhDLG9EQUFvRDtZQUNwRCxhQUFhLEVBQUUsSUFBSSxDQUFDLFFBQVE7aUJBQ3pCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEtBQUssSUFBSSxDQUFDO2lCQUN2QyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNwQixTQUFTLEVBQUUsR0FBRyxDQUFDLEdBQUc7Z0JBQ2xCLFNBQVMsRUFBRSxHQUFHLENBQUMsYUFBYSxJQUFJLGFBQWEsQ0FBQyxJQUFJO2dCQUNsRCxRQUFRLEVBQUUsS0FBSyxDQUFFLHVDQUF1QzthQUN6RCxDQUFDLENBQUM7WUFFTCxrREFBa0Q7WUFDbEQsZUFBZSxFQUFFLElBQUksQ0FBQyxRQUFRO2lCQUMzQixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLE9BQU8sS0FBSyxJQUFJLENBQUM7aUJBQ2pELEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ1gsU0FBUyxFQUFFLEdBQUcsQ0FBQyxHQUFHO2dCQUNsQixRQUFRLEVBQUUsR0FBRyxDQUFDLFlBQVksRUFBRSxRQUFRLElBQUksY0FBYyxDQUFDLFFBQVE7Z0JBQy9ELEtBQUssRUFBRSxHQUFHLENBQUMsWUFBWSxFQUFFLEtBQUs7Z0JBQzlCLE9BQU8sRUFBRSxJQUFJO2FBQ2QsQ0FBQyxDQUFDO1NBQ04sQ0FBQztJQUNKLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGFibGVTdGF0ZSAtIFJlYWN0aXZlIHN0YXRlIG1hbmFnZW1lbnQgZm9yIHRhYmxlIG9wZXJhdGlvbnNcbiAqIEV2ZW50LWRyaXZlbiBhcmNoaXRlY3R1cmU6IHRyYWNrcyBzdGF0ZSwgZW1pdHMgZXZlbnRzLCBjb25zdW1lciBoYW5kbGVzIGFzeW5jIGRhdGEgb3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENvbHVtbkNvbmZpZyB9IGZyb20gJy4uLy4uL21vZGVscy9jb2x1bW4tY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBcbiAgUGFnaW5hdGlvblN0YXRlLCBcbiAgU29ydERpcmVjdGlvbiwgXG4gIEZpbHRlck9wZXJhdG9yLFxuICBUYWJsZVN0YXRlQ2hhbmdlRXZlbnQsXG4gIFRhYmxlU3RhdGVTbmFwc2hvdCxcbiAgQ2VsbEZvY3VzUG9zaXRpb25cbn0gZnJvbSAnLi90YWJsZS10eXBlcyc7XG5pbXBvcnQgeyBUYWJsZVN0YXRlQ29uZmlnIH0gZnJvbSAnLi90YWJsZS1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTmF2aWdhdGlvbkRpcmVjdGlvbiB9IGZyb20gJy4uLy4uL21vZGVscy9jZWxsLXR5cGVzJztcbmltcG9ydCB7IFJvd1ZhbGlkYXRpb25TdGF0ZSB9IGZyb20gJy4vcm93LXZhbGlkYXRpb24tc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRhYmxlVmFsaWRhdGlvblN0YXRlIH0gZnJvbSAnLi90YWJsZS12YWxpZGF0aW9uLXN0YXRlLmludGVyZmFjZSc7XG5cbi8qKlxuICogVGFibGVTdGF0ZSBjbGFzcyAtIENvbHVtbi1kcml2ZW4sIGV2ZW50LWVtaXR0aW5nIHN0YXRlIG1hbmFnZW1lbnRcbiAqIE5PIGRhdGEgbWFuaXB1bGF0aW9uIC0gb25seSBzdGF0ZSB0cmFja2luZyBhbmQgZXZlbnQgZW1pc3Npb25cbiAqL1xuZXhwb3J0IGNsYXNzIFRhYmxlU3RhdGUge1xuICAvLyBSZWZlcmVuY2UgdG8gY29sdW1ucyBhcnJheSAoY29sdW1uLWRyaXZlbiBhcmNoaXRlY3R1cmUpXG4gIHByaXZhdGUgX2NvbHVtbnM6IENvbHVtbkNvbmZpZzxhbnk+W107XG4gIFxuICAvLyBQYWdpbmF0aW9uIHN0YXRlXG4gIHByaXZhdGUgX3BhZ2luYXRpb24kOiBCZWhhdmlvclN1YmplY3Q8UGFnaW5hdGlvblN0YXRlPjtcbiAgXG4gIC8vIFN0YXRlIGNoYW5nZSBldmVudHNcbiAgcHJpdmF0ZSBfc3RhdGVDaGFuZ2UkOiBTdWJqZWN0PFRhYmxlU3RhdGVDaGFuZ2VFdmVudD47XG4gIFxuICAvLyBJbml0aWFsIGNvbmZpZ3VyYXRpb25cbiAgcHJpdmF0ZSBfaW5pdGlhbENvbmZpZzogVGFibGVTdGF0ZUNvbmZpZztcbiAgXG4gIC8vIFJvdyBudW1iZXIgY29sdW1uIHdpZHRoIGZvciBzdGlja3kgb2Zmc2V0IGNhbGN1bGF0aW9uXG4gIHByaXZhdGUgX3Jvd051bWJlcldpZHRoOiBudW1iZXIgPSAwO1xuXG4gIC8vIFNldHRpbmdzIGNvbHVtbiB3aWR0aCBmb3Igc3RpY2t5IG9mZnNldCBjYWxjdWxhdGlvblxuICBwcml2YXRlIF9zZXR0aW5nc0NvbHVtbldpZHRoOiBudW1iZXIgPSAwO1xuICBcbiAgLy8gRm9jdXMgcG9zaXRpb24gdHJhY2tpbmdcbiAgcHJpdmF0ZSBfZm9jdXNlZENlbGxQb3NpdGlvbiQ6IEJlaGF2aW9yU3ViamVjdDxDZWxsRm9jdXNQb3NpdGlvbiB8IG51bGw+O1xuICBwdWJsaWMgcmVhZG9ubHkgZm9jdXNlZENlbGxQb3NpdGlvbiQ6IE9ic2VydmFibGU8Q2VsbEZvY3VzUG9zaXRpb24gfCBudWxsPjtcbiAgXG4gIC8vIEVkaXRpbmcgcG9zaXRpb24gdHJhY2tpbmdcbiAgcHJpdmF0ZSBfZWRpdGluZ0NlbGxQb3NpdGlvbiQ6IEJlaGF2aW9yU3ViamVjdDxDZWxsRm9jdXNQb3NpdGlvbiB8IG51bGw+O1xuICBwdWJsaWMgcmVhZG9ubHkgZWRpdGluZ0NlbGxQb3NpdGlvbiQ6IE9ic2VydmFibGU8Q2VsbEZvY3VzUG9zaXRpb24gfCBudWxsPjtcbiAgXG4gIC8vIFZhbGlkYXRpb24gc3RhdGUgdHJhY2tpbmdcbiAgcHJpdmF0ZSBfdGFibGVWYWxpZGF0aW9uU3RhdGUkOiBCZWhhdmlvclN1YmplY3Q8VGFibGVWYWxpZGF0aW9uU3RhdGU+O1xuICBwdWJsaWMgcmVhZG9ubHkgdGFibGVWYWxpZGF0aW9uU3RhdGUkOiBPYnNlcnZhYmxlPFRhYmxlVmFsaWRhdGlvblN0YXRlPjtcbiAgXG4gIC8vIFJlcXVlc3QgdG8gYWRkIGEgbmV3IHJvdyAoZW1pdHRlZCB3aGVuIG5hdmlnYXRpbmcgcGFzdCBsYXN0IHJvdylcbiAgcHJpdmF0ZSBfcmVxdWVzdEFkZFJvdyQ6IFN1YmplY3Q8eyBmb2N1c0NvbHVtbjogbnVtYmVyIH0+O1xuICBwdWJsaWMgcmVhZG9ubHkgcmVxdWVzdEFkZFJvdyQ6IE9ic2VydmFibGU8eyBmb2N1c0NvbHVtbjogbnVtYmVyIH0+O1xuICBcbiAgLy8gUGVuZGluZyBmb2N1cyBwb3NpdGlvbiBhZnRlciBhIG5ldyByb3cgaXMgYWRkZWRcbiAgLy8gU2V0IHdoZW4gcmVxdWVzdEFkZFJvdyBpcyBlbWl0dGVkLCBjbGVhcmVkIHdoZW4gZm9jdXMgaXMgYXBwbGllZFxuICBwcml2YXRlIF9wZW5kaW5nRm9jdXNBZnRlclJvd0FkZDogeyBjb2x1bW5JbmRleDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgXG4gIC8vIERpbWVuc2lvbnMgZm9yIGJvdW5kYXJ5IGNoZWNraW5nXG4gIHByaXZhdGUgX3Jvd0NvdW50OiBudW1iZXIgPSAwO1xuICBwcml2YXRlIF9jb2x1bW5Db3VudDogbnVtYmVyID0gMDtcblxuICAvKipcbiAgICogT2JzZXJ2YWJsZSBvZiBjb21wbGV0ZSBzdGF0ZSBzbmFwc2hvdFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHN0YXRlJDogT2JzZXJ2YWJsZTxUYWJsZVN0YXRlU25hcHNob3Q+O1xuXG4gIC8qKlxuICAgKiBPYnNlcnZhYmxlIG9mIHN0YXRlIGNoYW5nZSBldmVudHNcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzdGF0ZUNoYW5nZSQ6IE9ic2VydmFibGU8VGFibGVTdGF0ZUNoYW5nZUV2ZW50PjtcblxuICAvKipcbiAgICogT2JzZXJ2YWJsZSBvZiBwYWdpbmF0aW9uIHN0YXRlIGNoYW5nZXNcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwYWdpbmF0aW9uQ2hhbmdlJDogT2JzZXJ2YWJsZTxQYWdpbmF0aW9uU3RhdGU+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0gY29sdW1ucyBSZWZlcmVuY2UgdG8gY29sdW1ucyBhcnJheVxuICAgKiBAcGFyYW0gY29uZmlnIEluaXRpYWwgY29uZmlndXJhdGlvblxuICAgKi9cbiAgY29uc3RydWN0b3IoY29sdW1uczogQ29sdW1uQ29uZmlnPGFueT5bXSwgY29uZmlnPzogVGFibGVTdGF0ZUNvbmZpZykge1xuICAgIHRoaXMuX2NvbHVtbnMgPSBjb2x1bW5zO1xuICAgIHRoaXMuX2luaXRpYWxDb25maWcgPSB7XG4gICAgICBpbml0aWFsUGFnZTogY29uZmlnPy5pbml0aWFsUGFnZSA/PyAwLFxuICAgICAgcGFnZVNpemU6IGNvbmZpZz8ucGFnZVNpemUgPz8gMjVcbiAgICB9O1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBwYWdpbmF0aW9uIHN0YXRlXG4gICAgdGhpcy5fcGFnaW5hdGlvbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFBhZ2luYXRpb25TdGF0ZT4oe1xuICAgICAgY3VycmVudFBhZ2U6IHRoaXMuX2luaXRpYWxDb25maWcuaW5pdGlhbFBhZ2UhLFxuICAgICAgcGFnZVNpemU6IHRoaXMuX2luaXRpYWxDb25maWcucGFnZVNpemUhLFxuICAgICAgdG90YWxJdGVtczogMCxcbiAgICAgIHRvdGFsUGFnZXM6IDBcbiAgICB9KTtcblxuICAgIC8vIEluaXRpYWxpemUgc3RhdGUgY2hhbmdlIHN1YmplY3RcbiAgICB0aGlzLl9zdGF0ZUNoYW5nZSQgPSBuZXcgU3ViamVjdDxUYWJsZVN0YXRlQ2hhbmdlRXZlbnQ+KCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSBmb2N1cyBhbmQgZWRpdGluZyBwb3NpdGlvbiB0cmFja2luZ1xuICAgIHRoaXMuX2ZvY3VzZWRDZWxsUG9zaXRpb24kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDZWxsRm9jdXNQb3NpdGlvbiB8IG51bGw+KG51bGwpO1xuICAgIHRoaXMuZm9jdXNlZENlbGxQb3NpdGlvbiQgPSB0aGlzLl9mb2N1c2VkQ2VsbFBvc2l0aW9uJC5hc09ic2VydmFibGUoKTtcbiAgICBcbiAgICB0aGlzLl9lZGl0aW5nQ2VsbFBvc2l0aW9uJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Q2VsbEZvY3VzUG9zaXRpb24gfCBudWxsPihudWxsKTtcbiAgICB0aGlzLmVkaXRpbmdDZWxsUG9zaXRpb24kID0gdGhpcy5fZWRpdGluZ0NlbGxQb3NpdGlvbiQuYXNPYnNlcnZhYmxlKCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSB2YWxpZGF0aW9uIHN0YXRlXG4gICAgdGhpcy5fdGFibGVWYWxpZGF0aW9uU3RhdGUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUYWJsZVZhbGlkYXRpb25TdGF0ZT4oe1xuICAgICAgaXNWYWxpZDogdHJ1ZSxcbiAgICAgIHRvdGFsUm93czogMCxcbiAgICAgIHZhbGlkUm93czogMCxcbiAgICAgIGludmFsaWRSb3dzOiAwLFxuICAgICAgcm93U3RhdGVzOiBuZXcgTWFwKCksXG4gICAgICBsYXN0VXBkYXRlZDogbmV3IERhdGUoKVxuICAgIH0pO1xuICAgIHRoaXMudGFibGVWYWxpZGF0aW9uU3RhdGUkID0gdGhpcy5fdGFibGVWYWxpZGF0aW9uU3RhdGUkLmFzT2JzZXJ2YWJsZSgpO1xuICAgIFxuICAgIC8vIEluaXRpYWxpemUgcmVxdWVzdCBhZGQgcm93IHN1YmplY3RcbiAgICB0aGlzLl9yZXF1ZXN0QWRkUm93JCA9IG5ldyBTdWJqZWN0PHsgZm9jdXNDb2x1bW46IG51bWJlciB9PigpO1xuICAgIHRoaXMucmVxdWVzdEFkZFJvdyQgPSB0aGlzLl9yZXF1ZXN0QWRkUm93JC5hc09ic2VydmFibGUoKTtcbiAgICBcbiAgICB0aGlzLl9jb2x1bW5Db3VudCA9IGNvbHVtbnMuZmlsdGVyKGMgPT4gYy52aXNpYmxlICE9PSBmYWxzZSkubGVuZ3RoO1xuXG4gICAgLy8gU2V0dXAgb2JzZXJ2YWJsZXNcbiAgICB0aGlzLnBhZ2luYXRpb25DaGFuZ2UkID0gdGhpcy5fcGFnaW5hdGlvbiQuYXNPYnNlcnZhYmxlKCkucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKChhLCBiKSA9PiBcbiAgICAgICAgYS5jdXJyZW50UGFnZSA9PT0gYi5jdXJyZW50UGFnZSAmJiBcbiAgICAgICAgYS5wYWdlU2l6ZSA9PT0gYi5wYWdlU2l6ZSAmJlxuICAgICAgICBhLnRvdGFsSXRlbXMgPT09IGIudG90YWxJdGVtc1xuICAgICAgKVxuICAgICk7XG5cbiAgICB0aGlzLnN0YXRlJCA9IHRoaXMuX3BhZ2luYXRpb24kLnBpcGUoXG4gICAgICBtYXAoKCkgPT4gdGhpcy5idWlsZFN0YXRlU25hcHNob3QoKSlcbiAgICApO1xuXG4gICAgdGhpcy5zdGF0ZUNoYW5nZSQgPSB0aGlzLl9zdGF0ZUNoYW5nZSQuYXNPYnNlcnZhYmxlKCk7XG4gICAgXG4gICAgLy8gQ2xlYXIgZm9jdXMvZWRpdGluZyBvbiBwYWdpbmF0aW9uIGNoYW5nZXNcbiAgICB0aGlzLnBhZ2luYXRpb25DaGFuZ2UkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmNsZWFyRm9jdXMoKTtcbiAgICAgIHRoaXMuY2xlYXJFZGl0aW5nQ2VsbCgpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBTVEFURSBBQ0NFU1MgTUVUSE9EU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHN0YXRlIHNuYXBzaG90XG4gICAqL1xuICBnZXRTdGF0ZSgpOiBUYWJsZVN0YXRlU25hcHNob3Qge1xuICAgIHJldHVybiB0aGlzLmJ1aWxkU3RhdGVTbmFwc2hvdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHBhZ2luYXRpb24gc3RhdGVcbiAgICovXG4gIGdldFBhZ2luYXRpb24oKTogUGFnaW5hdGlvblN0YXRlIHtcbiAgICByZXR1cm4geyAuLi50aGlzLl9wYWdpbmF0aW9uJC52YWx1ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjb2x1bW5zIHdpdGggc29ydGluZyBlbmFibGVkXG4gICAqL1xuICBnZXRTb3J0ZWRDb2x1bW5zKCk6IENvbHVtbkNvbmZpZzxhbnk+W10ge1xuICAgIHJldHVybiB0aGlzLl9jb2x1bW5zLmZpbHRlcihjb2wgPT4gY29sLnNvcnRFbmFibGVkID09PSB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY29sdW1ucyB3aXRoIGZpbHRlcmluZyBlbmFibGVkXG4gICAqL1xuICBnZXRGaWx0ZXJlZENvbHVtbnMoKTogQ29sdW1uQ29uZmlnPGFueT5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbHVtbnMuZmlsdGVyKGNvbCA9PiBjb2wuZmlsdGVyQ29uZmlnPy5lbmFibGVkID09PSB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBjb2x1bW5zIHJlZmVyZW5jZVxuICAgKi9cbiAgZ2V0Q29sdW1ucygpOiBDb2x1bW5Db25maWc8YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1ucztcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gUEFHSU5BVElPTiBNRVRIT0RTXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogU2V0IGN1cnJlbnQgcGFnZVxuICAgKiBAcGFyYW0gcGFnZSBQYWdlIG51bWJlciAoMC1pbmRleGVkKVxuICAgKi9cbiAgc2V0UGFnZShwYWdlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB0aGlzLl9wYWdpbmF0aW9uJC52YWx1ZTtcbiAgICBpZiAocGFnZSA8IDAgfHwgcGFnZSA+PSBjdXJyZW50U3RhdGUudG90YWxQYWdlcykge1xuICAgICAgY29uc29sZS53YXJuKGBJbnZhbGlkIHBhZ2UgbnVtYmVyOiAke3BhZ2V9LiBWYWxpZCByYW5nZTogMC0ke2N1cnJlbnRTdGF0ZS50b3RhbFBhZ2VzIC0gMX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9wYWdpbmF0aW9uJC5uZXh0KHtcbiAgICAgIC4uLmN1cnJlbnRTdGF0ZSxcbiAgICAgIGN1cnJlbnRQYWdlOiBwYWdlXG4gICAgfSk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ3BhZ2luYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgcGFnZSBzaXplXG4gICAqIEBwYXJhbSBzaXplIE51bWJlciBvZiBpdGVtcyBwZXIgcGFnZVxuICAgKi9cbiAgc2V0UGFnZVNpemUoc2l6ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHNpemUgPD0gMCkge1xuICAgICAgY29uc29sZS53YXJuKGBJbnZhbGlkIHBhZ2Ugc2l6ZTogJHtzaXplfS4gTXVzdCBiZSBncmVhdGVyIHRoYW4gMC5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB0aGlzLl9wYWdpbmF0aW9uJC52YWx1ZTtcbiAgICBjb25zdCBuZXdUb3RhbFBhZ2VzID0gdGhpcy5jYWxjdWxhdGVUb3RhbFBhZ2VzKGN1cnJlbnRTdGF0ZS50b3RhbEl0ZW1zLCBzaXplKTtcbiAgICBcbiAgICB0aGlzLl9wYWdpbmF0aW9uJC5uZXh0KHtcbiAgICAgIGN1cnJlbnRQYWdlOiAwLCAvLyBSZXNldCB0byBmaXJzdCBwYWdlXG4gICAgICBwYWdlU2l6ZTogc2l6ZSxcbiAgICAgIHRvdGFsSXRlbXM6IGN1cnJlbnRTdGF0ZS50b3RhbEl0ZW1zLFxuICAgICAgdG90YWxQYWdlczogbmV3VG90YWxQYWdlc1xuICAgIH0pO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdwYWdpbmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRvdGFsIGl0ZW1zIChjYWxsZWQgYWZ0ZXIgQVBJIHJlc3BvbnNlKVxuICAgKiBAcGFyYW0gdG90YWwgVG90YWwgbnVtYmVyIG9mIGl0ZW1zXG4gICAqL1xuICBzZXRUb3RhbEl0ZW1zKHRvdGFsOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB0aGlzLl9wYWdpbmF0aW9uJC52YWx1ZTtcbiAgICBjb25zdCBuZXdUb3RhbFBhZ2VzID0gdGhpcy5jYWxjdWxhdGVUb3RhbFBhZ2VzKHRvdGFsLCBjdXJyZW50U3RhdGUucGFnZVNpemUpO1xuICAgIFxuICAgIHRoaXMuX3BhZ2luYXRpb24kLm5leHQoe1xuICAgICAgLi4uY3VycmVudFN0YXRlLFxuICAgICAgdG90YWxJdGVtczogdG90YWwsXG4gICAgICB0b3RhbFBhZ2VzOiBuZXdUb3RhbFBhZ2VzXG4gICAgfSk7XG4gICAgLy8gRG9uJ3QgZW1pdCBzdGF0ZSBjaGFuZ2UgaGVyZSAtIHRoaXMgaXMgY2FsbGVkIGFmdGVyIGRhdGEgbG9hZFxuICB9XG5cbiAgLyoqXG4gICAqIEdvIHRvIG5leHQgcGFnZVxuICAgKi9cbiAgbmV4dFBhZ2UoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5fcGFnaW5hdGlvbiQudmFsdWU7XG4gICAgaWYgKHRoaXMuaGFzTmV4dFBhZ2UoKSkge1xuICAgICAgdGhpcy5zZXRQYWdlKGN1cnJlbnRTdGF0ZS5jdXJyZW50UGFnZSArIDEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHbyB0byBwcmV2aW91cyBwYWdlXG4gICAqL1xuICBwcmV2aW91c1BhZ2UoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5fcGFnaW5hdGlvbiQudmFsdWU7XG4gICAgaWYgKHRoaXMuaGFzUHJldmlvdXNQYWdlKCkpIHtcbiAgICAgIHRoaXMuc2V0UGFnZShjdXJyZW50U3RhdGUuY3VycmVudFBhZ2UgLSAxKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR28gdG8gZmlyc3QgcGFnZVxuICAgKi9cbiAgZmlyc3RQYWdlKCk6IHZvaWQge1xuICAgIHRoaXMuc2V0UGFnZSgwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHbyB0byBsYXN0IHBhZ2VcbiAgICovXG4gIGxhc3RQYWdlKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuX3BhZ2luYXRpb24kLnZhbHVlO1xuICAgIGlmIChjdXJyZW50U3RhdGUudG90YWxQYWdlcyA+IDApIHtcbiAgICAgIHRoaXMuc2V0UGFnZShjdXJyZW50U3RhdGUudG90YWxQYWdlcyAtIDEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGVyZSBpcyBhIG5leHQgcGFnZVxuICAgKi9cbiAgaGFzTmV4dFBhZ2UoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5fcGFnaW5hdGlvbiQudmFsdWU7XG4gICAgcmV0dXJuIGN1cnJlbnRTdGF0ZS5jdXJyZW50UGFnZSA8IGN1cnJlbnRTdGF0ZS50b3RhbFBhZ2VzIC0gMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGVyZSBpcyBhIHByZXZpb3VzIHBhZ2VcbiAgICovXG4gIGhhc1ByZXZpb3VzUGFnZSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB0aGlzLl9wYWdpbmF0aW9uJC52YWx1ZTtcbiAgICByZXR1cm4gY3VycmVudFN0YXRlLmN1cnJlbnRQYWdlID4gMDtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU09SVElORyBNRVRIT0RTIChvcGVyYXRlIG9uIGNvbHVtbiBjb25maWdzKVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIFNldCBzb3J0IG9uIGEgY29sdW1uIChjbGVhcnMgb3RoZXIgc29ydHMpXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcGFyYW0gZGlyZWN0aW9uIFNvcnQgZGlyZWN0aW9uXG4gICAqL1xuICBzZXRTb3J0T25Db2x1bW4oY29sdW1uS2V5OiBzdHJpbmcsIGRpcmVjdGlvbjogU29ydERpcmVjdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xuICAgIGlmICghY29sdW1uKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiBub3QgZm91bmQ6ICR7Y29sdW1uS2V5fWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjb2x1bW4uc29ydGFibGUgPT09IGZhbHNlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiAke2NvbHVtbktleX0gaXMgbm90IHNvcnRhYmxlYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgYWxsIG90aGVyIHNvcnRzXG4gICAgdGhpcy5fY29sdW1ucy5mb3JFYWNoKGNvbCA9PiB7XG4gICAgICBpZiAoY29sLmtleSAhPT0gY29sdW1uS2V5KSB7XG4gICAgICAgIGNvbC5zb3J0RGlyZWN0aW9uID0gU29ydERpcmVjdGlvbi5OT05FO1xuICAgICAgICBjb2wuc29ydEVuYWJsZWQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFNldCBzb3J0IG9uIHRhcmdldCBjb2x1bW5cbiAgICBjb2x1bW4uc29ydERpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICBjb2x1bW4uc29ydEVuYWJsZWQgPSBkaXJlY3Rpb24gIT09IFNvcnREaXJlY3Rpb24uTk9ORTtcblxuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdzb3J0aW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHNvcnQgdG8gYSBjb2x1bW4gKGZvciBtdWx0aS1jb2x1bW4gc29ydGluZylcbiAgICogQHBhcmFtIGNvbHVtbktleSBDb2x1bW4ga2V5XG4gICAqIEBwYXJhbSBkaXJlY3Rpb24gU29ydCBkaXJlY3Rpb25cbiAgICovXG4gIGFkZFNvcnRUb0NvbHVtbihjb2x1bW5LZXk6IHN0cmluZywgZGlyZWN0aW9uOiBTb3J0RGlyZWN0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uIG5vdCBmb3VuZDogJHtjb2x1bW5LZXl9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNvbHVtbi5zb3J0YWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uICR7Y29sdW1uS2V5fSBpcyBub3Qgc29ydGFibGVgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb2x1bW4uc29ydERpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICBjb2x1bW4uc29ydEVuYWJsZWQgPSBkaXJlY3Rpb24gIT09IFNvcnREaXJlY3Rpb24uTk9ORTtcblxuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdzb3J0aW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlIHNvcnQgb24gYSBjb2x1bW4gKGN5Y2xlcyB0aHJvdWdoIG5vbmUgLT4gYXNjIC0+IGRlc2MgLT4gbm9uZSlcbiAgICogQHBhcmFtIGNvbHVtbktleSBDb2x1bW4ga2V5XG4gICAqL1xuICB0b2dnbGVTb3J0T25Db2x1bW4oY29sdW1uS2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29sdW1uLnNvcnRhYmxlID09PSBmYWxzZSkge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gJHtjb2x1bW5LZXl9IGlzIG5vdCBzb3J0YWJsZWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnREaXJlY3Rpb24gPSBjb2x1bW4uc29ydERpcmVjdGlvbiB8fCBTb3J0RGlyZWN0aW9uLk5PTkU7XG4gICAgbGV0IG5ld0RpcmVjdGlvbjogU29ydERpcmVjdGlvbjtcblxuICAgIHN3aXRjaCAoY3VycmVudERpcmVjdGlvbikge1xuICAgICAgY2FzZSBTb3J0RGlyZWN0aW9uLk5PTkU6XG4gICAgICAgIG5ld0RpcmVjdGlvbiA9IFNvcnREaXJlY3Rpb24uQVNDO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgU29ydERpcmVjdGlvbi5BU0M6XG4gICAgICAgIG5ld0RpcmVjdGlvbiA9IFNvcnREaXJlY3Rpb24uREVTQztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFNvcnREaXJlY3Rpb24uREVTQzpcbiAgICAgICAgbmV3RGlyZWN0aW9uID0gU29ydERpcmVjdGlvbi5OT05FO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG5ld0RpcmVjdGlvbiA9IFNvcnREaXJlY3Rpb24uQVNDO1xuICAgIH1cblxuICAgIGNvbHVtbi5zb3J0RGlyZWN0aW9uID0gbmV3RGlyZWN0aW9uO1xuICAgIGNvbHVtbi5zb3J0RW5hYmxlZCA9IG5ld0RpcmVjdGlvbiAhPT0gU29ydERpcmVjdGlvbi5OT05FO1xuXG4gICAgdGhpcy5jbGVhckZvY3VzKCk7XG4gICAgdGhpcy5jbGVhckVkaXRpbmdDZWxsKCk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ3NvcnRpbmcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgc29ydGluZ1xuICAgKi9cbiAgY2xlYXJBbGxTb3J0aW5nKCk6IHZvaWQge1xuICAgIHRoaXMuX2NvbHVtbnMuZm9yRWFjaChjb2wgPT4ge1xuICAgICAgY29sLnNvcnREaXJlY3Rpb24gPSBTb3J0RGlyZWN0aW9uLk5PTkU7XG4gICAgICBjb2wuc29ydEVuYWJsZWQgPSBmYWxzZTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2xlYXJGb2N1cygpO1xuICAgIHRoaXMuY2xlYXJFZGl0aW5nQ2VsbCgpO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdzb3J0aW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHNvcnQgY29uZmlndXJhdGlvbiBmb3IgYSBjb2x1bW5cbiAgICogQHBhcmFtIGNvbHVtbktleSBDb2x1bW4ga2V5XG4gICAqIEByZXR1cm5zIFNvcnQgY29uZmlndXJhdGlvbiBvciBudWxsXG4gICAqL1xuICBnZXRTb3J0Rm9yQ29sdW1uKGNvbHVtbktleTogc3RyaW5nKTogeyBkaXJlY3Rpb246IFNvcnREaXJlY3Rpb247IGVuYWJsZWQ6IGJvb2xlYW4gfSB8IG51bGwge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xuICAgIGlmICghY29sdW1uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGlyZWN0aW9uOiBjb2x1bW4uc29ydERpcmVjdGlvbiB8fCBTb3J0RGlyZWN0aW9uLk5PTkUsXG4gICAgICBlbmFibGVkOiBjb2x1bW4uc29ydEVuYWJsZWQgfHwgZmFsc2VcbiAgICB9O1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBGSUxURVJJTkcgTUVUSE9EUyAob3BlcmF0ZSBvbiBjb2x1bW4gY29uZmlncylcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBTZXQgZmlsdGVyIG9uIGEgY29sdW1uXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcGFyYW0gb3BlcmF0b3IgRmlsdGVyIG9wZXJhdG9yXG4gICAqIEBwYXJhbSB2YWx1ZSBGaWx0ZXIgdmFsdWVcbiAgICovXG4gIHNldEZpbHRlck9uQ29sdW1uKGNvbHVtbktleTogc3RyaW5nLCBvcGVyYXRvcjogRmlsdGVyT3BlcmF0b3IsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29sdW1uLmZpbHRlcmFibGUgPT09IGZhbHNlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiAke2NvbHVtbktleX0gaXMgbm90IGZpbHRlcmFibGVgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsaXplIGZpbHRlckNvbmZpZyBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgaWYgKCFjb2x1bW4uZmlsdGVyQ29uZmlnKSB7XG4gICAgICBjb2x1bW4uZmlsdGVyQ29uZmlnID0ge307XG4gICAgfVxuXG4gICAgY29sdW1uLmZpbHRlckNvbmZpZy5vcGVyYXRvciA9IG9wZXJhdG9yO1xuICAgIGNvbHVtbi5maWx0ZXJDb25maWcudmFsdWUgPSB2YWx1ZTtcbiAgICBjb2x1bW4uZmlsdGVyQ29uZmlnLmVuYWJsZWQgPSB0cnVlO1xuXG4gICAgdGhpcy5jbGVhckZvY3VzKCk7XG4gICAgdGhpcy5jbGVhckVkaXRpbmdDZWxsKCk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ2ZpbHRlcmluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGZpbHRlciBvbiBhIGNvbHVtblxuICAgKiBAcGFyYW0gY29sdW1uS2V5IENvbHVtbiBrZXlcbiAgICovXG4gIGNsZWFyRmlsdGVyT25Db2x1bW4oY29sdW1uS2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsaXplIGZpbHRlckNvbmZpZyBpZiBpdCBkb2Vzbid0IGV4aXN0IChmb3IgY29uc2lzdGVuY3kgd2l0aCBzZXRGaWx0ZXJPbkNvbHVtbilcbiAgICBpZiAoIWNvbHVtbi5maWx0ZXJDb25maWcpIHtcbiAgICAgIGNvbHVtbi5maWx0ZXJDb25maWcgPSB7fTtcbiAgICB9XG5cbiAgICBjb2x1bW4uZmlsdGVyQ29uZmlnLnZhbHVlID0gdW5kZWZpbmVkO1xuICAgIGNvbHVtbi5maWx0ZXJDb25maWcuZW5hYmxlZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5jbGVhckZvY3VzKCk7XG4gICAgdGhpcy5jbGVhckVkaXRpbmdDZWxsKCk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ2ZpbHRlcmluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBmaWx0ZXJzXG4gICAqL1xuICBjbGVhckFsbEZpbHRlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5fY29sdW1ucy5mb3JFYWNoKGNvbCA9PiB7XG4gICAgICAvLyBJbml0aWFsaXplIGZpbHRlckNvbmZpZyBpZiBpdCBkb2Vzbid0IGV4aXN0IChmb3IgY29uc2lzdGVuY3kgd2l0aCBzZXRGaWx0ZXJPbkNvbHVtbilcbiAgICAgIGlmICghY29sLmZpbHRlckNvbmZpZykge1xuICAgICAgICBjb2wuZmlsdGVyQ29uZmlnID0ge307XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbC5maWx0ZXJDb25maWcudmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICBjb2wuZmlsdGVyQ29uZmlnLmVuYWJsZWQgPSBmYWxzZTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2xlYXJGb2N1cygpO1xuICAgIHRoaXMuY2xlYXJFZGl0aW5nQ2VsbCgpO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdmaWx0ZXJpbmcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgZmlsdGVyIGVuYWJsZWQgc3RhdGVcbiAgICogQHBhcmFtIGNvbHVtbktleSBDb2x1bW4ga2V5XG4gICAqIEBwYXJhbSBlbmFibGVkIFdoZXRoZXIgZmlsdGVyIGlzIGVuYWJsZWRcbiAgICovXG4gIHNldEZpbHRlckVuYWJsZWQoY29sdW1uS2V5OiBzdHJpbmcsIGVuYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsaXplIGZpbHRlckNvbmZpZyBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgaWYgKCFjb2x1bW4uZmlsdGVyQ29uZmlnKSB7XG4gICAgICBjb2x1bW4uZmlsdGVyQ29uZmlnID0ge307XG4gICAgfVxuXG4gICAgY29sdW1uLmZpbHRlckNvbmZpZy5lbmFibGVkID0gZW5hYmxlZDtcblxuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdmaWx0ZXJpbmcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZmlsdGVyIGNvbmZpZ3VyYXRpb24gZm9yIGEgY29sdW1uXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcmV0dXJucyBGaWx0ZXIgY29uZmlndXJhdGlvbiBvciBudWxsXG4gICAqL1xuICBnZXRGaWx0ZXJGb3JDb2x1bW4oY29sdW1uS2V5OiBzdHJpbmcpOiB7IG9wZXJhdG9yOiBGaWx0ZXJPcGVyYXRvcjsgdmFsdWU6IGFueTsgZW5hYmxlZDogYm9vbGVhbiB9IHwgbnVsbCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBvcGVyYXRvcjogY29sdW1uLmZpbHRlckNvbmZpZz8ub3BlcmF0b3IgfHwgRmlsdGVyT3BlcmF0b3IuQ09OVEFJTlMsXG4gICAgICB2YWx1ZTogY29sdW1uLmZpbHRlckNvbmZpZz8udmFsdWUsXG4gICAgICBlbmFibGVkOiBjb2x1bW4uZmlsdGVyQ29uZmlnPy5lbmFibGVkIHx8IGZhbHNlXG4gICAgfTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU1RJQ0tZIENPTFVNTiBNQU5BR0VNRU5UXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogR2V0IHN0aWNreSBjb2x1bW5zIGdyb3VwZWQgYnkgcG9zaXRpb25cbiAgICogQHJldHVybnMgT2JqZWN0IHdpdGggbGVmdCBhbmQgcmlnaHQgc3RpY2t5IGNvbHVtbiBrZXlzXG4gICAqL1xuICBnZXRTdGlja3lDb2x1bW5zKCk6IHsgbGVmdDogc3RyaW5nW107IHJpZ2h0OiBzdHJpbmdbXSB9IHtcbiAgICBjb25zdCBsZWZ0ID0gdGhpcy5fY29sdW1uc1xuICAgICAgLmZpbHRlcihjb2wgPT4gY29sLnN0aWNreSA9PT0gJ2xlZnQnKVxuICAgICAgLm1hcChjb2wgPT4gY29sLmtleSk7XG4gICAgXG4gICAgY29uc3QgcmlnaHQgPSB0aGlzLl9jb2x1bW5zXG4gICAgICAuZmlsdGVyKGNvbCA9PiBjb2wuc3RpY2t5ID09PSAncmlnaHQnKVxuICAgICAgLm1hcChjb2wgPT4gY29sLmtleSk7XG4gICAgXG4gICAgcmV0dXJuIHsgbGVmdCwgcmlnaHQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgc3RpY2t5IHBvc2l0aW9uIGZvciBhIGNvbHVtblxuICAgKiBAcGFyYW0gY29sdW1uS2V5IENvbHVtbiBrZXlcbiAgICogQHBhcmFtIHBvc2l0aW9uIFN0aWNreSBwb3NpdGlvbiAoJ2xlZnQnLCAncmlnaHQnLCBvciBmYWxzZSlcbiAgICovXG4gIHNldFN0aWNreUNvbHVtbihjb2x1bW5LZXk6IHN0cmluZywgcG9zaXRpb246ICdsZWZ0JyB8ICdyaWdodCcgfCBmYWxzZSk6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xuICAgIGlmICghY29sdW1uKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiBub3QgZm91bmQ6ICR7Y29sdW1uS2V5fWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIChjb2x1bW4gYXMgYW55KS5zdGlja3kgPSBwb3NpdGlvbjtcbiAgICB0aGlzLmNhbGN1bGF0ZVN0aWNreU9mZnNldHMoKTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY29sdW1uLWNvbmZpZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBzdGlja3kgb2Zmc2V0cyBmb3IgYWxsIHN0aWNreSBjb2x1bW5zXG4gICAqIFRoaXMgY2FsY3VsYXRlcyBjdW11bGF0aXZlIHdpZHRocyBmb3IgcG9zaXRpb25pbmdcbiAgICogQHBhcmFtIHJvd051bWJlcldpZHRoIE9wdGlvbmFsIHdpZHRoIG9mIHJvdyBudW1iZXIgY29sdW1uIHRvIGFjY291bnQgZm9yIGluIGxlZnQgb2Zmc2V0XG4gICAqIEBwYXJhbSBzZXR0aW5nc0NvbHVtbldpZHRoIE9wdGlvbmFsIHdpZHRoIG9mIHNldHRpbmdzIGNvbHVtbiB0byBhY2NvdW50IGZvciBpbiByaWdodCBvZmZzZXRcbiAgICovXG4gIGNhbGN1bGF0ZVN0aWNreU9mZnNldHMocm93TnVtYmVyV2lkdGg/OiBudW1iZXIsIHNldHRpbmdzQ29sdW1uV2lkdGg/OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBVcGRhdGUgc3RvcmVkIHJvdyBudW1iZXIgd2lkdGggaWYgcHJvdmlkZWRcbiAgICBpZiAocm93TnVtYmVyV2lkdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fcm93TnVtYmVyV2lkdGggPSByb3dOdW1iZXJXaWR0aDtcbiAgICB9XG4gICAgXG4gICAgLy8gVXBkYXRlIHN0b3JlZCBzZXR0aW5ncyBjb2x1bW4gd2lkdGggaWYgcHJvdmlkZWRcbiAgICBpZiAoc2V0dGluZ3NDb2x1bW5XaWR0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLl9zZXR0aW5nc0NvbHVtbldpZHRoID0gc2V0dGluZ3NDb2x1bW5XaWR0aDtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2FsY3VsYXRlIGxlZnQgc3RpY2t5IG9mZnNldHNcbiAgICAvLyBBY2NvdW50IGZvciByb3cgbnVtYmVyIGNvbHVtbiB3aWR0aFxuICAgIGxldCBsZWZ0T2Zmc2V0ID0gdGhpcy5fcm93TnVtYmVyV2lkdGg7XG4gICAgdGhpcy5fY29sdW1ucy5mb3JFYWNoKGNvbCA9PiB7XG4gICAgICBpZiAoY29sLnN0aWNreSA9PT0gJ2xlZnQnKSB7XG4gICAgICAgIChjb2wgYXMgYW55KS5zdGlja3lPZmZzZXQgPSBsZWZ0T2Zmc2V0O1xuICAgICAgICBsZWZ0T2Zmc2V0ICs9IChjb2wud2lkdGggYXMgbnVtYmVyKSB8fCAxMDA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBDYWxjdWxhdGUgcmlnaHQgc3RpY2t5IG9mZnNldHNcbiAgICAvLyBBY2NvdW50IGZvciBzZXR0aW5ncyBjb2x1bW4gd2lkdGggKHJvdyBhY3Rpb25zIGNvbHVtbilcbiAgICBsZXQgcmlnaHRPZmZzZXQgPSB0aGlzLl9zZXR0aW5nc0NvbHVtbldpZHRoO1xuICAgIGZvciAobGV0IGkgPSB0aGlzLl9jb2x1bW5zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBjb25zdCBjb2wgPSB0aGlzLl9jb2x1bW5zW2ldO1xuICAgICAgaWYgKGNvbC5zdGlja3kgPT09ICdyaWdodCcpIHtcbiAgICAgICAgKGNvbCBhcyBhbnkpLnN0aWNreU9mZnNldCA9IHJpZ2h0T2Zmc2V0O1xuICAgICAgICByaWdodE9mZnNldCArPSAoY29sLndpZHRoIGFzIG51bWJlcikgfHwgMTAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gQ09MVU1OIE1BTkFHRU1FTlRcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgY29sdW1ucyByZWZlcmVuY2VcbiAgICogQHBhcmFtIGNvbHVtbnMgTmV3IGNvbHVtbnMgYXJyYXlcbiAgICovXG4gIHVwZGF0ZUNvbHVtbnMoY29sdW1uczogQ29sdW1uQ29uZmlnPGFueT5bXSk6IHZvaWQge1xuICAgIHRoaXMuX2NvbHVtbnMgPSBjb2x1bW5zO1xuICAgIHRoaXMuY2FsY3VsYXRlU3RpY2t5T2Zmc2V0cygpO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdjb2x1bW4tY29uZmlnJyk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIENPTFVNTiBWSVNJQklMSVRZIE1FVEhPRFNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBUb2dnbGUgdmlzaWJpbGl0eSBvZiBhIGNvbHVtblxuICAgKiBAcGFyYW0gY29sdW1uS2V5IENvbHVtbiBrZXlcbiAgICovXG4gIHRvZ2dsZUNvbHVtblZpc2liaWxpdHkoY29sdW1uS2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBjb2x1bW4gaXMgaGlkZWFibGVcbiAgICBpZiAoY29sdW1uLmhpZGVhYmxlID09PSBmYWxzZSkge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gJHtjb2x1bW5LZXl9IGNhbm5vdCBiZSBoaWRkZW4gKGhpZGVhYmxlIGlzIGZhbHNlKWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRWaXNpYmlsaXR5ID0gY29sdW1uLnZpc2libGUgIT09IGZhbHNlOyAvLyBEZWZhdWx0IHRvIHRydWUgaWYgbm90IHNldFxuICAgIChjb2x1bW4gYXMgYW55KS52aXNpYmxlID0gIWN1cnJlbnRWaXNpYmlsaXR5O1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdjb2x1bW4tdmlzaWJpbGl0eScpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB2aXNpYmlsaXR5IG9mIGEgY29sdW1uXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcGFyYW0gdmlzaWJsZSBXaGV0aGVyIGNvbHVtbiBzaG91bGQgYmUgdmlzaWJsZVxuICAgKi9cbiAgc2V0Q29sdW1uVmlzaWJpbGl0eShjb2x1bW5LZXk6IHN0cmluZywgdmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xuICAgIGlmICghY29sdW1uKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiBub3QgZm91bmQ6ICR7Y29sdW1uS2V5fWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGNvbHVtbiBpcyBoaWRlYWJsZSAob25seSB3aGVuIHRyeWluZyB0byBoaWRlKVxuICAgIGlmICghdmlzaWJsZSAmJiBjb2x1bW4uaGlkZWFibGUgPT09IGZhbHNlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiAke2NvbHVtbktleX0gY2Fubm90IGJlIGhpZGRlbiAoaGlkZWFibGUgaXMgZmFsc2UpYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgKGNvbHVtbiBhcyBhbnkpLnZpc2libGUgPSB2aXNpYmxlO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdjb2x1bW4tdmlzaWJpbGl0eScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgdmlzaWJsZSBjb2x1bW5zXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIHZpc2libGUgY29sdW1uIGNvbmZpZ3NcbiAgICovXG4gIGdldFZpc2libGVDb2x1bW5zKCk6IENvbHVtbkNvbmZpZzxhbnk+W10ge1xuICAgIHJldHVybiB0aGlzLl9jb2x1bW5zLmZpbHRlcihjb2wgPT4gY29sLnZpc2libGUgIT09IGZhbHNlKTsgLy8gRGVmYXVsdCB0byB0cnVlIGlmIG5vdCBzZXRcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdmlzaWJpbGl0eSBzdGF0ZSBmb3IgYWxsIGNvbHVtbnNcbiAgICogQHJldHVybnMgQXJyYXkgb2YgY29sdW1uIHZpc2liaWxpdHkgaW5mb1xuICAgKi9cbiAgZ2V0QWxsQ29sdW1uc1Zpc2liaWxpdHkoKTogeyBrZXk6IHN0cmluZzsgaGVhZGVyOiBzdHJpbmc7IHZpc2libGU6IGJvb2xlYW47IGhpZGVhYmxlOiBib29sZWFuIH1bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbHVtbnMubWFwKGNvbCA9PiAoe1xuICAgICAga2V5OiBjb2wua2V5LFxuICAgICAgaGVhZGVyOiBjb2wuaGVhZGVyIHx8IGNvbC5rZXksXG4gICAgICB2aXNpYmxlOiBjb2wudmlzaWJsZSAhPT0gZmFsc2UsIC8vIERlZmF1bHQgdG8gdHJ1ZSBpZiBub3Qgc2V0XG4gICAgICBoaWRlYWJsZTogY29sLmhpZGVhYmxlICE9PSBmYWxzZSAvLyBEZWZhdWx0IHRvIHRydWUgaWYgbm90IHNldFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gS0VZQk9BUkQgTkFWSUdBVElPTiAmIEZPQ1VTIE1BTkFHRU1FTlRcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBTZXQgdGFibGUgZGltZW5zaW9ucyBmb3IgbmF2aWdhdGlvbiBib3VuZGFyaWVzXG4gICAqL1xuICBzZXREaW1lbnNpb25zKHJvd0NvdW50OiBudW1iZXIsIGNvbHVtbkNvdW50OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91c1Jvd0NvdW50ID0gdGhpcy5fcm93Q291bnQ7XG4gICAgdGhpcy5fcm93Q291bnQgPSByb3dDb3VudDtcbiAgICB0aGlzLl9jb2x1bW5Db3VudCA9IGNvbHVtbkNvdW50O1xuICAgIFxuICAgIC8vIFVwZGF0ZSB0b3RhbCByb3dzIGluIHZhbGlkYXRpb24gc3RhdGVcbiAgICB0aGlzLnNldFZhbGlkYXRpb25Sb3dDb3VudChyb3dDb3VudCk7XG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgYSBuZXcgcm93IHdhcyBhZGRlZCBhbmQgd2UgaGF2ZSBhIHBlbmRpbmcgZm9jdXNcbiAgICBpZiAodGhpcy5fcGVuZGluZ0ZvY3VzQWZ0ZXJSb3dBZGQgJiYgcm93Q291bnQgPiBwcmV2aW91c1Jvd0NvdW50KSB7XG4gICAgICBjb25zdCB7IGNvbHVtbkluZGV4IH0gPSB0aGlzLl9wZW5kaW5nRm9jdXNBZnRlclJvd0FkZDtcbiAgICAgIC8vIEZvY3VzIHRoZSBsYXN0IHJvdyAobmV3bHkgYWRkZWQpIGF0IHRoZSBwZW5kaW5nIGNvbHVtblxuICAgICAgY29uc3QgbmV3Um93SW5kZXggPSByb3dDb3VudCAtIDE7XG4gICAgICB0aGlzLl9wZW5kaW5nRm9jdXNBZnRlclJvd0FkZCA9IG51bGw7IC8vIENsZWFyIHBlbmRpbmcgZm9jdXNcbiAgICAgIFxuICAgICAgLy8gRGVsYXkgZm9jdXMgdG8gZW5zdXJlIERPTSBpcyB1cGRhdGVkXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5mb2N1c0NlbGwobmV3Um93SW5kZXgsIGNvbHVtbkluZGV4KTtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIEZvY3VzIGEgY2VsbCBieSBwb3NpdGlvblxuICAgKi9cbiAgZm9jdXNDZWxsKHJvd0luZGV4OiBudW1iZXIsIGNvbHVtbkluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAocm93SW5kZXggPCAwIHx8IHJvd0luZGV4ID49IHRoaXMuX3Jvd0NvdW50KSByZXR1cm47XG4gICAgaWYgKGNvbHVtbkluZGV4IDwgMCB8fCBjb2x1bW5JbmRleCA+PSB0aGlzLl9jb2x1bW5Db3VudCkgcmV0dXJuO1xuICAgIFxuICAgIHRoaXMuX2ZvY3VzZWRDZWxsUG9zaXRpb24kLm5leHQoeyByb3dJbmRleCwgY29sdW1uSW5kZXggfSk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ2NlbGwtZm9jdXMnKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjdXJyZW50bHkgZm9jdXNlZCBwb3NpdGlvblxuICAgKi9cbiAgZ2V0Rm9jdXNlZFBvc2l0aW9uKCk6IENlbGxGb2N1c1Bvc2l0aW9uIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2ZvY3VzZWRDZWxsUG9zaXRpb24kLnZhbHVlO1xuICB9XG4gIFxuICAvKipcbiAgICogTm90aWZ5IHRoYXQgYSBjZWxsIGVudGVyZWQgZWRpdCBtb2RlXG4gICAqL1xuICBzZXRFZGl0aW5nQ2VsbChyb3dJbmRleDogbnVtYmVyLCBjb2x1bW5JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5fZWRpdGluZ0NlbGxQb3NpdGlvbiQubmV4dCh7IHJvd0luZGV4LCBjb2x1bW5JbmRleCB9KTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY2VsbC1lZGl0LXN0YXJ0Jyk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBOb3RpZnkgdGhhdCBlZGl0IG1vZGUgZW5kZWRcbiAgICovXG4gIGNsZWFyRWRpdGluZ0NlbGwoKTogdm9pZCB7XG4gICAgdGhpcy5fZWRpdGluZ0NlbGxQb3NpdGlvbiQubmV4dChudWxsKTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY2VsbC1lZGl0LWVuZCcpO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgYW55IGNlbGwgaXMgY3VycmVudGx5IGVkaXRpbmdcbiAgICovXG4gIGlzQW55Q2VsbEVkaXRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VkaXRpbmdDZWxsUG9zaXRpb24kLnZhbHVlICE9PSBudWxsO1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IGN1cnJlbnRseSBlZGl0aW5nIHBvc2l0aW9uXG4gICAqL1xuICBnZXRFZGl0aW5nUG9zaXRpb24oKTogQ2VsbEZvY3VzUG9zaXRpb24gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fZWRpdGluZ0NlbGxQb3NpdGlvbiQudmFsdWU7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBNb3ZlIGZvY3VzIGluIGEgZGlyZWN0aW9uIHVzaW5nIE5hdmlnYXRpb25EaXJlY3Rpb24gZW51bVxuICAgKiBAcGFyYW0gZGlyZWN0aW9uIFRoZSBuYXZpZ2F0aW9uIGRpcmVjdGlvblxuICAgKiBAcGFyYW0gYWRkUm93T25OYXZpZ2F0ZVBhc3RFbmQgSWYgdHJ1ZSwgZW1pdHMgcmVxdWVzdEFkZFJvdyB3aGVuIG5hdmlnYXRpbmcgcGFzdCBsYXN0IHJvd1xuICAgKi9cbiAgbW92ZUZvY3VzKGRpcmVjdGlvbjogTmF2aWdhdGlvbkRpcmVjdGlvbiwgYWRkUm93T25OYXZpZ2F0ZVBhc3RFbmQ6IGJvb2xlYW4gPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgIC8vIEJsb2NrIG5hdmlnYXRpb24gaWYgYW55IGNlbGwgaXMgZWRpdGluZ1xuICAgIGlmICh0aGlzLmlzQW55Q2VsbEVkaXRpbmcoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5fZm9jdXNlZENlbGxQb3NpdGlvbiQudmFsdWU7XG4gICAgaWYgKCFjdXJyZW50KSByZXR1cm4gZmFsc2U7XG4gICAgXG4gICAgbGV0IG5ld1JvdyA9IGN1cnJlbnQucm93SW5kZXg7XG4gICAgbGV0IG5ld0NvbCA9IGN1cnJlbnQuY29sdW1uSW5kZXg7XG4gICAgXG4gICAgLy8gVXNlIE5hdmlnYXRpb25EaXJlY3Rpb24gZW51bSB2YWx1ZXNcbiAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgY2FzZSBOYXZpZ2F0aW9uRGlyZWN0aW9uLlVQOiBuZXdSb3ctLTsgYnJlYWs7XG4gICAgICBjYXNlIE5hdmlnYXRpb25EaXJlY3Rpb24uRE9XTjogbmV3Um93Kys7IGJyZWFrO1xuICAgICAgY2FzZSBOYXZpZ2F0aW9uRGlyZWN0aW9uLkxFRlQ6IG5ld0NvbC0tOyBicmVhaztcbiAgICAgIGNhc2UgTmF2aWdhdGlvbkRpcmVjdGlvbi5SSUdIVDogbmV3Q29sKys7IGJyZWFrO1xuICAgIH1cbiAgICBcbiAgICAvLyBDaGVjayBpZiBuYXZpZ2F0aW5nIHBhc3QgbGFzdCByb3cgKGFycm93IGRvd24gYXQgYm90dG9tKVxuICAgIGlmIChkaXJlY3Rpb24gPT09IE5hdmlnYXRpb25EaXJlY3Rpb24uRE9XTiAmJiBuZXdSb3cgPj0gdGhpcy5fcm93Q291bnQpIHtcbiAgICAgIGlmIChhZGRSb3dPbk5hdmlnYXRlUGFzdEVuZCkge1xuICAgICAgICAvLyBTdG9yZSBwZW5kaW5nIGZvY3VzIGZvciB3aGVuIHRoZSBuZXcgcm93IGlzIGFkZGVkXG4gICAgICAgIHRoaXMuX3BlbmRpbmdGb2N1c0FmdGVyUm93QWRkID0geyBjb2x1bW5JbmRleDogY3VycmVudC5jb2x1bW5JbmRleCB9O1xuICAgICAgICAvLyBFbWl0IHJlcXVlc3QgdG8gYWRkIGEgbmV3IHJvdywga2VlcGluZyB0aGUgc2FtZSBjb2x1bW4gZm9yIGZvY3VzXG4gICAgICAgIHRoaXMuX3JlcXVlc3RBZGRSb3ckLm5leHQoeyBmb2N1c0NvbHVtbjogY3VycmVudC5jb2x1bW5JbmRleCB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgXG4gICAgaWYgKG5ld1JvdyA8IDAgfHwgbmV3Um93ID49IHRoaXMuX3Jvd0NvdW50KSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKG5ld0NvbCA8IDAgfHwgbmV3Q29sID49IHRoaXMuX2NvbHVtbkNvdW50KSByZXR1cm4gZmFsc2U7XG4gICAgXG4gICAgdGhpcy5mb2N1c0NlbGwobmV3Um93LCBuZXdDb2wpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2xlYXIgZm9jdXNcbiAgICovXG4gIGNsZWFyRm9jdXMoKTogdm9pZCB7XG4gICAgdGhpcy5fZm9jdXNlZENlbGxQb3NpdGlvbiQubmV4dChudWxsKTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY2VsbC1mb2N1cycpO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgbmF2aWdhdGlvbiBpcyBhY3RpdmVcbiAgICovXG4gIGlzTmF2aWdhdGlvbkFjdGl2ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fZm9jdXNlZENlbGxQb3NpdGlvbiQudmFsdWUgIT09IG51bGw7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFZBTElEQVRJT04gU1RBVEUgTUVUSE9EU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIFxuICAvKipcbiAgICogVXBkYXRlIGNlbGwgdmFsaWRhdGlvbiBhbmQgYWNjdW11bGF0ZSBpbnRvIHJvdy90YWJsZSB2YWxpZGF0aW9uIHN0YXRlXG4gICAqIE9ubHkgc3RvcmVzIGludmFsaWQgc3RhdGVzIC0gdmFsaWQgcm93cyBhcmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAqL1xuICB1cGRhdGVDZWxsVmFsaWRhdGlvbihyb3dJbmRleDogbnVtYmVyLCBjb2x1bW5LZXk6IHN0cmluZywgaXNWYWxpZDogYm9vbGVhbiwgZXJyb3I/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQudmFsdWU7XG4gICAgY29uc3Qgcm93U3RhdGVzID0gbmV3IE1hcChjdXJyZW50U3RhdGUucm93U3RhdGVzKTtcbiAgICBcbiAgICAvLyBHZXQgZXhpc3Rpbmcgcm93IHN0YXRlIChvbmx5IGV4aXN0cyBpZiByb3cgaGFzIGVycm9ycylcbiAgICBsZXQgcm93U3RhdGUgPSByb3dTdGF0ZXMuZ2V0KHJvd0luZGV4KTtcbiAgICBcbiAgICBpZiAoIWlzVmFsaWQgJiYgZXJyb3IpIHtcbiAgICAgIC8vIENlbGwgaXMgaW52YWxpZCAtIGFkZCBvciB1cGRhdGUgZXJyb3JcbiAgICAgIGlmICghcm93U3RhdGUpIHtcbiAgICAgICAgLy8gQ3JlYXRlIG5ldyByb3cgc3RhdGUgZm9yIHRoaXMgaW52YWxpZCByb3dcbiAgICAgICAgcm93U3RhdGUgPSB7XG4gICAgICAgICAgcm93SW5kZXgsXG4gICAgICAgICAgaXNWYWxpZDogZmFsc2UsXG4gICAgICAgICAgaW52YWxpZENlbGxDb3VudDogMSxcbiAgICAgICAgICBjZWxsRXJyb3JzOiBuZXcgTWFwKFtbY29sdW1uS2V5LCBlcnJvcl1dKSxcbiAgICAgICAgICBsYXN0VmFsaWRhdGVkOiBuZXcgRGF0ZSgpXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBVcGRhdGUgZXhpc3Rpbmcgcm93IHN0YXRlXG4gICAgICAgIGNvbnN0IGNlbGxFcnJvcnMgPSBuZXcgTWFwKHJvd1N0YXRlLmNlbGxFcnJvcnMpO1xuICAgICAgICBjZWxsRXJyb3JzLnNldChjb2x1bW5LZXksIGVycm9yKTtcbiAgICAgICAgXG4gICAgICAgIHJvd1N0YXRlID0ge1xuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIGlzVmFsaWQ6IGZhbHNlLFxuICAgICAgICAgIGludmFsaWRDZWxsQ291bnQ6IGNlbGxFcnJvcnMuc2l6ZSxcbiAgICAgICAgICBjZWxsRXJyb3JzLFxuICAgICAgICAgIGxhc3RWYWxpZGF0ZWQ6IG5ldyBEYXRlKClcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJvd1N0YXRlcy5zZXQocm93SW5kZXgsIHJvd1N0YXRlKTtcbiAgICAgIFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDZWxsIGlzIHZhbGlkIC0gcmVtb3ZlIGVycm9yIGlmIGl0IGV4aXN0c1xuICAgICAgaWYgKHJvd1N0YXRlKSB7XG4gICAgICAgIGNvbnN0IGNlbGxFcnJvcnMgPSBuZXcgTWFwKHJvd1N0YXRlLmNlbGxFcnJvcnMpO1xuICAgICAgICBjZWxsRXJyb3JzLmRlbGV0ZShjb2x1bW5LZXkpO1xuICAgICAgICBcbiAgICAgICAgaWYgKGNlbGxFcnJvcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgIC8vIE5vIG1vcmUgZXJyb3JzIGluIHRoaXMgcm93IC0gcmVtb3ZlIHJvdyBzdGF0ZSBjb21wbGV0ZWx5XG4gICAgICAgICAgcm93U3RhdGVzLmRlbGV0ZShyb3dJbmRleCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gU3RpbGwgaGFzIG90aGVyIGVycm9ycyAtIHVwZGF0ZSByb3cgc3RhdGVcbiAgICAgICAgICByb3dTdGF0ZSA9IHtcbiAgICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkQ2VsbENvdW50OiBjZWxsRXJyb3JzLnNpemUsXG4gICAgICAgICAgICBjZWxsRXJyb3JzLFxuICAgICAgICAgICAgbGFzdFZhbGlkYXRlZDogbmV3IERhdGUoKVxuICAgICAgICAgIH07XG4gICAgICAgICAgcm93U3RhdGVzLnNldChyb3dJbmRleCwgcm93U3RhdGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBJZiByb3dTdGF0ZSBkb2Vzbid0IGV4aXN0LCBjZWxsIHdhcyBhbHJlYWR5IHZhbGlkIC0gZG8gbm90aGluZ1xuICAgIH1cbiAgICBcbiAgICAvLyBSZWNhbGN1bGF0ZSB0YWJsZSBzdGF0ZVxuICAgIC8vIEFsbCByb3dzIGluIHJvd1N0YXRlcyBtYXAgYXJlIGludmFsaWQgYnkgZGVmaW5pdGlvblxuICAgIGNvbnN0IGludmFsaWRSb3dzID0gcm93U3RhdGVzLnNpemU7XG4gICAgXG4gICAgY29uc3QgbmV3VGFibGVTdGF0ZTogVGFibGVWYWxpZGF0aW9uU3RhdGUgPSB7XG4gICAgICBpc1ZhbGlkOiBpbnZhbGlkUm93cyA9PT0gMCxcbiAgICAgIHRvdGFsUm93czogY3VycmVudFN0YXRlLnRvdGFsUm93cywgLy8gS2VlcCB0cmFjayBvZiB0b3RhbCByb3dzIHNlcGFyYXRlbHlcbiAgICAgIHZhbGlkUm93czogY3VycmVudFN0YXRlLnRvdGFsUm93cyAtIGludmFsaWRSb3dzLFxuICAgICAgaW52YWxpZFJvd3MsXG4gICAgICByb3dTdGF0ZXMsXG4gICAgICBsYXN0VXBkYXRlZDogbmV3IERhdGUoKVxuICAgIH07XG4gICAgXG4gICAgLy8gRW1pdCBuZXcgc3RhdGVcbiAgICB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQubmV4dChuZXdUYWJsZVN0YXRlKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHRhYmxlIHZhbGlkYXRpb24gc3RhdGVcbiAgICovXG4gIGdldFRhYmxlVmFsaWRhdGlvblN0YXRlKCk6IFRhYmxlVmFsaWRhdGlvblN0YXRlIHtcbiAgICByZXR1cm4gdGhpcy5fdGFibGVWYWxpZGF0aW9uU3RhdGUkLnZhbHVlO1xuICB9XG4gIFxuICAvKipcbiAgICogU2V0IHRvdGFsIHJvd3MgZm9yIHZhbGlkYXRpb24gc3RhdGUgdHJhY2tpbmdcbiAgICovXG4gIHNldFZhbGlkYXRpb25Sb3dDb3VudCh0b3RhbFJvd3M6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuX3RhYmxlVmFsaWRhdGlvblN0YXRlJC52YWx1ZTtcbiAgICB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQubmV4dCh7XG4gICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICB0b3RhbFJvd3MsXG4gICAgICBsYXN0VXBkYXRlZDogbmV3IERhdGUoKVxuICAgIH0pO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBTVEFURSBSRVNFVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRvIGluaXRpYWwgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZXNldFBhZ2luYXRpb24oKTtcbiAgICB0aGlzLnJlc2V0QWxsU29ydGluZygpO1xuICAgIHRoaXMucmVzZXRBbGxGaWx0ZXJzKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgcGFnaW5hdGlvbiBvbmx5XG4gICAqL1xuICByZXNldFBhZ2luYXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5fcGFnaW5hdGlvbiQubmV4dCh7XG4gICAgICBjdXJyZW50UGFnZTogdGhpcy5faW5pdGlhbENvbmZpZy5pbml0aWFsUGFnZSEsXG4gICAgICBwYWdlU2l6ZTogdGhpcy5faW5pdGlhbENvbmZpZy5wYWdlU2l6ZSEsXG4gICAgICB0b3RhbEl0ZW1zOiAwLFxuICAgICAgdG90YWxQYWdlczogMFxuICAgIH0pO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdwYWdpbmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgYWxsIGNvbHVtbiBzb3J0c1xuICAgKi9cbiAgcmVzZXRBbGxTb3J0aW5nKCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJBbGxTb3J0aW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgYWxsIGNvbHVtbiBmaWx0ZXJzXG4gICAqL1xuICByZXNldEFsbEZpbHRlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhckFsbEZpbHRlcnMoKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gSU5URVJOQUwgTUVUSE9EU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIEZpbmQgYSBjb2x1bW4gYnkga2V5XG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcmV0dXJucyBDb2x1bW4gY29uZmlnIG9yIHVuZGVmaW5lZFxuICAgKi9cbiAgcHJpdmF0ZSBmaW5kQ29sdW1uKGNvbHVtbktleTogc3RyaW5nKTogQ29sdW1uQ29uZmlnPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9jb2x1bW5zLmZpbmQoY29sID0+IGNvbC5rZXkgPT09IGNvbHVtbktleSk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRvdGFsIHBhZ2VzXG4gICAqIEBwYXJhbSB0b3RhbEl0ZW1zIFRvdGFsIG51bWJlciBvZiBpdGVtc1xuICAgKiBAcGFyYW0gcGFnZVNpemUgUGFnZSBzaXplXG4gICAqIEByZXR1cm5zIFRvdGFsIG51bWJlciBvZiBwYWdlc1xuICAgKi9cbiAgcHJpdmF0ZSBjYWxjdWxhdGVUb3RhbFBhZ2VzKHRvdGFsSXRlbXM6IG51bWJlciA9IDAsIHBhZ2VTaXplOiBudW1iZXIgPSAyNSk6IG51bWJlciB7XG4gICAgaWYgKHRvdGFsSXRlbXMgPT09IDAgfHwgcGFnZVNpemUgPT09IDApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gTWF0aC5jZWlsKHRvdGFsSXRlbXMgLyBwYWdlU2l6ZSk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdCBzdGF0ZSBjaGFuZ2UgZXZlbnRcbiAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBjaGFuZ2VcbiAgICovXG4gIHByaXZhdGUgZW1pdFN0YXRlQ2hhbmdlKHR5cGU6IFRhYmxlU3RhdGVDaGFuZ2VFdmVudFsndHlwZSddKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLmJ1aWxkU3RhdGVTbmFwc2hvdCgpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlJC5uZXh0KHtcbiAgICAgIHR5cGUsXG4gICAgICBzdGF0ZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHN0YXRlIHNuYXBzaG90IGZyb20gY3VycmVudCBzdGF0ZVxuICAgKiBAcmV0dXJucyBTdGF0ZSBzbmFwc2hvdFxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFN0YXRlU25hcHNob3QoKTogVGFibGVTdGF0ZVNuYXBzaG90IHtcbiAgICByZXR1cm4ge1xuICAgICAgcGFnaW5hdGlvbjogdGhpcy5nZXRQYWdpbmF0aW9uKCksXG4gICAgICBcbiAgICAgIC8vIEJ1aWxkIGZ1bGwgc29ydCBzdGF0ZSB3aXRoIGRpcmVjdGlvbiBhbmQgcHJpb3JpdHlcbiAgICAgIHNvcnRlZENvbHVtbnM6IHRoaXMuX2NvbHVtbnNcbiAgICAgICAgLmZpbHRlcihjb2wgPT4gY29sLnNvcnRFbmFibGVkID09PSB0cnVlKVxuICAgICAgICAubWFwKChjb2wsIGluZGV4KSA9PiAoe1xuICAgICAgICAgIGNvbHVtbktleTogY29sLmtleSxcbiAgICAgICAgICBkaXJlY3Rpb246IGNvbC5zb3J0RGlyZWN0aW9uIHx8IFNvcnREaXJlY3Rpb24uTk9ORSxcbiAgICAgICAgICBwcmlvcml0eTogaW5kZXggIC8vIFNvcnQgb3JkZXIgYmFzZWQgb24gZW5hYmxlbWVudCBvcmRlclxuICAgICAgICB9KSksXG4gICAgICBcbiAgICAgIC8vIEJ1aWxkIGZ1bGwgZmlsdGVyIHN0YXRlIHdpdGggb3BlcmF0b3IgYW5kIHZhbHVlXG4gICAgICBmaWx0ZXJlZENvbHVtbnM6IHRoaXMuX2NvbHVtbnNcbiAgICAgICAgLmZpbHRlcihjb2wgPT4gY29sLmZpbHRlckNvbmZpZz8uZW5hYmxlZCA9PT0gdHJ1ZSlcbiAgICAgICAgLm1hcChjb2wgPT4gKHtcbiAgICAgICAgICBjb2x1bW5LZXk6IGNvbC5rZXksXG4gICAgICAgICAgb3BlcmF0b3I6IGNvbC5maWx0ZXJDb25maWc/Lm9wZXJhdG9yIHx8IEZpbHRlck9wZXJhdG9yLkNPTlRBSU5TLFxuICAgICAgICAgIHZhbHVlOiBjb2wuZmlsdGVyQ29uZmlnPy52YWx1ZSxcbiAgICAgICAgICBlbmFibGVkOiB0cnVlXG4gICAgICAgIH0pKVxuICAgIH07XG4gIH1cbn1cblxuIl19
|