@pecb-ui/components 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +556 -556
  2. package/fesm2022/pecb-ui-components.mjs +998 -1907
  3. package/fesm2022/pecb-ui-components.mjs.map +1 -1
  4. package/index.d.ts +2439 -3
  5. package/package.json +6 -8
  6. package/esm2022/lib/components/button/button.component.mjs +0 -171
  7. package/esm2022/lib/components/card/card.component.mjs +0 -182
  8. package/esm2022/lib/components/checkbox/checkbox.component.mjs +0 -126
  9. package/esm2022/lib/components/datepicker/datepicker.component.mjs +0 -349
  10. package/esm2022/lib/components/dropdown/dropdown.component.mjs +0 -329
  11. package/esm2022/lib/components/input/input.component.mjs +0 -321
  12. package/esm2022/lib/components/pagination/pagination.component.mjs +0 -197
  13. package/esm2022/lib/components/radio/radio.component.mjs +0 -147
  14. package/esm2022/lib/components/right-modal/right-modal.component.mjs +0 -234
  15. package/esm2022/lib/components/sidebar/sidebar.component.mjs +0 -155
  16. package/esm2022/lib/components/status/status.component.mjs +0 -50
  17. package/esm2022/lib/components/tab/tab.component.mjs +0 -151
  18. package/esm2022/lib/components/table/table.component.mjs +0 -503
  19. package/esm2022/lib/components/toggle/toggle.component.mjs +0 -126
  20. package/esm2022/lib/pecb-components.module.mjs +0 -118
  21. package/esm2022/lib/services/loading.service.mjs +0 -182
  22. package/esm2022/lib/services/notification.service.mjs +0 -144
  23. package/esm2022/lib/services/theme.service.mjs +0 -232
  24. package/esm2022/lib/shared/interfaces/component.interfaces.mjs +0 -2
  25. package/esm2022/lib/shared/types/common.types.mjs +0 -6
  26. package/esm2022/lib/shared/utils/accessibility.utils.mjs +0 -223
  27. package/esm2022/lib/shared/utils/dom.utils.mjs +0 -240
  28. package/esm2022/lib/shared/utils/error.utils.mjs +0 -277
  29. package/esm2022/lib/shared/utils/string.utils.mjs +0 -204
  30. package/esm2022/pecb-ui-components.mjs +0 -5
  31. package/esm2022/public-api.mjs +0 -53
  32. package/lib/components/button/button.component.d.ts +0 -130
  33. package/lib/components/card/card.component.d.ts +0 -140
  34. package/lib/components/checkbox/checkbox.component.d.ts +0 -74
  35. package/lib/components/datepicker/datepicker.component.d.ts +0 -155
  36. package/lib/components/dropdown/dropdown.component.d.ts +0 -144
  37. package/lib/components/input/input.component.d.ts +0 -215
  38. package/lib/components/pagination/pagination.component.d.ts +0 -53
  39. package/lib/components/radio/radio.component.d.ts +0 -93
  40. package/lib/components/right-modal/right-modal.component.d.ts +0 -137
  41. package/lib/components/sidebar/sidebar.component.d.ts +0 -97
  42. package/lib/components/status/status.component.d.ts +0 -19
  43. package/lib/components/tab/tab.component.d.ts +0 -102
  44. package/lib/components/table/table.component.d.ts +0 -403
  45. package/lib/components/toggle/toggle.component.d.ts +0 -74
  46. package/lib/pecb-components.module.d.ts +0 -37
  47. package/lib/services/loading.service.d.ts +0 -129
  48. package/lib/services/notification.service.d.ts +0 -136
  49. package/lib/services/theme.service.d.ts +0 -142
  50. package/lib/shared/interfaces/component.interfaces.d.ts +0 -283
  51. package/lib/shared/types/common.types.d.ts +0 -86
  52. package/lib/shared/utils/accessibility.utils.d.ts +0 -167
  53. package/lib/shared/utils/dom.utils.d.ts +0 -108
  54. package/lib/shared/utils/error.utils.d.ts +0 -191
  55. package/lib/shared/utils/string.utils.d.ts +0 -144
  56. package/public-api.d.ts +0 -24
@@ -1,503 +0,0 @@
1
- import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ContentChild, } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { PaginationComponent } from '../pagination/pagination.component';
4
- import { StatusComponent } from '../status/status.component';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/platform-browser";
7
- import * as i2 from "@angular/common";
8
- /**
9
- * Table component for displaying tabular data with pagination support.
10
- *
11
- * @example
12
- * ```html
13
- * <pecb-table
14
- * [columns]="columns"
15
- * [data]="tableData"
16
- * [showPagination]="true"
17
- * [totalItems]="500"
18
- * [pageSize]="15"
19
- * (pageChange)="onPageChange($event)"
20
- * (rowAction)="onRowAction($event)">
21
- * </pecb-table>
22
- * ```
23
- */
24
- export class TableComponent {
25
- constructor(sanitizer) {
26
- this.sanitizer = sanitizer;
27
- /**
28
- * Column definitions for the table
29
- */
30
- this.columns = [];
31
- /**
32
- * Data array to display in the table
33
- */
34
- this.data = [];
35
- /**
36
- * Size variant of the table
37
- * @default 'md'
38
- */
39
- this.size = 'md';
40
- /**
41
- * Visual variant of the table
42
- * @default 'default'
43
- */
44
- this.variant = 'default';
45
- /**
46
- * Whether to show the table header
47
- * @default true
48
- */
49
- this.showHeader = true;
50
- /**
51
- * Whether to enable row hover effect
52
- * @default true
53
- */
54
- this.hoverable = true;
55
- /**
56
- * Whether to show pagination
57
- * @default true
58
- */
59
- this.showPagination = true;
60
- /**
61
- * Total number of items for pagination
62
- */
63
- this.totalItems = 0;
64
- /**
65
- * Current page number (1-based)
66
- * @default 1
67
- */
68
- this.currentPage = 1;
69
- /**
70
- * Number of items per page
71
- * @default 15
72
- */
73
- this.pageSize = 15;
74
- /**
75
- * Available page size options
76
- */
77
- this.pageSizeOptions = [10, 15, 25, 50];
78
- /**
79
- * Whether to show page size selector in pagination
80
- * @default true
81
- */
82
- this.showPageSizeSelector = true;
83
- /**
84
- * Pagination variant
85
- * @default 'full'
86
- */
87
- this.paginationVariant = 'full';
88
- /**
89
- * Message to display when there is no data
90
- */
91
- this.emptyMessage = 'There are no entries yet.';
92
- /**
93
- * Whether to show loading state
94
- * @default false
95
- */
96
- this.loading = false;
97
- /**
98
- * Whether to enable row selection
99
- * @default false
100
- */
101
- this.selectable = false;
102
- /**
103
- * Currently selected row indices
104
- */
105
- this.selectedIndices = [];
106
- /**
107
- * Whether the table has a fixed header
108
- * @default false
109
- */
110
- this.stickyHeader = false;
111
- /**
112
- * Current sort direction
113
- */
114
- this.sortDirection = null;
115
- /**
116
- * ARIA label for the table
117
- */
118
- this.ariaLabel = 'Data table';
119
- /**
120
- * Emitted when a page change occurs
121
- */
122
- this.pageChange = new EventEmitter();
123
- /**
124
- * Emitted when page size changes
125
- */
126
- this.pageSizeChange = new EventEmitter();
127
- /**
128
- * Emitted when a row is clicked
129
- */
130
- this.rowClick = new EventEmitter();
131
- /**
132
- * Emitted when a row action is triggered
133
- */
134
- this.rowAction = new EventEmitter();
135
- /**
136
- * Emitted when sorting changes
137
- */
138
- this.sortChange = new EventEmitter();
139
- /**
140
- * Emitted when row selection changes
141
- */
142
- this.selectionChange = new EventEmitter();
143
- }
144
- /**
145
- * Gets the CSS classes for the table container
146
- */
147
- get containerClasses() {
148
- const classes = ['pecb-table-container'];
149
- if (this.stickyHeader) {
150
- classes.push('pecb-table-container--sticky');
151
- }
152
- return classes.join(' ');
153
- }
154
- /**
155
- * Gets the CSS classes for the pagination container
156
- */
157
- get paginationClasses() {
158
- const classes = ['pecb-table__pagination'];
159
- if (this.paginationVariant === 'full' || this.paginationVariant === 'compact') {
160
- classes.push('pecb-table__pagination--bordered');
161
- }
162
- return classes.join(' ');
163
- }
164
- /**
165
- * Gets the CSS classes for the table element
166
- */
167
- get tableClasses() {
168
- const classes = ['pecb-table', `pecb-table--${this.size}`, `pecb-table--${this.variant}`];
169
- if (this.hoverable) {
170
- classes.push('pecb-table--hoverable');
171
- }
172
- if (this.selectable) {
173
- classes.push('pecb-table--selectable');
174
- }
175
- return classes.join(' ');
176
- }
177
- /**
178
- * Gets the value from a row for a given column key
179
- * Supports nested keys like 'user.name'
180
- */
181
- getCellValue(row, key) {
182
- if (!row || !key)
183
- return '';
184
- const keys = key.split('.');
185
- let value = row;
186
- for (const k of keys) {
187
- if (value === null || value === undefined)
188
- return '';
189
- value = value[k];
190
- }
191
- return value ?? '';
192
- }
193
- /**
194
- * Gets the alignment class for a column
195
- */
196
- getAlignmentClass(column) {
197
- if (!column.align || column.align === 'left')
198
- return '';
199
- return `pecb-table__cell--${column.align}`;
200
- }
201
- /**
202
- * Handles row click events
203
- */
204
- onRowClick(row, index) {
205
- if (this.selectable) {
206
- this.toggleRowSelection(index);
207
- }
208
- this.rowClick.emit({ row, index });
209
- }
210
- /**
211
- * Handles row action button clicks
212
- */
213
- onRowAction(action, row, index, event) {
214
- event.stopPropagation();
215
- this.rowAction.emit({ action, row, index });
216
- }
217
- /**
218
- * Handles column header click for sorting
219
- */
220
- onHeaderClick(column) {
221
- if (!column.sortable)
222
- return;
223
- let newDirection = 'asc';
224
- if (this.sortColumn === column.key) {
225
- if (this.sortDirection === 'asc') {
226
- newDirection = 'desc';
227
- }
228
- else if (this.sortDirection === 'desc') {
229
- newDirection = null;
230
- }
231
- }
232
- this.sortColumn = newDirection ? column.key : undefined;
233
- this.sortDirection = newDirection;
234
- this.sortChange.emit({
235
- column: column.key,
236
- direction: newDirection,
237
- });
238
- }
239
- /**
240
- * Toggles row selection
241
- */
242
- toggleRowSelection(index) {
243
- const newSelection = [...this.selectedIndices];
244
- const existingIndex = newSelection.indexOf(index);
245
- if (existingIndex > -1) {
246
- newSelection.splice(existingIndex, 1);
247
- }
248
- else {
249
- newSelection.push(index);
250
- }
251
- this.selectedIndices = newSelection;
252
- this.emitSelectionChange();
253
- }
254
- /**
255
- * Toggles all rows selection
256
- */
257
- toggleAllSelection() {
258
- if (this.isAllSelected()) {
259
- this.selectedIndices = [];
260
- }
261
- else {
262
- this.selectedIndices = this.data.map((_, index) => index);
263
- }
264
- this.emitSelectionChange();
265
- }
266
- /**
267
- * Checks if a row is selected
268
- */
269
- isRowSelected(index) {
270
- return this.selectedIndices.includes(index);
271
- }
272
- /**
273
- * Checks if all rows are selected
274
- */
275
- isAllSelected() {
276
- return this.data.length > 0 && this.selectedIndices.length === this.data.length;
277
- }
278
- /**
279
- * Checks if some rows are selected (for indeterminate state)
280
- */
281
- isSomeSelected() {
282
- return this.selectedIndices.length > 0 && this.selectedIndices.length < this.data.length;
283
- }
284
- /**
285
- * Handles page change from pagination component
286
- */
287
- onPageChange(event) {
288
- this.currentPage = event.page;
289
- this.pageChange.emit(event);
290
- }
291
- /**
292
- * Handles page size change from pagination component
293
- */
294
- onPageSizeChange(newSize) {
295
- this.pageSize = newSize;
296
- this.currentPage = 1;
297
- this.pageSizeChange.emit(newSize);
298
- }
299
- /**
300
- * Gets the sort icon state for a column
301
- */
302
- getSortState(column) {
303
- if (!column.sortable)
304
- return 'none';
305
- if (this.sortColumn !== column.key)
306
- return 'none';
307
- return this.sortDirection || 'none';
308
- }
309
- /**
310
- * Tracks rows by index for ngFor performance
311
- */
312
- trackByIndex(index) {
313
- return index;
314
- }
315
- /**
316
- * Tracks columns by key for ngFor performance
317
- */
318
- trackByKey(_, column) {
319
- return column.key;
320
- }
321
- /**
322
- * Gets the effective column type (supports both 'type' and 'component' properties)
323
- */
324
- getColumnType(column) {
325
- return column.component || column.type || 'text';
326
- }
327
- /**
328
- * Gets the status type for a value based on column config
329
- */
330
- getStatusType(value, column) {
331
- const config = column.statusConfig;
332
- if (config?.typeMap && value in config.typeMap) {
333
- return config.typeMap[value];
334
- }
335
- // Default mappings
336
- const defaultMap = {
337
- 'Pending': 'warning',
338
- 'pending': 'warning',
339
- 'Inactive': 'error',
340
- 'inactive': 'error',
341
- 'Approved': 'success',
342
- 'approved': 'success',
343
- 'Active': 'success',
344
- 'active': 'success',
345
- 'Disabled': 'disabled',
346
- 'disabled': 'disabled',
347
- };
348
- return defaultMap[value] || 'neutral';
349
- }
350
- /**
351
- * Gets the status variant for a column
352
- */
353
- getStatusVariant(column) {
354
- return column.statusConfig?.variant || 'filled';
355
- }
356
- /**
357
- * Gets the status size for a column
358
- */
359
- getStatusSize(column) {
360
- return column.statusConfig?.size || 'sm';
361
- }
362
- /**
363
- * Gets user display data from row
364
- */
365
- getUserData(row, column) {
366
- const config = column.userConfig || {};
367
- return {
368
- avatar: row[config.avatarKey || 'avatar'] || '',
369
- name: row[config.nameKey || column.key] || '',
370
- secondary: row[config.secondaryKey || 'email'] || '',
371
- };
372
- }
373
- /**
374
- * Gets default actions if none specified
375
- */
376
- getActions(column) {
377
- if (column.actions && column.actions.length > 0) {
378
- return column.actions;
379
- }
380
- // Default actions
381
- return [
382
- { id: 'view', icon: 'view', tooltip: 'View' },
383
- { id: 'edit', icon: 'edit', tooltip: 'Edit' },
384
- { id: 'delete', icon: 'delete', tooltip: 'Delete', variant: 'danger' },
385
- ];
386
- }
387
- /**
388
- * Handles action button click
389
- */
390
- onActionClick(action, row, index, event) {
391
- event.stopPropagation();
392
- // Call individual action callback if provided
393
- if (action.action) {
394
- action.action(row, index);
395
- }
396
- // Always emit the rowAction event
397
- this.rowAction.emit({ action: action.id, row, index });
398
- }
399
- /**
400
- * Gets the inputs for a dynamic component
401
- * Combines static componentInputs with row-specific data from componentInputsFn
402
- */
403
- getDynamicComponentInputs(row, column, index) {
404
- const value = this.getCellValue(row, column.key);
405
- const staticInputs = column.componentInputs || {};
406
- if (column.componentInputsFn) {
407
- const dynamicInputs = column.componentInputsFn(row, value, index);
408
- return { ...staticInputs, ...dynamicInputs };
409
- }
410
- return staticInputs;
411
- }
412
- /**
413
- * Checks if column has a dynamic component
414
- */
415
- hasDynamicComponent(column) {
416
- return !!column.dynamicComponent;
417
- }
418
- /**
419
- * Sanitizes custom icon SVG for safe rendering
420
- */
421
- getSafeIcon(iconSvg) {
422
- if (!iconSvg)
423
- return '';
424
- return this.sanitizer.bypassSecurityTrustHtml(iconSvg);
425
- }
426
- emitSelectionChange() {
427
- const selectedRows = this.selectedIndices.map(index => this.data[index]);
428
- this.selectionChange.emit({
429
- selectedRows,
430
- selectedIndices: this.selectedIndices,
431
- });
432
- }
433
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
434
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TableComponent, isStandalone: true, selector: "pecb-table", inputs: { columns: "columns", data: "data", size: "size", variant: "variant", showHeader: "showHeader", hoverable: "hoverable", showPagination: "showPagination", totalItems: "totalItems", currentPage: "currentPage", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions", showPageSizeSelector: "showPageSizeSelector", paginationVariant: "paginationVariant", emptyMessage: "emptyMessage", loading: "loading", selectable: "selectable", selectedIndices: "selectedIndices", stickyHeader: "stickyHeader", maxHeight: "maxHeight", sortColumn: "sortColumn", sortDirection: "sortDirection", ariaLabel: ["aria-label", "ariaLabel"] }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange", rowClick: "rowClick", rowAction: "rowAction", sortChange: "sortChange", selectionChange: "selectionChange" }, queries: [{ propertyName: "emptyTemplate", first: true, predicate: ["emptyTemplate"], descendants: true }, { propertyName: "loadingTemplate", first: true, predicate: ["loadingTemplate"], descendants: true }], ngImport: i0, template: "<div class=\"pecb-table-wrapper\">\r\n <div [class]=\"containerClasses\" [style.maxHeight]=\"maxHeight\">\r\n <!-- Loading State -->\r\n <div *ngIf=\"loading\" class=\"pecb-table__loading\">\r\n <ng-container *ngIf=\"loadingTemplate; else defaultLoading\">\r\n <ng-container *ngTemplateOutlet=\"loadingTemplate\"></ng-container>\r\n </ng-container>\r\n <ng-template #defaultLoading>\r\n <div class=\"pecb-table__loading-spinner\">\r\n <svg class=\"pecb-table__spinner-icon\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-dasharray=\"31.4 31.4\" />\r\n </svg>\r\n <span>Loading...</span>\r\n </div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Table -->\r\n <table\r\n *ngIf=\"!loading\"\r\n [class]=\"tableClasses\"\r\n [attr.aria-label]=\"ariaLabel\"\r\n role=\"table\">\r\n\r\n <!-- Table Header -->\r\n <thead *ngIf=\"showHeader\" class=\"pecb-table__head\" [class.pecb-table__head--sticky]=\"stickyHeader\">\r\n <tr class=\"pecb-table__row pecb-table__row--header\" role=\"row\">\r\n <!-- Selection Checkbox Column -->\r\n <th\r\n *ngIf=\"selectable\"\r\n class=\"pecb-table__cell pecb-table__cell--header pecb-table__cell--checkbox\"\r\n role=\"columnheader\"\r\n scope=\"col\">\r\n <label class=\"pecb-table__checkbox-wrapper\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"pecb-table__checkbox\"\r\n [checked]=\"isAllSelected()\"\r\n [indeterminate]=\"isSomeSelected()\"\r\n (change)=\"toggleAllSelection()\"\r\n aria-label=\"Select all rows\" />\r\n <span class=\"pecb-table__checkbox-custom\"></span>\r\n </label>\r\n </th>\r\n\r\n <!-- Data Columns -->\r\n <th\r\n *ngFor=\"let column of columns; trackBy: trackByKey\"\r\n class=\"pecb-table__cell pecb-table__cell--header\"\r\n [class.pecb-table__cell--sortable]=\"column.sortable\"\r\n [class]=\"getAlignmentClass(column)\"\r\n [ngClass]=\"column.cssClass\"\r\n [style.width]=\"column.width\"\r\n [attr.aria-sort]=\"column.sortable ? (sortColumn === column.key ? (sortDirection === 'asc' ? 'ascending' : 'descending') : 'none') : null\"\r\n role=\"columnheader\"\r\n scope=\"col\"\r\n (click)=\"onHeaderClick(column)\"\r\n (keydown.enter)=\"onHeaderClick(column)\"\r\n (keydown.space)=\"onHeaderClick(column); $event.preventDefault()\"\r\n [attr.tabindex]=\"column.sortable ? 0 : null\">\r\n <div class=\"pecb-table__header-content\">\r\n <ng-container *ngIf=\"column.headerTemplate; else defaultHeader\">\r\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\r\n </ng-container>\r\n <ng-template #defaultHeader>\r\n <span class=\"pecb-table__header-text\">{{ column.label }}</span>\r\n </ng-template>\r\n\r\n <!-- Sort Icon -->\r\n <span *ngIf=\"column.sortable\" class=\"pecb-table__sort-icon\" [attr.data-sort]=\"getSortState(column)\">\r\n <svg *ngIf=\"getSortState(column) === 'none'\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 3L12 7H4L8 3Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n <path d=\"M8 13L4 9H12L8 13Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n </svg>\r\n <svg *ngIf=\"getSortState(column) === 'asc'\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 3L12 7H4L8 3Z\" fill=\"currentColor\"/>\r\n <path d=\"M8 13L4 9H12L8 13Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n </svg>\r\n <svg *ngIf=\"getSortState(column) === 'desc'\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 3L12 7H4L8 3Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n <path d=\"M8 13L4 9H12L8 13Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <!-- Table Body -->\r\n <tbody class=\"pecb-table__body\">\r\n <!-- Empty State -->\r\n <tr *ngIf=\"data.length === 0\" class=\"pecb-table__row pecb-table__row--empty\">\r\n <td\r\n [attr.colspan]=\"selectable ? columns.length + 1 : columns.length\"\r\n class=\"pecb-table__cell pecb-table__cell--empty\">\r\n <ng-container *ngIf=\"emptyTemplate; else defaultEmpty\">\r\n <ng-container *ngTemplateOutlet=\"emptyTemplate\"></ng-container>\r\n </ng-container>\r\n <ng-template #defaultEmpty>\r\n <div class=\"pecb-table__empty-content\">\r\n <span class=\"pecb-table__empty-message\">{{ emptyMessage }}</span>\r\n </div>\r\n </ng-template>\r\n </td>\r\n </tr>\r\n\r\n <!-- Data Rows -->\r\n <tr\r\n *ngFor=\"let row of data; let i = index; trackBy: trackByIndex\"\r\n class=\"pecb-table__row pecb-table__row--data\"\r\n [class.pecb-table__row--selected]=\"isRowSelected(i)\"\r\n role=\"row\"\r\n (click)=\"onRowClick(row, i)\"\r\n [attr.tabindex]=\"0\"\r\n (keydown.enter)=\"onRowClick(row, i)\">\r\n\r\n <!-- Selection Checkbox -->\r\n <td\r\n *ngIf=\"selectable\"\r\n class=\"pecb-table__cell pecb-table__cell--checkbox\"\r\n role=\"cell\"\r\n (click)=\"$event.stopPropagation()\">\r\n <label class=\"pecb-table__checkbox-wrapper\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"pecb-table__checkbox\"\r\n [checked]=\"isRowSelected(i)\"\r\n (change)=\"toggleRowSelection(i)\"\r\n [attr.aria-label]=\"'Select row ' + (i + 1)\" />\r\n <span class=\"pecb-table__checkbox-custom\"></span>\r\n </label>\r\n </td>\r\n\r\n <!-- Data Cells -->\r\n <td\r\n *ngFor=\"let column of columns; trackBy: trackByKey\"\r\n class=\"pecb-table__cell\"\r\n [class]=\"getAlignmentClass(column)\"\r\n [ngClass]=\"column.cssClass\"\r\n role=\"cell\">\r\n\r\n <!-- Custom Template -->\r\n <ng-container *ngIf=\"column.cellTemplate\">\r\n <ng-container *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: getCellValue(row, column.key), row: row, column: column, index: i }\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Dynamic Component - renders any component passed via dynamicComponent -->\r\n <ng-container *ngIf=\"!column.cellTemplate && hasDynamicComponent(column)\">\r\n <ng-container\r\n *ngComponentOutlet=\"column.dynamicComponent!; inputs: getDynamicComponentInputs(row, column, i)\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Status Component - renders pecb-status -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'status'\">\r\n <pecb-status\r\n [type]=\"getStatusType(getCellValue(row, column.key), column)\"\r\n [variant]=\"getStatusVariant(column)\"\r\n [size]=\"getStatusSize(column)\">\r\n {{ getCellValue(row, column.key) }}\r\n </pecb-status>\r\n </ng-container>\r\n\r\n <!-- User Component - renders avatar + name + email -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'user'\">\r\n <div class=\"pecb-table__user-cell\">\r\n <img\r\n *ngIf=\"getUserData(row, column).avatar\"\r\n [src]=\"getUserData(row, column).avatar\"\r\n alt=\"\"\r\n class=\"pecb-table__user-avatar\">\r\n <div class=\"pecb-table__user-info\">\r\n <div class=\"pecb-table__user-name\">{{ getUserData(row, column).name }}</div>\r\n <div *ngIf=\"getUserData(row, column).secondary\" class=\"pecb-table__user-secondary\">\r\n {{ getUserData(row, column).secondary }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Action Component - renders action buttons with icons -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'action'\">\r\n <div class=\"pecb-table__action-buttons\">\r\n <button\r\n *ngFor=\"let action of getActions(column)\"\r\n class=\"pecb-table__action-btn\"\r\n [class.pecb-table__action-btn--danger]=\"action.variant === 'danger'\"\r\n [title]=\"action.tooltip || action.id\"\r\n [disabled]=\"action.disabled\"\r\n (click)=\"onActionClick(action, row, i, $event)\">\r\n <!-- View Icon -->\r\n <svg *ngIf=\"action.icon === 'view'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n <!-- Edit Icon -->\r\n <svg *ngIf=\"action.icon === 'edit'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path>\r\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"></path>\r\n </svg>\r\n <!-- Delete Icon -->\r\n <svg *ngIf=\"action.icon === 'delete'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <polyline points=\"3 6 5 6 21 6\"></polyline>\r\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path>\r\n </svg>\r\n <!-- Download Icon -->\r\n <svg *ngIf=\"action.icon === 'download'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path>\r\n <polyline points=\"7 10 12 15 17 10\"></polyline>\r\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"></line>\r\n </svg>\r\n <!-- Copy Icon -->\r\n <svg *ngIf=\"action.icon === 'copy'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\r\n </svg>\r\n <!-- Custom Icon (SVG string) -->\r\n <span *ngIf=\"action.icon === 'custom' && action.customIcon\" class=\"pecb-table__custom-icon\" [innerHTML]=\"getSafeIcon(action.customIcon)\"></span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Default Text -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'text'\">\r\n {{ getCellValue(row, column.key) }}\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Pagination (outside table container) -->\r\n <div *ngIf=\"showPagination && !loading && data.length > 0\" [class]=\"paginationClasses\">\r\n <pecb-pagination\r\n [totalItems]=\"totalItems\"\r\n [pageSize]=\"pageSize\"\r\n [currentPage]=\"currentPage\"\r\n [pageSizeOptions]=\"pageSizeOptions\"\r\n [showPageSizeSelector]=\"showPageSizeSelector\"\r\n [variant]=\"paginationVariant\"\r\n size=\"md\"\r\n (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\">\r\n </pecb-pagination>\r\n </div>\r\n</div>\r\n", styles: [".pecb-table-wrapper{width:100%}.pecb-table-container{width:100%;background-color:#fff;border-radius:8px;overflow:hidden;border:1px solid #f4f4f4}.pecb-table-container--sticky{position:relative;overflow:auto}.pecb-table{width:100%;border-collapse:collapse;border-spacing:0;font-family:Plus Jakarta Sans,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;color:#313131}.pecb-table--sm{font-size:12px}.pecb-table--sm .pecb-table__cell,.pecb-table--sm .pecb-table__cell--header{padding:8px 12px}.pecb-table--md{font-size:14px}.pecb-table--md .pecb-table__cell{padding:16px 18px}.pecb-table--md .pecb-table__cell--header{padding:12px 18px}.pecb-table--lg{font-size:16px}.pecb-table--lg .pecb-table__cell{padding:18px 20px}.pecb-table--lg .pecb-table__cell--header{padding:16px 20px}.pecb-table--default .pecb-table__row--data{border-bottom:1px solid #f4f4f4}.pecb-table--default .pecb-table__row--data:last-child{border-bottom:none}.pecb-table--striped .pecb-table__row--data:nth-child(2n){background-color:#fafafa}.pecb-table--bordered .pecb-table__cell{border:1px solid #f4f4f4}.pecb-table--hoverable .pecb-table__row--data{transition:background-color .15s ease-in-out}.pecb-table--hoverable .pecb-table__row--data:hover{background-color:#ececec}.pecb-table--selectable .pecb-table__row--data{cursor:pointer}.pecb-table__head{background-color:#212427}.pecb-table__head--sticky{position:sticky;top:0;z-index:1020}.pecb-table__row--header{text-transform:uppercase;height:58px}.pecb-table__row--data{background-color:#fff;height:58px}.pecb-table__row--data:focus{outline:none}.pecb-table__row--data:focus-visible{outline:none}.pecb-table__row--selected{background-color:#a11e290d}.pecb-table__row--selected:hover{background-color:#a11e2914}.pecb-table__row--empty{background-color:#fff}.pecb-table__cell{text-align:left;vertical-align:middle;white-space:nowrap}.pecb-table__cell--header{font-weight:500;font-size:12px;color:#fff;letter-spacing:.02em;-webkit-user-select:none;user-select:none}.pecb-table__cell--sortable{cursor:pointer;transition:background-color .15s ease-in-out}.pecb-table__cell--sortable:hover{background-color:#ffffff1a}.pecb-table__cell--sortable:focus{outline:none;box-shadow:inset 0 0 0 2px #fff}.pecb-table__cell--sortable:focus-visible{box-shadow:inset 0 0 0 2px #fff}.pecb-table__cell--checkbox{width:48px;text-align:center}.pecb-table__cell--center{text-align:center}.pecb-table__cell--right{text-align:right}.pecb-table__cell--empty{text-align:center;padding:48px 18px}.pecb-table__header-content{display:flex;align-items:center;gap:8px}.pecb-table__header-text{flex:1}.pecb-table__sort-icon{display:flex;align-items:center;justify-content:center;color:#ffffff80;transition:color .15s ease-in-out}.pecb-table__sort-icon svg{width:16px;height:16px}.pecb-table__sort-icon[data-sort=asc],.pecb-table__sort-icon[data-sort=desc]{color:#fff}.pecb-table__checkbox-wrapper{display:inline-flex;align-items:center;justify-content:center;position:relative;cursor:pointer}.pecb-table__checkbox{position:absolute;opacity:0;width:0;height:0}.pecb-table__checkbox:checked+.pecb-table__checkbox-custom{background-color:#a11e29;border-color:#a11e29}.pecb-table__checkbox:checked+.pecb-table__checkbox-custom:after{display:block}.pecb-table__checkbox:indeterminate+.pecb-table__checkbox-custom{background-color:#a11e29;border-color:#a11e29}.pecb-table__checkbox:indeterminate+.pecb-table__checkbox-custom:before{display:block}.pecb-table__checkbox:indeterminate+.pecb-table__checkbox-custom:after{display:none}.pecb-table__checkbox:focus+.pecb-table__checkbox-custom{box-shadow:0 0 0 2px #a11e2940}.pecb-table__checkbox-custom{width:18px;height:18px;border:2px solid #ececec;border-radius:6px;background-color:#fff;position:relative;transition:all .15s ease-in-out}.pecb-table__checkbox-custom:after{content:\"\";display:none;position:absolute;left:5px;top:2px;width:4px;height:8px;border:solid #ffffff;border-width:0 2px 2px 0;transform:rotate(45deg)}.pecb-table__checkbox-custom:before{content:\"\";display:none;position:absolute;left:3px;top:6px;width:8px;height:2px;background-color:#fff}.pecb-table__empty-content{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px}.pecb-table__empty-message{color:#919191;font-size:14px}.pecb-table__loading{display:flex;align-items:center;justify-content:center;padding:48px;min-height:200px}.pecb-table__loading-spinner{display:flex;flex-direction:column;align-items:center;gap:12px;color:#616161}.pecb-table__spinner-icon{width:32px;height:32px;animation:spin 1s linear infinite;color:#a11e29}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.pecb-table__pagination{padding:16px 0;margin-top:16px}.pecb-table__pagination--bordered{padding:16px 18px;background-color:#fff;border:1px solid #ececec;border-radius:12px}.pecb-table__user-cell{display:flex;align-items:center;gap:12px}.pecb-table__user-avatar{width:40px;height:40px;border-radius:9999px;object-fit:cover;flex-shrink:0}.pecb-table__user-info{display:flex;flex-direction:column;min-width:0}.pecb-table__user-name{font-weight:500;color:#313131;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pecb-table__user-secondary{font-size:12px;color:#919191;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pecb-table__action-buttons{display:flex;gap:8px;justify-content:center}.pecb-table__action-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;color:#919191;cursor:pointer;border-radius:6px;transition:all .15s ease-in-out;padding:0}.pecb-table__action-btn:hover{background-color:#ececec;color:#313131}.pecb-table__action-btn:focus{outline:none;box-shadow:0 0 0 2px #a11e2940}.pecb-table__action-btn:disabled{opacity:.5;cursor:not-allowed}.pecb-table__action-btn--danger:hover{background-color:#ff606f;color:#dc3545}.pecb-table__action-btn svg{width:20px;height:20px}.pecb-table__custom-icon{display:flex;align-items:center;justify-content:center}.pecb-table__custom-icon svg{width:20px;height:20px}@media (min-width: 768px){.pecb-table--md,.pecb-table--lg{font-size:14px}.pecb-table--md .pecb-table__cell,.pecb-table--lg .pecb-table__cell{padding:12px 16px}.pecb-table--md .pecb-table__cell--header,.pecb-table--lg .pecb-table__cell--header{padding:8px 16px}.pecb-table__pagination{padding:12px 16px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginationComponent, selector: "pecb-pagination", inputs: ["totalItems", "pageSize", "currentPage", "pageSizeOptions", "size", "variant", "showPageSizeSelector", "showItemsInfo", "maxVisiblePages", "disabled", "aria-label"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "component", type: StatusComponent, selector: "pecb-status", inputs: ["type", "variant", "size", "ariaLabel", "text", "customClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
435
- }
436
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableComponent, decorators: [{
437
- type: Component,
438
- args: [{ selector: 'pecb-table', standalone: true, imports: [CommonModule, PaginationComponent, StatusComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"pecb-table-wrapper\">\r\n <div [class]=\"containerClasses\" [style.maxHeight]=\"maxHeight\">\r\n <!-- Loading State -->\r\n <div *ngIf=\"loading\" class=\"pecb-table__loading\">\r\n <ng-container *ngIf=\"loadingTemplate; else defaultLoading\">\r\n <ng-container *ngTemplateOutlet=\"loadingTemplate\"></ng-container>\r\n </ng-container>\r\n <ng-template #defaultLoading>\r\n <div class=\"pecb-table__loading-spinner\">\r\n <svg class=\"pecb-table__spinner-icon\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-dasharray=\"31.4 31.4\" />\r\n </svg>\r\n <span>Loading...</span>\r\n </div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Table -->\r\n <table\r\n *ngIf=\"!loading\"\r\n [class]=\"tableClasses\"\r\n [attr.aria-label]=\"ariaLabel\"\r\n role=\"table\">\r\n\r\n <!-- Table Header -->\r\n <thead *ngIf=\"showHeader\" class=\"pecb-table__head\" [class.pecb-table__head--sticky]=\"stickyHeader\">\r\n <tr class=\"pecb-table__row pecb-table__row--header\" role=\"row\">\r\n <!-- Selection Checkbox Column -->\r\n <th\r\n *ngIf=\"selectable\"\r\n class=\"pecb-table__cell pecb-table__cell--header pecb-table__cell--checkbox\"\r\n role=\"columnheader\"\r\n scope=\"col\">\r\n <label class=\"pecb-table__checkbox-wrapper\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"pecb-table__checkbox\"\r\n [checked]=\"isAllSelected()\"\r\n [indeterminate]=\"isSomeSelected()\"\r\n (change)=\"toggleAllSelection()\"\r\n aria-label=\"Select all rows\" />\r\n <span class=\"pecb-table__checkbox-custom\"></span>\r\n </label>\r\n </th>\r\n\r\n <!-- Data Columns -->\r\n <th\r\n *ngFor=\"let column of columns; trackBy: trackByKey\"\r\n class=\"pecb-table__cell pecb-table__cell--header\"\r\n [class.pecb-table__cell--sortable]=\"column.sortable\"\r\n [class]=\"getAlignmentClass(column)\"\r\n [ngClass]=\"column.cssClass\"\r\n [style.width]=\"column.width\"\r\n [attr.aria-sort]=\"column.sortable ? (sortColumn === column.key ? (sortDirection === 'asc' ? 'ascending' : 'descending') : 'none') : null\"\r\n role=\"columnheader\"\r\n scope=\"col\"\r\n (click)=\"onHeaderClick(column)\"\r\n (keydown.enter)=\"onHeaderClick(column)\"\r\n (keydown.space)=\"onHeaderClick(column); $event.preventDefault()\"\r\n [attr.tabindex]=\"column.sortable ? 0 : null\">\r\n <div class=\"pecb-table__header-content\">\r\n <ng-container *ngIf=\"column.headerTemplate; else defaultHeader\">\r\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\r\n </ng-container>\r\n <ng-template #defaultHeader>\r\n <span class=\"pecb-table__header-text\">{{ column.label }}</span>\r\n </ng-template>\r\n\r\n <!-- Sort Icon -->\r\n <span *ngIf=\"column.sortable\" class=\"pecb-table__sort-icon\" [attr.data-sort]=\"getSortState(column)\">\r\n <svg *ngIf=\"getSortState(column) === 'none'\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 3L12 7H4L8 3Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n <path d=\"M8 13L4 9H12L8 13Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n </svg>\r\n <svg *ngIf=\"getSortState(column) === 'asc'\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 3L12 7H4L8 3Z\" fill=\"currentColor\"/>\r\n <path d=\"M8 13L4 9H12L8 13Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n </svg>\r\n <svg *ngIf=\"getSortState(column) === 'desc'\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 3L12 7H4L8 3Z\" fill=\"currentColor\" opacity=\"0.4\"/>\r\n <path d=\"M8 13L4 9H12L8 13Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <!-- Table Body -->\r\n <tbody class=\"pecb-table__body\">\r\n <!-- Empty State -->\r\n <tr *ngIf=\"data.length === 0\" class=\"pecb-table__row pecb-table__row--empty\">\r\n <td\r\n [attr.colspan]=\"selectable ? columns.length + 1 : columns.length\"\r\n class=\"pecb-table__cell pecb-table__cell--empty\">\r\n <ng-container *ngIf=\"emptyTemplate; else defaultEmpty\">\r\n <ng-container *ngTemplateOutlet=\"emptyTemplate\"></ng-container>\r\n </ng-container>\r\n <ng-template #defaultEmpty>\r\n <div class=\"pecb-table__empty-content\">\r\n <span class=\"pecb-table__empty-message\">{{ emptyMessage }}</span>\r\n </div>\r\n </ng-template>\r\n </td>\r\n </tr>\r\n\r\n <!-- Data Rows -->\r\n <tr\r\n *ngFor=\"let row of data; let i = index; trackBy: trackByIndex\"\r\n class=\"pecb-table__row pecb-table__row--data\"\r\n [class.pecb-table__row--selected]=\"isRowSelected(i)\"\r\n role=\"row\"\r\n (click)=\"onRowClick(row, i)\"\r\n [attr.tabindex]=\"0\"\r\n (keydown.enter)=\"onRowClick(row, i)\">\r\n\r\n <!-- Selection Checkbox -->\r\n <td\r\n *ngIf=\"selectable\"\r\n class=\"pecb-table__cell pecb-table__cell--checkbox\"\r\n role=\"cell\"\r\n (click)=\"$event.stopPropagation()\">\r\n <label class=\"pecb-table__checkbox-wrapper\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"pecb-table__checkbox\"\r\n [checked]=\"isRowSelected(i)\"\r\n (change)=\"toggleRowSelection(i)\"\r\n [attr.aria-label]=\"'Select row ' + (i + 1)\" />\r\n <span class=\"pecb-table__checkbox-custom\"></span>\r\n </label>\r\n </td>\r\n\r\n <!-- Data Cells -->\r\n <td\r\n *ngFor=\"let column of columns; trackBy: trackByKey\"\r\n class=\"pecb-table__cell\"\r\n [class]=\"getAlignmentClass(column)\"\r\n [ngClass]=\"column.cssClass\"\r\n role=\"cell\">\r\n\r\n <!-- Custom Template -->\r\n <ng-container *ngIf=\"column.cellTemplate\">\r\n <ng-container *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: getCellValue(row, column.key), row: row, column: column, index: i }\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Dynamic Component - renders any component passed via dynamicComponent -->\r\n <ng-container *ngIf=\"!column.cellTemplate && hasDynamicComponent(column)\">\r\n <ng-container\r\n *ngComponentOutlet=\"column.dynamicComponent!; inputs: getDynamicComponentInputs(row, column, i)\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Status Component - renders pecb-status -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'status'\">\r\n <pecb-status\r\n [type]=\"getStatusType(getCellValue(row, column.key), column)\"\r\n [variant]=\"getStatusVariant(column)\"\r\n [size]=\"getStatusSize(column)\">\r\n {{ getCellValue(row, column.key) }}\r\n </pecb-status>\r\n </ng-container>\r\n\r\n <!-- User Component - renders avatar + name + email -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'user'\">\r\n <div class=\"pecb-table__user-cell\">\r\n <img\r\n *ngIf=\"getUserData(row, column).avatar\"\r\n [src]=\"getUserData(row, column).avatar\"\r\n alt=\"\"\r\n class=\"pecb-table__user-avatar\">\r\n <div class=\"pecb-table__user-info\">\r\n <div class=\"pecb-table__user-name\">{{ getUserData(row, column).name }}</div>\r\n <div *ngIf=\"getUserData(row, column).secondary\" class=\"pecb-table__user-secondary\">\r\n {{ getUserData(row, column).secondary }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Action Component - renders action buttons with icons -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'action'\">\r\n <div class=\"pecb-table__action-buttons\">\r\n <button\r\n *ngFor=\"let action of getActions(column)\"\r\n class=\"pecb-table__action-btn\"\r\n [class.pecb-table__action-btn--danger]=\"action.variant === 'danger'\"\r\n [title]=\"action.tooltip || action.id\"\r\n [disabled]=\"action.disabled\"\r\n (click)=\"onActionClick(action, row, i, $event)\">\r\n <!-- View Icon -->\r\n <svg *ngIf=\"action.icon === 'view'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n <!-- Edit Icon -->\r\n <svg *ngIf=\"action.icon === 'edit'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path>\r\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"></path>\r\n </svg>\r\n <!-- Delete Icon -->\r\n <svg *ngIf=\"action.icon === 'delete'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <polyline points=\"3 6 5 6 21 6\"></polyline>\r\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path>\r\n </svg>\r\n <!-- Download Icon -->\r\n <svg *ngIf=\"action.icon === 'download'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path>\r\n <polyline points=\"7 10 12 15 17 10\"></polyline>\r\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"></line>\r\n </svg>\r\n <!-- Copy Icon -->\r\n <svg *ngIf=\"action.icon === 'copy'\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\r\n </svg>\r\n <!-- Custom Icon (SVG string) -->\r\n <span *ngIf=\"action.icon === 'custom' && action.customIcon\" class=\"pecb-table__custom-icon\" [innerHTML]=\"getSafeIcon(action.customIcon)\"></span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Default Text -->\r\n <ng-container *ngIf=\"!column.cellTemplate && !hasDynamicComponent(column) && getColumnType(column) === 'text'\">\r\n {{ getCellValue(row, column.key) }}\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Pagination (outside table container) -->\r\n <div *ngIf=\"showPagination && !loading && data.length > 0\" [class]=\"paginationClasses\">\r\n <pecb-pagination\r\n [totalItems]=\"totalItems\"\r\n [pageSize]=\"pageSize\"\r\n [currentPage]=\"currentPage\"\r\n [pageSizeOptions]=\"pageSizeOptions\"\r\n [showPageSizeSelector]=\"showPageSizeSelector\"\r\n [variant]=\"paginationVariant\"\r\n size=\"md\"\r\n (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\">\r\n </pecb-pagination>\r\n </div>\r\n</div>\r\n", styles: [".pecb-table-wrapper{width:100%}.pecb-table-container{width:100%;background-color:#fff;border-radius:8px;overflow:hidden;border:1px solid #f4f4f4}.pecb-table-container--sticky{position:relative;overflow:auto}.pecb-table{width:100%;border-collapse:collapse;border-spacing:0;font-family:Plus Jakarta Sans,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;color:#313131}.pecb-table--sm{font-size:12px}.pecb-table--sm .pecb-table__cell,.pecb-table--sm .pecb-table__cell--header{padding:8px 12px}.pecb-table--md{font-size:14px}.pecb-table--md .pecb-table__cell{padding:16px 18px}.pecb-table--md .pecb-table__cell--header{padding:12px 18px}.pecb-table--lg{font-size:16px}.pecb-table--lg .pecb-table__cell{padding:18px 20px}.pecb-table--lg .pecb-table__cell--header{padding:16px 20px}.pecb-table--default .pecb-table__row--data{border-bottom:1px solid #f4f4f4}.pecb-table--default .pecb-table__row--data:last-child{border-bottom:none}.pecb-table--striped .pecb-table__row--data:nth-child(2n){background-color:#fafafa}.pecb-table--bordered .pecb-table__cell{border:1px solid #f4f4f4}.pecb-table--hoverable .pecb-table__row--data{transition:background-color .15s ease-in-out}.pecb-table--hoverable .pecb-table__row--data:hover{background-color:#ececec}.pecb-table--selectable .pecb-table__row--data{cursor:pointer}.pecb-table__head{background-color:#212427}.pecb-table__head--sticky{position:sticky;top:0;z-index:1020}.pecb-table__row--header{text-transform:uppercase;height:58px}.pecb-table__row--data{background-color:#fff;height:58px}.pecb-table__row--data:focus{outline:none}.pecb-table__row--data:focus-visible{outline:none}.pecb-table__row--selected{background-color:#a11e290d}.pecb-table__row--selected:hover{background-color:#a11e2914}.pecb-table__row--empty{background-color:#fff}.pecb-table__cell{text-align:left;vertical-align:middle;white-space:nowrap}.pecb-table__cell--header{font-weight:500;font-size:12px;color:#fff;letter-spacing:.02em;-webkit-user-select:none;user-select:none}.pecb-table__cell--sortable{cursor:pointer;transition:background-color .15s ease-in-out}.pecb-table__cell--sortable:hover{background-color:#ffffff1a}.pecb-table__cell--sortable:focus{outline:none;box-shadow:inset 0 0 0 2px #fff}.pecb-table__cell--sortable:focus-visible{box-shadow:inset 0 0 0 2px #fff}.pecb-table__cell--checkbox{width:48px;text-align:center}.pecb-table__cell--center{text-align:center}.pecb-table__cell--right{text-align:right}.pecb-table__cell--empty{text-align:center;padding:48px 18px}.pecb-table__header-content{display:flex;align-items:center;gap:8px}.pecb-table__header-text{flex:1}.pecb-table__sort-icon{display:flex;align-items:center;justify-content:center;color:#ffffff80;transition:color .15s ease-in-out}.pecb-table__sort-icon svg{width:16px;height:16px}.pecb-table__sort-icon[data-sort=asc],.pecb-table__sort-icon[data-sort=desc]{color:#fff}.pecb-table__checkbox-wrapper{display:inline-flex;align-items:center;justify-content:center;position:relative;cursor:pointer}.pecb-table__checkbox{position:absolute;opacity:0;width:0;height:0}.pecb-table__checkbox:checked+.pecb-table__checkbox-custom{background-color:#a11e29;border-color:#a11e29}.pecb-table__checkbox:checked+.pecb-table__checkbox-custom:after{display:block}.pecb-table__checkbox:indeterminate+.pecb-table__checkbox-custom{background-color:#a11e29;border-color:#a11e29}.pecb-table__checkbox:indeterminate+.pecb-table__checkbox-custom:before{display:block}.pecb-table__checkbox:indeterminate+.pecb-table__checkbox-custom:after{display:none}.pecb-table__checkbox:focus+.pecb-table__checkbox-custom{box-shadow:0 0 0 2px #a11e2940}.pecb-table__checkbox-custom{width:18px;height:18px;border:2px solid #ececec;border-radius:6px;background-color:#fff;position:relative;transition:all .15s ease-in-out}.pecb-table__checkbox-custom:after{content:\"\";display:none;position:absolute;left:5px;top:2px;width:4px;height:8px;border:solid #ffffff;border-width:0 2px 2px 0;transform:rotate(45deg)}.pecb-table__checkbox-custom:before{content:\"\";display:none;position:absolute;left:3px;top:6px;width:8px;height:2px;background-color:#fff}.pecb-table__empty-content{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px}.pecb-table__empty-message{color:#919191;font-size:14px}.pecb-table__loading{display:flex;align-items:center;justify-content:center;padding:48px;min-height:200px}.pecb-table__loading-spinner{display:flex;flex-direction:column;align-items:center;gap:12px;color:#616161}.pecb-table__spinner-icon{width:32px;height:32px;animation:spin 1s linear infinite;color:#a11e29}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.pecb-table__pagination{padding:16px 0;margin-top:16px}.pecb-table__pagination--bordered{padding:16px 18px;background-color:#fff;border:1px solid #ececec;border-radius:12px}.pecb-table__user-cell{display:flex;align-items:center;gap:12px}.pecb-table__user-avatar{width:40px;height:40px;border-radius:9999px;object-fit:cover;flex-shrink:0}.pecb-table__user-info{display:flex;flex-direction:column;min-width:0}.pecb-table__user-name{font-weight:500;color:#313131;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pecb-table__user-secondary{font-size:12px;color:#919191;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pecb-table__action-buttons{display:flex;gap:8px;justify-content:center}.pecb-table__action-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;color:#919191;cursor:pointer;border-radius:6px;transition:all .15s ease-in-out;padding:0}.pecb-table__action-btn:hover{background-color:#ececec;color:#313131}.pecb-table__action-btn:focus{outline:none;box-shadow:0 0 0 2px #a11e2940}.pecb-table__action-btn:disabled{opacity:.5;cursor:not-allowed}.pecb-table__action-btn--danger:hover{background-color:#ff606f;color:#dc3545}.pecb-table__action-btn svg{width:20px;height:20px}.pecb-table__custom-icon{display:flex;align-items:center;justify-content:center}.pecb-table__custom-icon svg{width:20px;height:20px}@media (min-width: 768px){.pecb-table--md,.pecb-table--lg{font-size:14px}.pecb-table--md .pecb-table__cell,.pecb-table--lg .pecb-table__cell{padding:12px 16px}.pecb-table--md .pecb-table__cell--header,.pecb-table--lg .pecb-table__cell--header{padding:8px 16px}.pecb-table__pagination{padding:12px 16px}}\n"] }]
439
- }], ctorParameters: () => [{ type: i1.DomSanitizer }], propDecorators: { columns: [{
440
- type: Input
441
- }], data: [{
442
- type: Input
443
- }], size: [{
444
- type: Input
445
- }], variant: [{
446
- type: Input
447
- }], showHeader: [{
448
- type: Input
449
- }], hoverable: [{
450
- type: Input
451
- }], showPagination: [{
452
- type: Input
453
- }], totalItems: [{
454
- type: Input
455
- }], currentPage: [{
456
- type: Input
457
- }], pageSize: [{
458
- type: Input
459
- }], pageSizeOptions: [{
460
- type: Input
461
- }], showPageSizeSelector: [{
462
- type: Input
463
- }], paginationVariant: [{
464
- type: Input
465
- }], emptyMessage: [{
466
- type: Input
467
- }], loading: [{
468
- type: Input
469
- }], selectable: [{
470
- type: Input
471
- }], selectedIndices: [{
472
- type: Input
473
- }], stickyHeader: [{
474
- type: Input
475
- }], maxHeight: [{
476
- type: Input
477
- }], sortColumn: [{
478
- type: Input
479
- }], sortDirection: [{
480
- type: Input
481
- }], ariaLabel: [{
482
- type: Input,
483
- args: ['aria-label']
484
- }], pageChange: [{
485
- type: Output
486
- }], pageSizeChange: [{
487
- type: Output
488
- }], rowClick: [{
489
- type: Output
490
- }], rowAction: [{
491
- type: Output
492
- }], sortChange: [{
493
- type: Output
494
- }], selectionChange: [{
495
- type: Output
496
- }], emptyTemplate: [{
497
- type: ContentChild,
498
- args: ['emptyTemplate']
499
- }], loadingTemplate: [{
500
- type: ContentChild,
501
- args: ['loadingTemplate']
502
- }] } });
503
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWktY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWktY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWix1QkFBdUIsRUFDdkIsWUFBWSxHQUdiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUvQyxPQUFPLEVBQW1CLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDMUYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDOzs7O0FBd0k3RDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFTSCxNQUFNLE9BQU8sY0FBYztJQUN6QixZQUFvQixTQUF1QjtRQUF2QixjQUFTLEdBQVQsU0FBUyxDQUFjO1FBRTNDOztXQUVHO1FBQ00sWUFBTyxHQUFzQixFQUFFLENBQUM7UUFFekM7O1dBRUc7UUFDTSxTQUFJLEdBQVUsRUFBRSxDQUFDO1FBRTFCOzs7V0FHRztRQUNNLFNBQUksR0FBYyxJQUFJLENBQUM7UUFFaEM7OztXQUdHO1FBQ00sWUFBTyxHQUFpQixTQUFTLENBQUM7UUFFM0M7OztXQUdHO1FBQ00sZUFBVSxHQUFHLElBQUksQ0FBQztRQUUzQjs7O1dBR0c7UUFDTSxjQUFTLEdBQUcsSUFBSSxDQUFDO1FBRTFCOzs7V0FHRztRQUNNLG1CQUFjLEdBQUcsSUFBSSxDQUFDO1FBRS9COztXQUVHO1FBQ00sZUFBVSxHQUFHLENBQUMsQ0FBQztRQUV4Qjs7O1dB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O2dCQUtHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBTUcsT0FBTztzQkFBZixLQUFLO2dCQU1HLFVBQVU7c0JBQWxCLEtBQUs7Z0JBS0csZUFBZTtzQkFBdkIsS0FBSztnQkFNRyxZQUFZO3NCQUFwQixLQUFLO2dCQUtHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBS0csVUFBVTtzQkFBbEIsS0FBSztnQkFLRyxhQUFhO3NCQUFyQixLQUFLO2dCQUtlLFNBQVM7c0JBQTdCLEtBQUs7dUJBQUMsWUFBWTtnQkFLVCxVQUFVO3NCQUFuQixNQUFNO2dCQUtHLGNBQWM7c0JBQXZCLE1BQU07Z0JBS0csUUFBUTtzQkFBakIsTUFBTTtnQkFLRyxTQUFTO3NCQUFsQixNQUFNO2dCQUtHLFVBQVU7c0JBQW5CLE1BQU07Z0JBS0csZUFBZTtzQkFBeEIsTUFBTTtnQkFLd0IsYUFBYTtzQkFBM0MsWUFBWTt1QkFBQyxlQUFlO2dCQUtJLGVBQWU7c0JBQS9DLFlBQVk7dUJBQUMsaUJBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgSW5wdXQsXHJcbiAgT3V0cHV0LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcclxuICBDb250ZW50Q2hpbGQsXHJcbiAgVGVtcGxhdGVSZWYsXHJcbiAgVHlwZSxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlSHRtbCB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5pbXBvcnQgeyBQYWdlQ2hhbmdlRXZlbnQsIFBhZ2luYXRpb25Db21wb25lbnQgfSBmcm9tICcuLi9wYWdpbmF0aW9uL3BhZ2luYXRpb24uY29tcG9uZW50JztcclxuaW1wb3J0IHsgU3RhdHVzQ29tcG9uZW50IH0gZnJvbSAnLi4vc3RhdHVzL3N0YXR1cy5jb21wb25lbnQnO1xyXG5cclxuLyoqXHJcbiAqIERlZmluZXMgdGhlIGF2YWlsYWJsZSB0YWJsZSBzaXplc1xyXG4gKi9cclxuZXhwb3J0IHR5cGUgVGFibGVTaXplID0gJ3NtJyB8ICdtZCcgfCAnbGcnO1xyXG5cclxuLyoqXHJcbiAqIERlZmluZXMgdGhlIGF2YWlsYWJsZSB0YWJsZSB2YXJpYW50c1xyXG4gKi9cclxuZXhwb3J0IHR5cGUgVGFibGVWYXJpYW50ID0gJ2RlZmF1bHQnIHwgJ3N0cmlwZWQnIHwgJ2JvcmRlcmVkJztcclxuXHJcbi8qKlxyXG4gKiBEZWZpbmVzIGJ1aWx0LWluIGNvbHVtbiB0eXBlc1xyXG4gKi9cclxuZXhwb3J0IHR5cGUgUGVjYlRhYmxlQ29sdW1uVHlwZSA9ICd0ZXh0JyB8ICdzdGF0dXMnIHwgJ2FjdGlvbicgfCAndXNlcicgfCAnY3VzdG9tJztcclxuXHJcbi8qKlxyXG4gKiBEZWZpbmVzIGJ1aWx0LWluIGNvbXBvbmVudCBuYW1lcyBmb3IgY29sdW1uc1xyXG4gKi9cclxuZXhwb3J0IHR5cGUgUGVjYlRhYmxlQ29sdW1uQ29tcG9uZW50ID0gJ3N0YXR1cycgfCAnYWN0aW9uJyB8ICd1c2VyJztcclxuXHJcbi8qKlxyXG4gKiBBY3Rpb24gYnV0dG9uIGRlZmluaXRpb24gZm9yIGFjdGlvbiBjb2x1bW5zXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlQWN0aW9uIHtcclxuICAvKiogVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBhY3Rpb24gKi9cclxuICBpZDogc3RyaW5nO1xyXG4gIC8qKiBJY29uIG5hbWUgb3IgdHlwZSAqL1xyXG4gIGljb246ICd2aWV3JyB8ICdlZGl0JyB8ICdkZWxldGUnIHwgJ2Rvd25sb2FkJyB8ICdjb3B5JyB8ICdjdXN0b20nO1xyXG4gIC8qKiBUb29sdGlwL3RpdGxlIHRleHQgKi9cclxuICB0b29sdGlwPzogc3RyaW5nO1xyXG4gIC8qKiBDdXN0b20gaWNvbiBTVkcgKHdoZW4gaWNvbiBpcyAnY3VzdG9tJykgKi9cclxuICBjdXN0b21JY29uPzogc3RyaW5nO1xyXG4gIC8qKiBXaGV0aGVyIHRoZSBhY3Rpb24gaXMgZGlzYWJsZWQgKi9cclxuICBkaXNhYmxlZD86IGJvb2xlYW47XHJcbiAgLyoqIFZhcmlhbnQgZm9yIHN0eWxpbmcgKGUuZy4sICdkYW5nZXInIGZvciBkZWxldGUpICovXHJcbiAgdmFyaWFudD86ICdkZWZhdWx0JyB8ICdkYW5nZXInO1xyXG4gIC8qKiBDbGljayBoYW5kbGVyIGZvciB0aGlzIHNwZWNpZmljIGFjdGlvbiAqL1xyXG4gIGFjdGlvbj86IChyb3c6IGFueSwgaW5kZXg6IG51bWJlcikgPT4gdm9pZDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFN0YXR1cyBtYXBwaW5nIGNvbmZpZ3VyYXRpb25cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVTdGF0dXNDb25maWcge1xyXG4gIC8qKiBNYXAgb2YgdmFsdWUgdG8gc3RhdHVzIHR5cGUgKi9cclxuICB0eXBlTWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcclxuICAvKiogU3RhdHVzIHZhcmlhbnQgKi9cclxuICB2YXJpYW50PzogJ2FjY2VudCcgfCAnZmlsbGVkJyB8ICdvdXRsaW5lJztcclxuICAvKiogU3RhdHVzIHNpemUgKi9cclxuICBzaXplPzogJ3NtJyB8ICdtZCcgfCAnbGcnO1xyXG59XHJcblxyXG4vKipcclxuICogVXNlciBjZWxsIGNvbmZpZ3VyYXRpb25cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVVc2VyQ29uZmlnIHtcclxuICAvKiogS2V5IGZvciB0aGUgYXZhdGFyL2ltYWdlIFVSTCAqL1xyXG4gIGF2YXRhcktleT86IHN0cmluZztcclxuICAvKiogS2V5IGZvciB0aGUgbmFtZSAqL1xyXG4gIG5hbWVLZXk/OiBzdHJpbmc7XHJcbiAgLyoqIEtleSBmb3IgdGhlIHNlY29uZGFyeSB0ZXh0IChlLmcuLCBlbWFpbCkgKi9cclxuICBzZWNvbmRhcnlLZXk/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb2x1bW4gZGVmaW5pdGlvbiBmb3IgdGhlIHRhYmxlXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFBlY2JUYWJsZUNvbHVtbiB7XHJcbiAgLyoqIFVuaXF1ZSBrZXkgZm9yIHRoZSBjb2x1bW4sIHVzZWQgdG8gYWNjZXNzIGRhdGEgKi9cclxuICBrZXk6IHN0cmluZztcclxuICAvKiogRGlzcGxheSBsYWJlbCBmb3IgdGhlIGNvbHVtbiBoZWFkZXIgKi9cclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIC8qKiBXaWR0aCBvZiB0aGUgY29sdW1uIChlLmcuLCAnMjAwcHgnLCAnMjAlJywgJ2F1dG8nKSAqL1xyXG4gIHdpZHRoPzogc3RyaW5nO1xyXG4gIC8qKiBBbGlnbm1lbnQgb2YgdGhlIGNvbHVtbiBjb250ZW50ICovXHJcbiAgYWxpZ24/OiAnbGVmdCcgfCAnY2VudGVyJyB8ICdyaWdodCc7XHJcbiAgLyoqIFdoZXRoZXIgdGhlIGNvbHVtbiBpcyBzb3J0YWJsZSAqL1xyXG4gIHNvcnRhYmxlPzogYm9vbGVhbjtcclxuICAvKiogQ3VzdG9tIHRlbXBsYXRlIHJlZmVyZW5jZSBmb3IgY2VsbCBjb250ZW50ICovXHJcbiAgY2VsbFRlbXBsYXRlPzogVGVtcGxhdGVSZWY8YW55PjtcclxuICAvKiogQ3VzdG9tIHRlbXBsYXRlIHJlZmVyZW5jZSBmb3IgaGVhZGVyIGNvbnRlbnQgKi9cclxuICBoZWFkZXJUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgLyoqIENTUyBjbGFzcyB0byBhcHBseSB0byB0aGUgY29sdW1uICovXHJcbiAgY3NzQ2xhc3M/OiBzdHJpbmc7XHJcbiAgLyoqIEJ1aWx0LWluIGNvbHVtbiB0eXBlIChkZXByZWNhdGVkLCB1c2UgJ2NvbXBvbmVudCcgaW5zdGVhZCkgKi9cclxuICB0eXBlPzogUGVjYlRhYmxlQ29sdW1uVHlwZTtcclxuICAvKiogQnVpbHQtaW4gY29tcG9uZW50IHRvIHJlbmRlcjogJ3N0YXR1cycsICdhY3Rpb24nLCAndXNlcicgKi9cclxuICBjb21wb25lbnQ/OiBQZWNiVGFibGVDb2x1bW5Db21wb25lbnQ7XHJcbiAgLyoqIER5bmFtaWMgY29tcG9uZW50IGNsYXNzIHRvIHJlbmRlciBpbiB0aGUgY2VsbCAoZS5nLiwgU3RhdHVzQ29tcG9uZW50KSAqL1xyXG4gIGR5bmFtaWNDb21wb25lbnQ/OiBUeXBlPGFueT47XHJcbiAgLyoqIElucHV0cyB0byBwYXNzIHRvIHRoZSBkeW5hbWljIGNvbXBvbmVudCAqL1xyXG4gIGNvbXBvbmVudElucHV0cz86IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgLyoqIEZ1bmN0aW9uIHRvIGdlbmVyYXRlIGR5bmFtaWMgaW5wdXRzIGJhc2VkIG9uIHJvdyBkYXRhICovXHJcbiAgY29tcG9uZW50SW5wdXRzRm4/OiAocm93OiBhbnksIHZhbHVlOiBhbnksIGluZGV4OiBudW1iZXIpID0+IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgLyoqIEFjdGlvbiBidXR0b25zIGNvbmZpZ3VyYXRpb24gKHdoZW4gY29tcG9uZW50IGlzICdhY3Rpb24nKSAqL1xyXG4gIGFjdGlvbnM/OiBUYWJsZUFjdGlvbltdO1xyXG4gIC8qKiBTdGF0dXMgY29uZmlndXJhdGlvbiAod2hlbiBjb21wb25lbnQgaXMgJ3N0YXR1cycpICovXHJcbiAgc3RhdHVzQ29uZmlnPzogVGFibGVTdGF0dXNDb25maWc7XHJcbiAgLyoqIFVzZXIgY2VsbCBjb25maWd1cmF0aW9uICh3aGVuIGNvbXBvbmVudCBpcyAndXNlcicpICovXHJcbiAgdXNlckNvbmZpZz86IFRhYmxlVXNlckNvbmZpZztcclxufVxyXG5cclxuLyoqXHJcbiAqIFNvcnQgZXZlbnQgZW1pdHRlZCB3aGVuIGEgc29ydGFibGUgY29sdW1uIGlzIGNsaWNrZWRcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVTb3J0RXZlbnQge1xyXG4gIC8qKiBDb2x1bW4ga2V5IHRoYXQgd2FzIHNvcnRlZCAqL1xyXG4gIGNvbHVtbjogc3RyaW5nO1xyXG4gIC8qKiBTb3J0IGRpcmVjdGlvbiAqL1xyXG4gIGRpcmVjdGlvbjogJ2FzYycgfCAnZGVzYycgfCBudWxsO1xyXG59XHJcblxyXG4vKipcclxuICogUm93IGFjdGlvbiBldmVudCBlbWl0dGVkIHdoZW4gYW4gYWN0aW9uIGJ1dHRvbiBpcyBjbGlja2VkXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlUm93QWN0aW9uRXZlbnQge1xyXG4gIC8qKiBUeXBlIG9mIGFjdGlvbiBwZXJmb3JtZWQgKi9cclxuICBhY3Rpb246IHN0cmluZztcclxuICAvKiogUm93IGRhdGEgZm9yIHRoZSBhY3Rpb24gKi9cclxuICByb3c6IGFueTtcclxuICAvKiogUm93IGluZGV4ICovXHJcbiAgaW5kZXg6IG51bWJlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJvdyBzZWxlY3Rpb24gZXZlbnQgZW1pdHRlZCB3aGVuIHJvd3MgYXJlIHNlbGVjdGVkL2Rlc2VsZWN0ZWRcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVTZWxlY3Rpb25FdmVudCB7XHJcbiAgLyoqIFNlbGVjdGVkIHJvd3MgZGF0YSAqL1xyXG4gIHNlbGVjdGVkUm93czogYW55W107XHJcbiAgLyoqIFNlbGVjdGVkIHJvdyBpbmRpY2VzICovXHJcbiAgc2VsZWN0ZWRJbmRpY2VzOiBudW1iZXJbXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRhYmxlIGNvbXBvbmVudCBmb3IgZGlzcGxheWluZyB0YWJ1bGFyIGRhdGEgd2l0aCBwYWdpbmF0aW9uIHN1cHBvcnQuXHJcbiAqXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYGh0bWxcclxuICogPHBlY2ItdGFibGVcclxuICogICBbY29sdW1uc109XCJjb2x1bW5zXCJcclxuICogICBbZGF0YV09XCJ0YWJsZURhdGFcIlxyXG4gKiAgIFtzaG93UGFnaW5hdGlvbl09XCJ0cnVlXCJcclxuICogICBbdG90YWxJdGVtc109XCI1MDBcIlxyXG4gKiAgIFtwYWdlU2l6ZV09XCIxNVwiXHJcbiAqICAgKHBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIlxyXG4gKiAgIChyb3dBY3Rpb24pPVwib25Sb3dBY3Rpb24oJGV2ZW50KVwiPlxyXG4gKiA8L3BlY2ItdGFibGU+XHJcbiAqIGBgYFxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdwZWNiLXRhYmxlJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFBhZ2luYXRpb25Db21wb25lbnQsIFN0YXR1c0NvbXBvbmVudF0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3RhYmxlLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi90YWJsZS5jb21wb25lbnQuc2NzcyddLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVGFibGVDb21wb25lbnQge1xyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIpIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbHVtbiBkZWZpbml0aW9ucyBmb3IgdGhlIHRhYmxlXHJcbiAgICovXHJcbiAgQElucHV0KCkgY29sdW1uczogUGVjYlRhYmxlQ29sdW1uW10gPSBbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGF0YSBhcnJheSB0byBkaXNwbGF5IGluIHRoZSB0YWJsZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGRhdGE6IGFueVtdID0gW107XHJcblxyXG4gIC8qKlxyXG4gICAqIFNpemUgdmFyaWFudCBvZiB0aGUgdGFibGVcclxuICAgKiBAZGVmYXVsdCAnbWQnXHJcbiAgICovXHJcbiAgQElucHV0KCkgc2l6ZTogVGFibGVTaXplID0gJ21kJztcclxuXHJcbiAgLyoqXHJcbiAgICogVmlzdWFsIHZhcmlhbnQgb2YgdGhlIHRhYmxlXHJcbiAgICogQGRlZmF1bHQgJ2RlZmF1bHQnXHJcbiAgICovXHJcbiAgQElucHV0KCkgdmFyaWFudDogVGFibGVWYXJpYW50ID0gJ2RlZmF1bHQnO1xyXG5cclxuICAvKipcclxuICAgKiBXaGV0aGVyIHRvIHNob3cgdGhlIHRhYmxlIGhlYWRlclxyXG4gICAqIEBkZWZhdWx0IHRydWVcclxuICAgKi9cclxuICBASW5wdXQoKSBzaG93SGVhZGVyID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogV2hldGhlciB0byBlbmFibGUgcm93IGhvdmVyIGVmZmVjdFxyXG4gICAqIEBkZWZhdWx0IHRydWVcclxuICAgKi9cclxuICBASW5wdXQoKSBob3ZlcmFibGUgPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBXaGV0aGVyIHRvIHNob3cgcGFnaW5hdGlvblxyXG4gICAqIEBkZWZhdWx0IHRydWVcclxuICAgKi9cclxuICBASW5wdXQoKSBzaG93UGFnaW5hdGlvbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvdGFsIG51bWJlciBvZiBpdGVtcyBmb3IgcGFnaW5hdGlvblxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHRvdGFsSXRlbXMgPSAwO1xyXG5cclxuICAvKipcclxuICAgKiBDdXJyZW50IHBhZ2UgbnVtYmVyICgxLWJhc2VkKVxyXG4gICAqIEBkZWZhdWx0IDFcclxuICAgKi9cclxuICBASW5wdXQoKSBjdXJyZW50UGFnZSA9IDE7XHJcblxyXG4gIC8qKlxyXG4gICAqIE51bWJlciBvZiBpdGVtcyBwZXIgcGFnZVxyXG4gICAqIEBkZWZhdWx0IDE1XHJcbiAgICovXHJcbiAgQElucHV0KCkgcGFnZVNpemUgPSAxNTtcclxuXHJcbiAgLyoqXHJcbiAgICogQXZhaWxhYmxlIHBhZ2Ugc2l6ZSBvcHRpb25zXHJcbiAgICovXHJcbiAgQElucHV0KCkgcGFnZVNpemVPcHRpb25zOiBudW1iZXJbXSA9IFsxMCwgMTUsIDI1LCA1MF07XHJcblxyXG4gIC8qKlxyXG4gICAqIFdoZXRoZXIgdG8gc2hvdyBwYWdlIHNpemUgc2VsZWN0b3IgaW4gcGFnaW5hdGlvblxyXG4gICAqIEBkZWZhdWx0IHRydWVcclxuICAgKi9cclxuICBASW5wdXQoKSBzaG93UGFnZVNpemVTZWxlY3RvciA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhZ2luYXRpb24gdmFyaWFudFxyXG4gICAqIEBkZWZhdWx0ICdmdWxsJ1xyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHBhZ2luYXRpb25WYXJpYW50OiAnZnVsbCcgfCAnY29tcGFjdCcgfCAnbWluaW1hbCcgfCAnY2VudGVyZWQnID0gJ2Z1bGwnO1xyXG5cclxuICAvKipcclxuICAgKiBNZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiB0aGVyZSBpcyBubyBkYXRhXHJcbiAgICovXHJcbiAgQElucHV0KCkgZW1wdHlNZXNzYWdlID0gJ1RoZXJlIGFyZSBubyBlbnRyaWVzIHlldC4nO1xyXG5cclxuICAvKipcclxuICAgKiBXaGV0aGVyIHRvIHNob3cgbG9hZGluZyBzdGF0ZVxyXG4gICAqIEBkZWZhdWx0IGZhbHNlXHJcbiAgICovXHJcbiAgQElucHV0KCkgbG9hZGluZyA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBXaGV0aGVyIHRvIGVuYWJsZSByb3cgc2VsZWN0aW9uXHJcbiAgICogQGRlZmF1bHQgZmFsc2VcclxuICAgKi9cclxuICBASW5wdXQoKSBzZWxlY3RhYmxlID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEN1cnJlbnRseSBzZWxlY3RlZCByb3cgaW5kaWNlc1xyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHNlbGVjdGVkSW5kaWNlczogbnVtYmVyW10gPSBbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogV2hldGhlciB0aGUgdGFibGUgaGFzIGEgZml4ZWQgaGVhZGVyXHJcbiAgICogQGRlZmF1bHQgZmFsc2VcclxuICAgKi9cclxuICBASW5wdXQoKSBzdGlja3lIZWFkZXIgPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogTWF4aW11bSBoZWlnaHQgb2YgdGhlIHRhYmxlIGJvZHkgKGVuYWJsZXMgc2Nyb2xsaW5nKVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIG1heEhlaWdodD86IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogQ29sdW1uIGtleSBjdXJyZW50bHkgYmVpbmcgc29ydGVkXHJcbiAgICovXHJcbiAgQElucHV0KCkgc29ydENvbHVtbj86IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogQ3VycmVudCBzb3J0IGRpcmVjdGlvblxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHNvcnREaXJlY3Rpb246ICdhc2MnIHwgJ2Rlc2MnIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIEFSSUEgbGFiZWwgZm9yIHRoZSB0YWJsZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgnYXJpYS1sYWJlbCcpIGFyaWFMYWJlbCA9ICdEYXRhIHRhYmxlJztcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHRlZCB3aGVuIGEgcGFnZSBjaGFuZ2Ugb2NjdXJzXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIHBhZ2VDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFBhZ2VDaGFuZ2VFdmVudD4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHRlZCB3aGVuIHBhZ2Ugc2l6ZSBjaGFuZ2VzXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIHBhZ2VTaXplQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXR0ZWQgd2hlbiBhIHJvdyBpcyBjbGlja2VkXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIHJvd0NsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjx7IHJvdzogYW55OyBpbmRleDogbnVtYmVyIH0+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXR0ZWQgd2hlbiBhIHJvdyBhY3Rpb24gaXMgdHJpZ2dlcmVkXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIHJvd0FjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8VGFibGVSb3dBY3Rpb25FdmVudD4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHRlZCB3aGVuIHNvcnRpbmcgY2hhbmdlc1xyXG4gICAqL1xyXG4gIEBPdXRwdXQoKSBzb3J0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxUYWJsZVNvcnRFdmVudD4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHRlZCB3aGVuIHJvdyBzZWxlY3Rpb24gY2hhbmdlc1xyXG4gICAqL1xyXG4gIEBPdXRwdXQoKSBzZWxlY3Rpb25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFRhYmxlU2VsZWN0aW9uRXZlbnQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEN1c3RvbSB0ZW1wbGF0ZSBmb3IgZW1wdHkgc3RhdGVcclxuICAgKi9cclxuICBAQ29udGVudENoaWxkKCdlbXB0eVRlbXBsYXRlJykgZW1wdHlUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPGFueT47XHJcblxyXG4gIC8qKlxyXG4gICAqIEN1c3RvbSB0ZW1wbGF0ZSBmb3IgbG9hZGluZyBzdGF0ZVxyXG4gICAqL1xyXG4gIEBDb250ZW50Q2hpbGQoJ2xvYWRpbmdUZW1wbGF0ZScpIGxvYWRpbmdUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPGFueT47XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgdGhlIENTUyBjbGFzc2VzIGZvciB0aGUgdGFibGUgY29udGFpbmVyXHJcbiAgICovXHJcbiAgZ2V0IGNvbnRhaW5lckNsYXNzZXMoKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGNsYXNzZXMgPSBbJ3BlY2ItdGFibGUtY29udGFpbmVyJ107XHJcblxyXG4gICAgaWYgKHRoaXMuc3RpY2t5SGVhZGVyKSB7XHJcbiAgICAgIGNsYXNzZXMucHVzaCgncGVjYi10YWJsZS1jb250YWluZXItLXN0aWNreScpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjbGFzc2VzLmpvaW4oJyAnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgdGhlIENTUyBjbGFzc2VzIGZvciB0aGUgcGFnaW5hdGlvbiBjb250YWluZXJcclxuICAgKi9cclxuICBnZXQgcGFnaW5hdGlvbkNsYXNzZXMoKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGNsYXNzZXMgPSBbJ3BlY2ItdGFibGVfX3BhZ2luYXRpb24nXTtcclxuXHJcbiAgICBpZiAodGhpcy5wYWdpbmF0aW9uVmFyaWFudCA9PT0gJ2Z1bGwnIHx8IHRoaXMucGFnaW5hdGlvblZhcmlhbnQgPT09ICdjb21wYWN0Jykge1xyXG4gICAgICBjbGFzc2VzLnB1c2goJ3BlY2ItdGFibGVfX3BhZ2luYXRpb24tLWJvcmRlcmVkJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNsYXNzZXMuam9pbignICcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyB0aGUgQ1NTIGNsYXNzZXMgZm9yIHRoZSB0YWJsZSBlbGVtZW50XHJcbiAgICovXHJcbiAgZ2V0IHRhYmxlQ2xhc3NlcygpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgY2xhc3NlcyA9IFsncGVjYi10YWJsZScsIGBwZWNiLXRhYmxlLS0ke3RoaXMuc2l6ZX1gLCBgcGVjYi10YWJsZS0tJHt0aGlzLnZhcmlhbnR9YF07XHJcblxyXG4gICAgaWYgKHRoaXMuaG92ZXJhYmxlKSB7XHJcbiAgICAgIGNsYXNzZXMucHVzaCgncGVjYi10YWJsZS0taG92ZXJhYmxlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc2VsZWN0YWJsZSkge1xyXG4gICAgICBjbGFzc2VzLnB1c2goJ3BlY2ItdGFibGUtLXNlbGVjdGFibGUnKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY2xhc3Nlcy5qb2luKCcgJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIHRoZSB2YWx1ZSBmcm9tIGEgcm93IGZvciBhIGdpdmVuIGNvbHVtbiBrZXlcclxuICAgKiBTdXBwb3J0cyBuZXN0ZWQga2V5cyBsaWtlICd1c2VyLm5hbWUnXHJcbiAgICovXHJcbiAgZ2V0Q2VsbFZhbHVlKHJvdzogYW55LCBrZXk6IHN0cmluZyk6IGFueSB7XHJcbiAgICBpZiAoIXJvdyB8fCAha2V5KSByZXR1cm4gJyc7XHJcblxyXG4gICAgY29uc3Qga2V5cyA9IGtleS5zcGxpdCgnLicpO1xyXG4gICAgbGV0IHZhbHVlID0gcm93O1xyXG5cclxuICAgIGZvciAoY29uc3QgayBvZiBrZXlzKSB7XHJcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XHJcbiAgICAgIHZhbHVlID0gdmFsdWVba107XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbHVlID8/ICcnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyB0aGUgYWxpZ25tZW50IGNsYXNzIGZvciBhIGNvbHVtblxyXG4gICAqL1xyXG4gIGdldEFsaWdubWVudENsYXNzKGNvbHVtbjogUGVjYlRhYmxlQ29sdW1uKTogc3RyaW5nIHtcclxuICAgIGlmICghY29sdW1uLmFsaWduIHx8IGNvbHVtbi5hbGlnbiA9PT0gJ2xlZnQnKSByZXR1cm4gJyc7XHJcbiAgICByZXR1cm4gYHBlY2ItdGFibGVfX2NlbGwtLSR7Y29sdW1uLmFsaWdufWA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIHJvdyBjbGljayBldmVudHNcclxuICAgKi9cclxuICBvblJvd0NsaWNrKHJvdzogYW55LCBpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5zZWxlY3RhYmxlKSB7XHJcbiAgICAgIHRoaXMudG9nZ2xlUm93U2VsZWN0aW9uKGluZGV4KTtcclxuICAgIH1cclxuICAgIHRoaXMucm93Q2xpY2suZW1pdCh7IHJvdywgaW5kZXggfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIHJvdyBhY3Rpb24gYnV0dG9uIGNsaWNrc1xyXG4gICAqL1xyXG4gIG9uUm93QWN0aW9uKGFjdGlvbjogc3RyaW5nLCByb3c6IGFueSwgaW5kZXg6IG51bWJlciwgZXZlbnQ6IEV2ZW50KTogdm9pZCB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIHRoaXMucm93QWN0aW9uLmVtaXQoeyBhY3Rpb24sIHJvdywgaW5kZXggfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIGNvbHVtbiBoZWFkZXIgY2xpY2sgZm9yIHNvcnRpbmdcclxuICAgKi9cclxuICBvbkhlYWRlckNsaWNrKGNvbHVtbjogUGVjYlRhYmxlQ29sdW1uKTogdm9pZCB7XHJcbiAgICBpZiAoIWNvbHVtbi5zb3J0YWJsZSkgcmV0dXJuO1xyXG5cclxuICAgIGxldCBuZXdEaXJlY3Rpb246ICdhc2MnIHwgJ2Rlc2MnIHwgbnVsbCA9ICdhc2MnO1xyXG5cclxuICAgIGlmICh0aGlzLnNvcnRDb2x1bW4gPT09IGNvbHVtbi5rZXkpIHtcclxuICAgICAgaWYgKHRoaXMuc29ydERpcmVjdGlvbiA9PT0gJ2FzYycpIHtcclxuICAgICAgICBuZXdEaXJlY3Rpb24gPSAnZGVzYyc7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zb3J0RGlyZWN0aW9uID09PSAnZGVzYycpIHtcclxuICAgICAgICBuZXdEaXJlY3Rpb24gPSBudWxsO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zb3J0Q29sdW1uID0gbmV3RGlyZWN0aW9uID8gY29sdW1uLmtleSA6IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuc29ydERpcmVjdGlvbiA9IG5ld0RpcmVjdGlvbjtcclxuXHJcbiAgICB0aGlzLnNvcnRDaGFuZ2UuZW1pdCh7XHJcbiAgICAgIGNvbHVtbjogY29sdW1uLmtleSxcclxuICAgICAgZGlyZWN0aW9uOiBuZXdEaXJlY3Rpb24sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZXMgcm93IHNlbGVjdGlvblxyXG4gICAqL1xyXG4gIHRvZ2dsZVJvd1NlbGVjdGlvbihpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBjb25zdCBuZXdTZWxlY3Rpb24gPSBbLi4udGhpcy5zZWxlY3RlZEluZGljZXNdO1xyXG4gICAgY29uc3QgZXhpc3RpbmdJbmRleCA9IG5ld1NlbGVjdGlvbi5pbmRleE9mKGluZGV4KTtcclxuXHJcbiAgICBpZiAoZXhpc3RpbmdJbmRleCA+IC0xKSB7XHJcbiAgICAgIG5ld1NlbGVjdGlvbi5zcGxpY2UoZXhpc3RpbmdJbmRleCwgMSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBuZXdTZWxlY3Rpb24ucHVzaChpbmRleCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zZWxlY3RlZEluZGljZXMgPSBuZXdTZWxlY3Rpb247XHJcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb25DaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZXMgYWxsIHJvd3Mgc2VsZWN0aW9uXHJcbiAgICovXHJcbiAgdG9nZ2xlQWxsU2VsZWN0aW9uKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaXNBbGxTZWxlY3RlZCgpKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRJbmRpY2VzID0gW107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSW5kaWNlcyA9IHRoaXMuZGF0YS5tYXAoKF8sIGluZGV4KSA9PiBpbmRleCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb25DaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyBpZiBhIHJvdyBpcyBzZWxlY3RlZFxyXG4gICAqL1xyXG4gIGlzUm93U2VsZWN0ZWQoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJbmRpY2VzLmluY2x1ZGVzKGluZGV4KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyBpZiBhbGwgcm93cyBhcmUgc2VsZWN0ZWRcclxuICAgKi9cclxuICBpc0FsbFNlbGVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggPiAwICYmIHRoaXMuc2VsZWN0ZWRJbmRpY2VzLmxlbmd0aCA9PT0gdGhpcy5kYXRhLmxlbmd0aDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyBpZiBzb21lIHJvd3MgYXJlIHNlbGVjdGVkIChmb3IgaW5kZXRlcm1pbmF0ZSBzdGF0ZSlcclxuICAgKi9cclxuICBpc1NvbWVTZWxlY3RlZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkSW5kaWNlcy5sZW5ndGggPiAwICYmIHRoaXMuc2VsZWN0ZWRJbmRpY2VzLmxlbmd0aCA8IHRoaXMuZGF0YS5sZW5ndGg7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIHBhZ2UgY2hhbmdlIGZyb20gcGFnaW5hdGlvbiBjb21wb25lbnRcclxuICAgKi9cclxuICBvblBhZ2VDaGFuZ2UoZXZlbnQ6IFBhZ2VDaGFuZ2VFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IGV2ZW50LnBhZ2U7XHJcbiAgICB0aGlzLnBhZ2VDaGFuZ2UuZW1pdChldmVudCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIHBhZ2Ugc2l6ZSBjaGFuZ2UgZnJvbSBwYWdpbmF0aW9uIGNvbXBvbmVudFxyXG4gICAqL1xyXG4gIG9uUGFnZVNpemVDaGFuZ2UobmV3U2l6ZTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLnBhZ2VTaXplID0gbmV3U2l6ZTtcclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xyXG4gICAgdGhpcy5wYWdlU2l6ZUNoYW5nZS5lbWl0KG5ld1NpemUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyB0aGUgc29ydCBpY29uIHN0YXRlIGZvciBhIGNvbHVtblxyXG4gICAqL1xyXG4gIGdldFNvcnRTdGF0ZShjb2x1bW46IFBlY2JUYWJsZUNvbHVtbik6ICdhc2MnIHwgJ2Rlc2MnIHwgJ25vbmUnIHtcclxuICAgIGlmICghY29sdW1uLnNvcnRhYmxlKSByZXR1cm4gJ25vbmUnO1xyXG4gICAgaWYgKHRoaXMuc29ydENvbHVtbiAhPT0gY29sdW1uLmtleSkgcmV0dXJuICdub25lJztcclxuICAgIHJldHVybiB0aGlzLnNvcnREaXJlY3Rpb24gfHwgJ25vbmUnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHJhY2tzIHJvd3MgYnkgaW5kZXggZm9yIG5nRm9yIHBlcmZvcm1hbmNlXHJcbiAgICovXHJcbiAgdHJhY2tCeUluZGV4KGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIGluZGV4O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHJhY2tzIGNvbHVtbnMgYnkga2V5IGZvciBuZ0ZvciBwZXJmb3JtYW5jZVxyXG4gICAqL1xyXG4gIHRyYWNrQnlLZXkoXzogbnVtYmVyLCBjb2x1bW46IFBlY2JUYWJsZUNvbHVtbik6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gY29sdW1uLmtleTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgdGhlIGVmZmVjdGl2ZSBjb2x1bW4gdHlwZSAoc3VwcG9ydHMgYm90aCAndHlwZScgYW5kICdjb21wb25lbnQnIHByb3BlcnRpZXMpXHJcbiAgICovXHJcbiAgZ2V0Q29sdW1uVHlwZShjb2x1bW46IFBlY2JUYWJsZUNvbHVtbik6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gY29sdW1uLmNvbXBvbmVudCB8fCBjb2x1bW4udHlwZSB8fCAndGV4dCc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIHRoZSBzdGF0dXMgdHlwZSBmb3IgYSB2YWx1ZSBiYXNlZCBvbiBjb2x1bW4gY29uZmlnXHJcbiAgICovXHJcbiAgZ2V0U3RhdHVzVHlwZSh2YWx1ZTogYW55LCBjb2x1bW46IFBlY2JUYWJsZUNvbHVtbik6IGFueSB7XHJcbiAgICBjb25zdCBjb25maWcgPSBjb2x1bW4uc3RhdHVzQ29uZmlnO1xyXG4gICAgaWYgKGNvbmZpZz8udHlwZU1hcCAmJiB2YWx1ZSBpbiBjb25maWcudHlwZU1hcCkge1xyXG4gICAgICByZXR1cm4gY29uZmlnLnR5cGVNYXBbdmFsdWVdO1xyXG4gICAgfVxyXG4gICAgLy8gRGVmYXVsdCBtYXBwaW5nc1xyXG4gICAgY29uc3QgZGVmYXVsdE1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcclxuICAgICAgJ1BlbmRpbmcnOiAnd2FybmluZycsXHJcbiAgICAgICdwZW5kaW5nJzogJ3dhcm5pbmcnLFxyXG4gICAgICAnSW5hY3RpdmUnOiAnZXJyb3InLFxyXG4gICAgICAnaW5hY3RpdmUnOiAnZXJyb3InLFxyXG4gICAgICAnQXBwcm92ZWQnOiAnc3VjY2VzcycsXHJcbiAgICAgICdhcHByb3ZlZCc6ICdzdWNjZXNzJyxcclxuICAgICAgJ0FjdGl2ZSc6ICdzdWNjZXNzJyxcclxuICAgICAgJ2FjdGl2ZSc6ICdzdWNjZXNzJyxcclxuICAgICAgJ0Rpc2FibGVkJzogJ2Rpc2FibGVkJyxcclxuICAgICAgJ2Rpc2FibGVkJzogJ2Rpc2FibGVkJyxcclxuICAgIH07XHJcbiAgICByZXR1cm4gZGVmYXVsdE1hcFt2YWx1ZV0gfHwgJ25ldXRyYWwnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyB0aGUgc3RhdHVzIHZhcmlhbnQgZm9yIGEgY29sdW1uXHJcbiAgICovXHJcbiAgZ2V0U3RhdHVzVmFyaWFudChjb2x1bW46IFBlY2JUYWJsZUNvbHVtbik6IGFueSB7XHJcbiAgICByZXR1cm4gY29sdW1uLnN0YXR1c0NvbmZpZz8udmFyaWFudCB8fCAnZmlsbGVkJztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgdGhlIHN0YXR1cyBzaXplIGZvciBhIGNvbHVtblxyXG4gICAqL1xyXG4gIGdldFN0YXR1c1NpemUoY29sdW1uOiBQZWNiVGFibGVDb2x1bW4pOiBhbnkge1xyXG4gICAgcmV0dXJuIGNvbHVtbi5zdGF0dXNDb25maWc/LnNpemUgfHwgJ3NtJztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgdXNlciBkaXNwbGF5IGRhdGEgZnJvbSByb3dcclxuICAgKi9cclxuICBnZXRVc2VyRGF0YShyb3c6IGFueSwgY29sdW1uOiBQZWNiVGFibGVDb2x1bW4pOiB7IGF2YXRhcjogc3RyaW5nOyBuYW1lOiBzdHJpbmc7IHNlY29uZGFyeTogc3RyaW5nIH0ge1xyXG4gICAgY29uc3QgY29uZmlnID0gY29sdW1uLnVzZXJDb25maWcgfHwge307XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBhdmF0YXI6IHJvd1tjb25maWcuYXZhdGFyS2V5IHx8ICdhdmF0YXInXSB8fCAnJyxcclxuICAgICAgbmFtZTogcm93W2NvbmZpZy5uYW1lS2V5IHx8IGNvbHVtbi5rZXldIHx8ICcnLFxyXG4gICAgICBzZWNvbmRhcnk6IHJvd1tjb25maWcuc2Vjb25kYXJ5S2V5IHx8ICdlbWFpbCddIHx8ICcnLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgZGVmYXVsdCBhY3Rpb25zIGlmIG5vbmUgc3BlY2lmaWVkXHJcbiAgICovXHJcbiAgZ2V0QWN0aW9ucyhjb2x1bW46IFBlY2JUYWJsZUNvbHVtbik6IFRhYmxlQWN0aW9uW10ge1xyXG4gICAgaWYgKGNvbHVtbi5hY3Rpb25zICYmIGNvbHVtbi5hY3Rpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgcmV0dXJuIGNvbHVtbi5hY3Rpb25zO1xyXG4gICAgfVxyXG4gICAgLy8gRGVmYXVsdCBhY3Rpb25zXHJcbiAgICByZXR1cm4gW1xyXG4gICAgICB7IGlkOiAndmlldycsIGljb246ICd2aWV3JywgdG9vbHRpcDogJ1ZpZXcnIH0sXHJcbiAgICAgIHsgaWQ6ICdlZGl0JywgaWNvbjogJ2VkaXQnLCB0b29sdGlwOiAnRWRpdCcgfSxcclxuICAgICAgeyBpZDogJ2RlbGV0ZScsIGljb246ICdkZWxldGUnLCB0b29sdGlwOiAnRGVsZXRlJywgdmFyaWFudDogJ2RhbmdlcicgfSxcclxuICAgIF07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIGFjdGlvbiBidXR0b24gY2xpY2tcclxuICAgKi9cclxuICBvbkFjdGlvbkNsaWNrKGFjdGlvbjogVGFibGVBY3Rpb24sIHJvdzogYW55LCBpbmRleDogbnVtYmVyLCBldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgIC8vIENhbGwgaW5kaXZpZHVhbCBhY3Rpb24gY2FsbGJhY2sgaWYgcHJvdmlkZWRcclxuICAgIGlmIChhY3Rpb24uYWN0aW9uKSB7XHJcbiAgICAgIGFjdGlvbi5hY3Rpb24ocm93LCBpbmRleCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWx3YXlzIGVtaXQgdGhlIHJvd0FjdGlvbiBldmVudFxyXG4gICAgdGhpcy5yb3dBY3Rpb24uZW1pdCh7IGFjdGlvbjogYWN0aW9uLmlkLCByb3csIGluZGV4IH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyB0aGUgaW5wdXRzIGZvciBhIGR5bmFtaWMgY29tcG9uZW50XHJcbiAgICogQ29tYmluZXMgc3RhdGljIGNvbXBvbmVudElucHV0cyB3aXRoIHJvdy1zcGVjaWZpYyBkYXRhIGZyb20gY29tcG9uZW50SW5wdXRzRm5cclxuICAgKi9cclxuICBnZXREeW5hbWljQ29tcG9uZW50SW5wdXRzKHJvdzogYW55LCBjb2x1bW46IFBlY2JUYWJsZUNvbHVtbiwgaW5kZXg6IG51bWJlcik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xyXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENlbGxWYWx1ZShyb3csIGNvbHVtbi5rZXkpO1xyXG4gICAgY29uc3Qgc3RhdGljSW5wdXRzID0gY29sdW1uLmNvbXBvbmVudElucHV0cyB8fCB7fTtcclxuXHJcbiAgICBpZiAoY29sdW1uLmNvbXBvbmVudElucHV0c0ZuKSB7XHJcbiAgICAgIGNvbnN0IGR5bmFtaWNJbnB1dHMgPSBjb2x1bW4uY29tcG9uZW50SW5wdXRzRm4ocm93LCB2YWx1ZSwgaW5kZXgpO1xyXG4gICAgICByZXR1cm4geyAuLi5zdGF0aWNJbnB1dHMsIC4uLmR5bmFtaWNJbnB1dHMgfTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc3RhdGljSW5wdXRzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2tzIGlmIGNvbHVtbiBoYXMgYSBkeW5hbWljIGNvbXBvbmVudFxyXG4gICAqL1xyXG4gIGhhc0R5bmFtaWNDb21wb25lbnQoY29sdW1uOiBQZWNiVGFibGVDb2x1bW4pOiBib29sZWFuIHtcclxuICAgIHJldHVybiAhIWNvbHVtbi5keW5hbWljQ29tcG9uZW50O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2FuaXRpemVzIGN1c3RvbSBpY29uIFNWRyBmb3Igc2FmZSByZW5kZXJpbmdcclxuICAgKi9cclxuICBnZXRTYWZlSWNvbihpY29uU3ZnOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBTYWZlSHRtbCB7XHJcbiAgICBpZiAoIWljb25TdmcpIHJldHVybiAnJztcclxuICAgIHJldHVybiB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChpY29uU3ZnKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZW1pdFNlbGVjdGlvbkNoYW5nZSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHNlbGVjdGVkUm93cyA9IHRoaXMuc2VsZWN0ZWRJbmRpY2VzLm1hcChpbmRleCA9PiB0aGlzLmRhdGFbaW5kZXhdKTtcclxuICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQoe1xyXG4gICAgICBzZWxlY3RlZFJvd3MsXHJcbiAgICAgIHNlbGVjdGVkSW5kaWNlczogdGhpcy5zZWxlY3RlZEluZGljZXMsXHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cInBlY2ItdGFibGUtd3JhcHBlclwiPlxyXG4gIDxkaXYgW2NsYXNzXT1cImNvbnRhaW5lckNsYXNzZXNcIiBbc3R5bGUubWF4SGVpZ2h0XT1cIm1heEhlaWdodFwiPlxyXG4gICAgPCEtLSBMb2FkaW5nIFN0YXRlIC0tPlxyXG4gICAgPGRpdiAqbmdJZj1cImxvYWRpbmdcIiBjbGFzcz1cInBlY2ItdGFibGVfX2xvYWRpbmdcIj5cclxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvYWRpbmdUZW1wbGF0ZTsgZWxzZSBkZWZhdWx0TG9hZGluZ1wiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2FkaW5nVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdExvYWRpbmc+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInBlY2ItdGFibGVfX2xvYWRpbmctc3Bpbm5lclwiPlxyXG4gICAgICAgICAgPHN2ZyBjbGFzcz1cInBlY2ItdGFibGVfX3NwaW5uZXItaWNvblwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICA8Y2lyY2xlIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjEwXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtZGFzaGFycmF5PVwiMzEuNCAzMS40XCIgLz5cclxuICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgPHNwYW4+TG9hZGluZy4uLjwvc3Bhbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDwhLS0gVGFibGUgLS0+XHJcbiAgPHRhYmxlXHJcbiAgICAqbmdJZj1cIiFsb2FkaW5nXCJcclxuICAgIFtjbGFzc109XCJ0YWJsZUNsYXNzZXNcIlxyXG4gICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWxcIlxyXG4gICAgcm9sZT1cInRhYmxlXCI+XHJcblxyXG4gICAgPCEtLSBUYWJsZSBIZWFkZXIgLS0+XHJcbiAgICA8dGhlYWQgKm5nSWY9XCJzaG93SGVhZGVyXCIgY2xhc3M9XCJwZWNiLXRhYmxlX19oZWFkXCIgW2NsYXNzLnBlY2ItdGFibGVfX2hlYWQtLXN0aWNreV09XCJzdGlja3lIZWFkZXJcIj5cclxuICAgICAgPHRyIGNsYXNzPVwicGVjYi10YWJsZV9fcm93IHBlY2ItdGFibGVfX3Jvdy0taGVhZGVyXCIgcm9sZT1cInJvd1wiPlxyXG4gICAgICAgIDwhLS0gU2VsZWN0aW9uIENoZWNrYm94IENvbHVtbiAtLT5cclxuICAgICAgICA8dGhcclxuICAgICAgICAgICpuZ0lmPVwic2VsZWN0YWJsZVwiXHJcbiAgICAgICAgICBjbGFzcz1cInBlY2ItdGFibGVfX2NlbGwgcGVjYi10YWJsZV9fY2VsbC0taGVhZGVyIHBlY2ItdGFibGVfX2NlbGwtLWNoZWNrYm94XCJcclxuICAgICAgICAgIHJvbGU9XCJjb2x1bW5oZWFkZXJcIlxyXG4gICAgICAgICAgc2NvcGU9XCJjb2xcIj5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInBlY2ItdGFibGVfX2NoZWNrYm94LXdyYXBwZXJcIj5cclxuICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcclxuICAgICAgICAgICAgICBjbGFzcz1cInBlY2ItdGFibGVfX2NoZWNrYm94XCJcclxuICAgICAgICAgICAgICBbY2hlY2tlZF09XCJpc0FsbFNlbGVjdGVkKClcIlxyXG4gICAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cImlzU29tZVNlbGVjdGVkKClcIlxyXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwidG9nZ2xlQWxsU2VsZWN0aW9uKClcIlxyXG4gICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJTZWxlY3QgYWxsIHJvd3NcIiAvPlxyXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBlY2ItdGFibGVfX2NoZWNrYm94LWN1c3RvbVwiPjwvc3Bhbj5cclxuICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgPC90aD5cclxuXHJcbiAgICAgICAgPCEtLSBEYXRhIENvbHVtbnMgLS0+XHJcbiAgICAgICAgPHRoXHJcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnM7IHRyYWNrQnk6IHRyYWNrQnlLZXlcIlxyXG4gICAgICAgICAgY2xhc3M9XCJwZWNiLXRhYmxlX19jZWxsIHBlY2ItdGFibGVfX2NlbGwtLWhlYWRlclwiXHJcbiAgICAgICAgICBbY2xhc3MucGVjYi10YWJsZV9fY2VsbC0tc29ydGFibGVdPVwiY29sdW1uLnNvcnRhYmxlXCJcclxuICAgICAgICAgIFtjbGFzc109XCJnZXRBbGlnbm1lbnRDbGFzcyhjb2x1bW4pXCJcclxuICAgICAgICAgIFtuZ0NsYXNzXT1cImNvbHVtbi5jc3NDbGFzc1wiXHJcbiAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sdW1uLndpZHRoXCJcclxuICAgICAgICAgIFthdHRyLmFyaWEtc29ydF09XCJjb2x1bW4uc29ydGFibGUgPyAoc29ydENvbHVtbiA9PT0gY29sdW1uLmtleSA/IChzb3J0RGlyZWN0aW9uID09PSAnYXNjJyA/ICdhc2NlbmRpbmcnIDogJ2Rlc2NlbmRpbmcnKSA6ICdub25lJykgOiBudWxsXCJcclxuICAgICAgICAgIHJvbGU9XCJjb2x1bW5oZWFkZXJcIlxyXG4gICAgICAgICAgc2NvcGU9XCJjb2xcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIm9uSGVhZGVyQ2xpY2soY29sdW1uKVwiXHJcbiAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJvbkhlYWRlckNsaWNrKGNvbHVtbilcIlxyXG4gICAgICAgICAgKGtleWRvd24uc3BhY2UpPVwib25IZWFkZXJDbGljayhjb2x1bW4pOyAkZXZlbnQucHJldmVudERlZmF1bHQoKVwiXHJcbiAgICAgICAgICBbYXR0ci50YWJpbmRleF09XCJjb2x1bW4uc29ydGFibGUgPyAwIDogbnVsbFwiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInBlY2ItdGFibGVfX2hlYWRlci1jb250ZW50XCI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2x1bW4uaGVhZGVyVGVtcGxhdGU7IGVsc2UgZGVmYXVsdEhlYWRlclwiPlxyXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2x1bW4uaGVhZGVyVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjb2x1bW4gfVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0SGVhZGVyPlxyXG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGVjYi10YWJsZV9faGVhZGVyLXRleHRcIj57eyBjb2x1bW4ubGFiZWwgfX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICA8IS0tIFNvcnQgSWNvbiAtLT5cclxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJjb2x1bW4uc29ydGFibGVcIiBjbGFzcz1cInBlY2ItdGFibGVfX3NvcnQtaWNvblwiIFthdHRyLmRhdGEtc29ydF09XCJnZXRTb3J0U3RhdGUoY29sdW1uKVwiPlxyXG4gICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJnZXRTb3J0U3RhdGUoY29sdW1uKSA9PT0gJ25vbmUnXCIgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTggM0wxMiA3SDRMOCAzWlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBvcGFjaXR5PVwiMC40XCIvPlxyXG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk04IDEzTDQgOUgxMkw4IDEzWlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBvcGFjaXR5PVwiMC40XCIvPlxyXG4gICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJnZXRTb3J0U3RhdGUoY29sdW1uKSA9PT0gJ2FzYydcIiB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNOCAzTDEyIDdINEw4IDNaXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz5cclxuICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNOCAxM0w0IDlIMTJMOCAxM1pcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgb3BhY2l0eT1cIjAuNFwiLz5cclxuICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiZ2V0U29ydFN0YXRlKGNvbHVtbikgPT09ICdkZXNjJ1wiIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk04IDNMMTIgN0g0TDggM1pcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgb3BhY2l0eT1cIjAuNFwiLz5cclxuICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNOCAxM0w0IDlIMTJMOCAxM1pcIiBmaWxsPVwiY3VycmVudENvbG9yXCIvPlxyXG4gICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L3RoPlxyXG4gICAgICA8L3RyPlxyXG4gICAgPC90aGVhZD5cclxuXHJcbiAgICA8IS0tIFRhYmxlIEJvZHkgLS0+XHJcbiAgICA8dGJvZHkgY2xhc3M9XCJwZWNiLXRhYmxlX19ib2R5XCI+XHJcbiAgICAgIDwhLS0gRW1wdHkgU3RhdGUgLS0+XHJcbiAgICAgIDx0ciAqbmdJZj1cImRhdGEubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJwZWNiLXRhYmxlX19yb3cgcGVjYi10YWJsZV9fcm93LS1lbXB0eVwiPlxyXG4gICAgICAgIDx0ZFxyXG4gICAgICAgICAgW2F0dHIuY29sc3Bhbl09XCJzZWxlY3RhYmxlID8gY29sdW1ucy5sZW5ndGggKyAxIDogY29sdW1ucy5sZW5ndGhcIlxyXG4gICAgICAgICAgY2xhc3M9XCJwZWNiLXRhYmxlX19jZWxsIHBlY2ItdGFibGVfX2NlbGwtLWVtcHR5XCI+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZW1wdHlUZW1wbGF0ZTsgZWxzZSBkZWZhdWx0RW1wdHlcIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImVtcHR5VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RW1wdHk+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwZWNiLXRhYmxlX19lbXB0eS1jb250ZW50XCI+XHJcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwZWNiLXRhYmxlX19lbXB0eS1tZXNzYWdlXCI+e3sgZW1wdHlNZXNzYWdlIH19PC9zcGFuPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPC90ZD5cclxuICAgICAgPC90cj5cclxuXHJcbiAgICAgIDwhLS0gRGF0YSBSb3dzIC0tPlxyXG4gICAgICA8dHJcclxuICAgICAgICAqbmdGb3I9XCJsZXQgcm93IG9mIGRhdGE7IGxldCBpID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiXHJcbiAgICAgICAgY2xhc3M9XCJwZWNiLXRhYmxlX19yb3cgcGVjYi10YWJsZV9fcm93LS1kYXRhXCJcclxuICAgICAgICBbY2xhc3MucGVjYi10YWJsZV9fcm93LS1zZWxlY3RlZF09XCJpc1Jvd1NlbGVjdGVkKGkpXCJcclxuICAgICAgICByb2xlPVwicm93XCJcclxuICAgICAgICAoY2xpY2spPVwib25Sb3dDbGljayhyb3csIGkpXCJcclxuICAgICAgICBbYXR0ci50YWJpbmRleF09XCIwXCJcclxuICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJvblJvd0NsaWNrKHJvdywgaSlcIj5cclxuXHJcbiAgICAgICAgPCEtLSBTZWxlY3Rpb24gQ2hlY2tib3ggLS0+XHJcbiAgICAgICAgPHRkXHJcbiAgICAgICAgICAqbmdJZj1cInNlbGVjdGFibGVcIlxyXG4gICAgICAgICAgY2xhc3M9XCJwZWNiLXRhYmxlX19jZWxsIHBlY2ItdGFibGVfX2NlbGwtLWNoZWNrYm94XCJcclxuICAgICAgICAgIHJvbGU9XCJjZWxsXCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInBlY2ItdGFibGVfX2NoZWNrYm94LXdyYXBwZXJcIj5cclxuICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcclxuICAgICAgICAgICAgICBjbGFzcz1cInBlY2ItdGFibGVfX2NoZWNrYm94XCJcclxuICAgICAgICAgICAgICBbY2hlY2tlZF09XCJpc1Jvd1NlbGVjdGVkKGkpXCJcclxuICAgICAgICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZVJvd1NlbGVjdGlvbihpKVwiXHJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInU2VsZWN0IHJvdyAnICsgKGkgKyAxKVwiIC8+XHJcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGVjYi10YWJsZV9fY2hlY2tib3gtY3VzdG9tXCI+PC9zcGFuPlxyXG4gICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICA8L3RkPlxyXG5cclxuICAgICAgICA8IS0tIERhdGEgQ2VsbHMgLS0+XHJcbiAgICAgICAgPHRkXHJcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnM7IHRyYWNrQnk6IHRyYWNrQnlLZXlcIlxyXG4gICAgICAgICAgY2xhc3M9XCJwZWNiLXRhYmxlX19jZWxsXCJcclxuICAgICAgICAgIFtjbGFzc109XCJnZXRBbGlnbm1lbnRDbGFzcyhjb2x1bW4pXCJcclxuICAgICAgICAgIFtuZ0NsYXNzXT1cImNvbHVtbi5jc3NDbGFzc1wiXHJcbiAgICAgICAgICByb2xlPVwiY2VsbFwiPlxyXG5cclxuICAgICAgICAgIDwhLS0gQ3VzdG9tIFRlbXBsYXRlIC0tPlxyXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbHVtbi5jZWxsVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbHVtbi5jZWxsVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBnZXRDZWxsVmFsdWUocm93LCBjb2x1bW4ua2V5KSwgcm93OiByb3csIGNvbHVtbjogY29sdW1uLCBpbmRleDogaSB9XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICA8IS0tIER5bmFtaWMgQ29tcG9uZW50IC0gcmVuZGVycyBhbnkgY29tcG9uZW50IHBhc3NlZCB2aWEgZHluYW1pY0NvbXBvbmVudCAtLT5cclxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29sdW1uLmNlbGxUZW1wbGF0ZSAmJiBoYXNEeW5hbWljQ29tcG9uZW50KGNvbHVtbilcIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICpuZ0NvbXBvbmVudE91dGxldD1cImNvbHVtbi5keW5hbWljQ29tcG9uZW50ITsgaW5wdXRzOiBnZXREeW5hbWljQ29tcG9uZW50SW5wdXRzKHJvdywgY29sdW1uLCBpKVwiPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgIDwhLS0gU3RhdHVzIENvbXBvbmVudCAtIHJlbmRlcnMgcGVjYi1zdGF0dXMgLS0+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNvbHVtbi5jZWxsVGVtcGxhdGUgJiYgIWhhc0R5bmFtaWNDb21wb25lbnQoY29sdW1uKSAmJiBnZXRDb2x1bW5UeXBlKGNvbHVtbikgPT09ICdzdGF0dXMnXCI+XHJcbiAgICAgICAgICAgIDxwZWNiLXN0YXR1c1xyXG4gICAgICAgICAgICAgIFt0eXBlXT1cImdldFN0YXR1c1R5cGUoZ2V0Q2VsbFZhbHVlKHJvdywgY29sdW1uLmtleSksIGNvbHVtbilcIlxyXG4gICAgICAgICAgICAgIFt2YXJpYW50XT1cImdldFN0YXR1c1ZhcmlhbnQoY29sdW1uKVwiXHJcbiAgICAgICAgICAgICAgW3NpemVdPVwiZ2V0U3RhdHVzU2l6ZShjb2x1bW4pXCI+XHJcbiAgICAgICAgICAgICAge3sgZ2V0Q2VsbFZhbHVlKHJvdywgY29sdW1uLmtleSkgfX1cclxuICAgICAgICAgICAgPC9wZWNiLXN0YXR1cz5cclxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgIDwhLS0gVXNlciBDb21wb25lbnQgLSByZW5kZXJzIGF2YXRhciArIG5hbWUgKyBlbWFpbCAtLT5cclxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29sdW1uLmNlbGxUZW1wbGF0ZSAmJiAhaGFzRHluYW1pY0NvbXBvbmVudChjb2x1bW4pICYmIGdldENvbHVtblR5cGUoY29sdW1uKSA9PT0gJ3VzZXInXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwZWNiLXRhYmxlX191c2VyLWNlbGxcIj5cclxuICAgICAgICAgICAgICA8aW1nXHJcbiAgICAgICAgICAgICAgICAqbmdJZj1cImdldFVzZXJEYXRhKHJvdywgY29sdW1uKS5hdmF0YXJcIlxyXG4gICAgICAgICAgICAgICAgW3NyY109XCJnZXRVc2VyRGF0YShyb3csIGNvbHVtbikuYXZhdGFyXCJcclxuICAgICAgICAgICAgICAgIGFsdD1cIlwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInBlY2ItdGFibGVfX3VzZXItYXZhdGFyXCI+XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBlY2ItdGFibGVfX3VzZXItaW5mb1wiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBlY2ItdGFibGVfX3VzZXItbmFtZVwiPnt7IGdldFVzZXJEYXRhKHJvdywgY29sdW1uKS5uYW1lIH19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZ2V0VXNlckRhdGEocm93LCBjb2x1bW4pLnNlY29uZGFyeVwiIGNsYXNzPVwicGVjYi10YWJsZV9fdXNlci1zZWNvbmRhcnlcIj5cclxuICAgICAgICAgICAgICAgICAge3sgZ2V0VXNlckRhdGEocm93LCBjb2x1bW4pLnNlY29uZGFyeSB9fVxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgPCEtLSBBY3Rpb24gQ29tcG9uZW50IC0gcmVuZGVycyBhY3Rpb24gYnV0dG9ucyB3aXRoIGljb25zIC0tPlxyXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFjb2x1bW4uY2VsbFRlbXBsYXRlICYmICFoYXNEeW5hbWljQ29tcG9uZW50KGNvbHVtbikgJiYgZ2V0Q29sdW1uVHlwZShjb2x1bW4pID09PSAnYWN0aW9uJ1wiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGVjYi10YWJsZV9fYWN0aW9uLWJ1dHRvbnNcIj5cclxuICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgYWN0aW9uIG9mIGdldEFjdGlvbnMoY29sdW1uKVwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInBlY2ItdGFibGVfX2FjdGlvbi1idG5cIlxyXG4gICAgICAgICAgICAgICAgW2NsYXNzLnBlY2ItdGFibGVfX2FjdGlvbi1idG4tLWRhbmdlcl09XCJhY3Rpb24udmFyaWFudCA9PT0gJ2RhbmdlcidcIlxyXG4gICAgICAgICAgICAgICAgW3RpdGxlXT1cImFjdGlvbi50b29sdGlwIHx8IGFjdGlvbi5pZFwiXHJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiYWN0aW9uLmRpc2FibGVkXCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkFjdGlvbkNsaWNrKGFjdGlvbiwgcm93LCBpLCAkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgICAgICA8IS0tIFZpZXcgSWNvbiAtLT5cclxuICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJhY3Rpb24uaWNvbiA9PT0gJ3ZpZXcnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPlxyXG4gICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTEgMTJzNC04IDExLTggMTEgOCAxMSA4LTQgOC0xMSA4LTExLTgtMTEtOHpcIj48L3BhdGg+XHJcbiAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9XCIxMlwiIGN5PVwiMTJcIiByPVwiM1wiPjwvY2lyY2xlPlxyXG4gICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICA8IS0tIEVkaXQgSWNvbiAtLT5cclxuICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJhY3Rpb24uaWNvbiA9PT0gJ2VkaXQnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPlxyXG4gICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTExIDRINGEyIDIgMCAwIDAtMiAydjE0YTIgMiAwIDAgMCAyIDJoMTRhMiAyIDAgMCAwIDItMnYtN1wiPjwvcGF0aD5cclxuICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xOC41IDIuNWEyLjEyMSAyLjEyMSAwIDAgMSAzIDNMMTIgMTVsLTQgMSAxLTQgOS41LTkuNXpcIj48L3BhdGg+XHJcbiAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgIDwhLS0gRGVsZXRlIEljb24gLS0+XHJcbiAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiYWN0aW9uLmljb24gPT09ICdkZWxldGUnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPlxyXG4gICAgICAgICAgICAgICAgICA8cG9seWxpbmUgcG9pbnRzPVwiMyA2IDUgNiAyMSA2XCI+PC9wb2x5bGluZT5cclxuICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xOSA2djE0YTIgMiAwIDAgMS0yIDJIN2EyIDIgMCAwIDEtMi0yVjZtMyAwVjRhMiAyIDAgMCAxIDItMmg0YTIgMiAwIDAgMSAyIDJ2MlwiPjwvcGF0aD5cclxuICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgPCEtLSBEb3dubG9hZCBJY29uIC0tPlxyXG4gICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cImFjdGlvbi5pY29uID09PSAnZG93bmxvYWQnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPlxyXG4gICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIxIDE1djRhMiAyIDAgMCAxLTIgMkg1YTIgMiAwIDAgMS0yLTJ2LTRcIj48L3BhdGg+XHJcbiAgICAgICAgICAgICAgICAgIDxwb2x5bGluZSBwb2ludHM9XCI3IDEwIDEyIDE1IDE3IDEwXCI+PC9wb2x5bGluZT5cclxuICAgICAgICAgICAgICAgICAgPGxpbmUgeDE9XCIxMlwiIHkxPVwiMTVcIiB4Mj1cIjEyXCIgeTI9XCIzXCI+PC9saW5lPlxyXG4gICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICA8IS0tIENvcHkgSWNvbiAtLT5cclxuICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJhY3Rpb24uaWNvbiA9PT0gJ2NvcHknXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPlxyXG4gICAgICAgICAgICAgICAgICA8cmVjdCB4PVwiOVwiIHk9XCI5XCIgd2lkdGg9XCIxM1wiIGhlaWdodD1cIjEzXCIgcng9XCIyXCIgcnk9XCIyXCI+PC9yZWN0PlxyXG4gICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTUgMTVINGEyIDIgMCAwIDEtMi0yVjRhMiAyIDAgMCAxIDItMmg5YTIgMiAwIDAgMSAyIDJ2MVwiPjwvcGF0aD5cclxuICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgPCEtLSBDdXN0b20gSWNvbiAoU1ZHIHN0cmluZykgLS0+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjdGlvbi5pY29uID09PSAnY3VzdG9tJyAmJiBhY3Rpb24uY3VzdG9tSWNvblwiIGNsYXNzPVwicGVjYi10YWJsZV9fY3VzdG9tLWljb25cIiBbaW5uZXJIVE1MXT1cImdldFNhZmVJY29uKGFjdGlvbi5jdXN0b21JY29uKVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICA8IS0tIERlZmF1bHQgVGV4dCAtLT5cclxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29sdW1uLmNlbGxUZW1wbGF0ZSAmJiAhaGFzRHluYW1pY0NvbXBvbmVudChjb2x1bW4pICYmIGdldENvbHVtblR5cGUoY29sdW1uKSA9PT0gJ3RleHQnXCI+XHJcbiAgICAgICAgICAgIHt7IGdldENlbGxWYWx1ZShyb3csIGNvbHVtbi5rZXkpIH19XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L3RkPlxyXG4gICAgICA8L3RyPlxyXG4gICAgPC90Ym9keT5cclxuICA8L3RhYmxlPlxyXG4gIDwvZGl2PlxyXG5cclxuICA8IS0tIFBhZ2luYXRpb24gKG91dHNpZGUgdGFibGUgY29udGFpbmVyKSAtLT5cclxuICA8ZGl2ICpuZ0lmPVwic2hvd1BhZ2luYXRpb24gJiYgIWxvYWRpbmcgJiYgZGF0YS5sZW5ndGggPiAwXCIgW2NsYXNzXT1cInBhZ2luYXRpb25DbGFzc2VzXCI+XHJcbiAgICA8cGVjYi1wYWdpbmF0aW9uXHJcbiAgICAgIFt0b3RhbEl0ZW1zXT1cInRvdGFsSXRlbXNcIlxyXG4gICAgICBbcGFnZVNpemVdPVwicGFnZVNpemVcIlxyXG4gICAgICBbY3VycmVudFBhZ2VdPVwiY3VycmVudFBhZ2VcIlxyXG4gICAgICBbcGFnZVNpemVPcHRpb25zXT1cInBhZ2VTaXplT3B0aW9uc1wiXHJcbiAgICAgIFtzaG93UGFnZVNpemVTZWxlY3Rvcl09XCJzaG93UGFnZVNpemVTZWxlY3RvclwiXHJcbiAgICAgIFt2YXJpYW50XT1cInBhZ2luYXRpb25WYXJpYW50XCJcclxuICAgICAgc2l6ZT1cIm1kXCJcclxuICAgICAgKHBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIlxyXG4gICAgICAocGFnZVNpemVDaGFuZ2UpPVwib25QYWdlU2l6ZUNoYW5nZSgkZXZlbnQpXCI+XHJcbiAgICA8L3BlY2ItcGFnaW5hdGlvbj5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcbiJdfQ==