@aquera/ngx-smart-table 0.0.2-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +152 -0
  2. package/aquera-ngx-smart-table.d.ts +5 -0
  3. package/esm2020/aquera-ngx-smart-table.mjs +5 -0
  4. package/esm2020/lib/builder/components/builder-preview/builder-preview.component.mjs +63 -0
  5. package/esm2020/lib/builder/components/builder-toolbar/builder-toolbar.component.mjs +115 -0
  6. package/esm2020/lib/builder/components/column-editor/column-editor.component.mjs +206 -0
  7. package/esm2020/lib/builder/components/column-list/column-list.component.mjs +125 -0
  8. package/esm2020/lib/builder/components/definition-builder/definition-builder.component.mjs +105 -0
  9. package/esm2020/lib/builder/components/table-config-editor/table-config-editor.component.mjs +132 -0
  10. package/esm2020/lib/builder/definition-builder.module.mjs +70 -0
  11. package/esm2020/lib/builder/models/builder-state.interface.mjs +5 -0
  12. package/esm2020/lib/builder/services/definition-builder.service.mjs +251 -0
  13. package/esm2020/lib/builder/services/definition-export.service.mjs +167 -0
  14. package/esm2020/lib/builder/services/definition-import.service.mjs +193 -0
  15. package/esm2020/lib/builder/services/sample-data-generator.service.mjs +126 -0
  16. package/esm2020/lib/builder/utils/config-validator.util.mjs +165 -0
  17. package/esm2020/lib/builder/utils/typescript-generator.util.mjs +206 -0
  18. package/esm2020/lib/editors/index.mjs +9 -0
  19. package/esm2020/lib/editors/nile-autocomplete-editor.mjs +228 -0
  20. package/esm2020/lib/editors/nile-calendar-editor.mjs +214 -0
  21. package/esm2020/lib/editors/nile-date-picker-editor.mjs +227 -0
  22. package/esm2020/lib/editors/nile-input-editor.mjs +235 -0
  23. package/esm2020/lib/editors/nile-select-editor.mjs +317 -0
  24. package/esm2020/lib/factories/column-config.factory.mjs +231 -0
  25. package/esm2020/lib/models/autosave-config.interface.mjs +8 -0
  26. package/esm2020/lib/models/base-column-config.class.mjs +253 -0
  27. package/esm2020/lib/models/cell-strategies.interface.mjs +6 -0
  28. package/esm2020/lib/models/cell-types.mjs +147 -0
  29. package/esm2020/lib/models/column-action.interface.mjs +6 -0
  30. package/esm2020/lib/models/column-config.interface.mjs +43 -0
  31. package/esm2020/lib/models/column-config.utils.mjs +101 -0
  32. package/esm2020/lib/models/row-action.interface.mjs +5 -0
  33. package/esm2020/lib/models/row-validator.interface.mjs +2 -0
  34. package/esm2020/lib/models/schema-validation.interface.mjs +2 -0
  35. package/esm2020/lib/models/sheet-action.interface.mjs +5 -0
  36. package/esm2020/lib/models/sheet-config.interface.mjs +5 -0
  37. package/esm2020/lib/models/table-config.interface.mjs +106 -0
  38. package/esm2020/lib/models/table-validator.interface.mjs +2 -0
  39. package/esm2020/lib/models/workbook-action.interface.mjs +5 -0
  40. package/esm2020/lib/models/workbook-config.interface.mjs +5 -0
  41. package/esm2020/lib/renderer/components/st-add-column-button/st-add-column-button.component.mjs +24 -0
  42. package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +391 -0
  43. package/esm2020/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.mjs +103 -0
  44. package/esm2020/lib/renderer/components/st-column-filter/st-column-filter.component.mjs +383 -0
  45. package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +232 -0
  46. package/esm2020/lib/renderer/components/st-column-visibility/st-column-visibility.component.mjs +97 -0
  47. package/esm2020/lib/renderer/components/st-header/st-header.component.mjs +157 -0
  48. package/esm2020/lib/renderer/components/st-pagination/st-pagination.component.mjs +87 -0
  49. package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +167 -0
  50. package/esm2020/lib/renderer/components/st-sheet/st-sheet.component.mjs +165 -0
  51. package/esm2020/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.mjs +112 -0
  52. package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +1246 -0
  53. package/esm2020/lib/renderer/components/st-table-actions/st-table-actions.component.mjs +171 -0
  54. package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +489 -0
  55. package/esm2020/lib/renderer/directives/click-outside.directive.mjs +28 -0
  56. package/esm2020/lib/renderer/directives/st-column-resize.directive.mjs +108 -0
  57. package/esm2020/lib/renderer/directives/st-keyboard-navigation.directive.mjs +73 -0
  58. package/esm2020/lib/renderer/models/cell-state.interface.mjs +66 -0
  59. package/esm2020/lib/renderer/models/cell.class.mjs +389 -0
  60. package/esm2020/lib/renderer/models/row-validation-state.interface.mjs +7 -0
  61. package/esm2020/lib/renderer/models/sheet-state.class.mjs +90 -0
  62. package/esm2020/lib/renderer/models/sheet-state.interface.mjs +5 -0
  63. package/esm2020/lib/renderer/models/table-state.class.mjs +841 -0
  64. package/esm2020/lib/renderer/models/table-state.interface.mjs +5 -0
  65. package/esm2020/lib/renderer/models/table-types.mjs +29 -0
  66. package/esm2020/lib/renderer/models/table-validation-state.interface.mjs +7 -0
  67. package/esm2020/lib/renderer/models/workbook-state.class.mjs +174 -0
  68. package/esm2020/lib/renderer/models/workbook-state.interface.mjs +5 -0
  69. package/esm2020/lib/renderer/models/z-index.enum.mjs +55 -0
  70. package/esm2020/lib/schemas/table-config.schema.mjs +472 -0
  71. package/esm2020/lib/services/autosave.service.mjs +92 -0
  72. package/esm2020/lib/services/custom-validation-rules.util.mjs +124 -0
  73. package/esm2020/lib/services/json-schema-validator.service.mjs +216 -0
  74. package/esm2020/lib/services/row-validation.service.mjs +42 -0
  75. package/esm2020/lib/services/validation-logger.service.mjs +177 -0
  76. package/esm2020/lib/services/virtual-scroll.service.mjs +52 -0
  77. package/esm2020/lib/shared/shared-table-components.module.mjs +35 -0
  78. package/esm2020/lib/smart-table.module.mjs +124 -0
  79. package/esm2020/lib/strategies/default-editors.mjs +433 -0
  80. package/esm2020/lib/strategies/default-formatters.mjs +238 -0
  81. package/esm2020/lib/strategies/default-validators.mjs +327 -0
  82. package/esm2020/public-api.mjs +146 -0
  83. package/fesm2015/aquera-ngx-smart-table.mjs +11860 -0
  84. package/fesm2015/aquera-ngx-smart-table.mjs.map +1 -0
  85. package/fesm2020/aquera-ngx-smart-table.mjs +11897 -0
  86. package/fesm2020/aquera-ngx-smart-table.mjs.map +1 -0
  87. package/lib/builder/components/builder-preview/builder-preview.component.d.ts +31 -0
  88. package/lib/builder/components/builder-toolbar/builder-toolbar.component.d.ts +53 -0
  89. package/lib/builder/components/column-editor/column-editor.component.d.ts +69 -0
  90. package/lib/builder/components/column-list/column-list.component.d.ts +65 -0
  91. package/lib/builder/components/definition-builder/definition-builder.component.d.ts +58 -0
  92. package/lib/builder/components/table-config-editor/table-config-editor.component.d.ts +32 -0
  93. package/lib/builder/definition-builder.module.d.ts +15 -0
  94. package/lib/builder/models/builder-state.interface.d.ts +93 -0
  95. package/lib/builder/services/definition-builder.service.d.ts +80 -0
  96. package/lib/builder/services/definition-export.service.d.ts +59 -0
  97. package/lib/builder/services/definition-import.service.d.ts +31 -0
  98. package/lib/builder/services/sample-data-generator.service.d.ts +41 -0
  99. package/lib/builder/utils/config-validator.util.d.ts +32 -0
  100. package/lib/builder/utils/typescript-generator.util.d.ts +29 -0
  101. package/lib/editors/index.d.ts +8 -0
  102. package/lib/editors/nile-autocomplete-editor.d.ts +102 -0
  103. package/lib/editors/nile-calendar-editor.d.ts +89 -0
  104. package/lib/editors/nile-date-picker-editor.d.ts +95 -0
  105. package/lib/editors/nile-input-editor.d.ts +67 -0
  106. package/lib/editors/nile-select-editor.d.ts +109 -0
  107. package/lib/factories/column-config.factory.d.ts +73 -0
  108. package/lib/models/autosave-config.interface.d.ts +23 -0
  109. package/lib/models/base-column-config.class.d.ts +115 -0
  110. package/lib/models/cell-strategies.interface.d.ts +181 -0
  111. package/lib/models/cell-types.d.ts +337 -0
  112. package/lib/models/column-action.interface.d.ts +86 -0
  113. package/lib/models/column-config.interface.d.ts +272 -0
  114. package/lib/models/column-config.utils.d.ts +37 -0
  115. package/lib/models/row-action.interface.d.ts +86 -0
  116. package/lib/models/row-validator.interface.d.ts +37 -0
  117. package/lib/models/schema-validation.interface.d.ts +42 -0
  118. package/lib/models/sheet-action.interface.d.ts +59 -0
  119. package/lib/models/sheet-config.interface.d.ts +41 -0
  120. package/lib/models/table-config.interface.d.ts +245 -0
  121. package/lib/models/table-validator.interface.d.ts +40 -0
  122. package/lib/models/workbook-action.interface.d.ts +90 -0
  123. package/lib/models/workbook-config.interface.d.ts +107 -0
  124. package/lib/renderer/components/st-add-column-button/st-add-column-button.component.d.ts +9 -0
  125. package/lib/renderer/components/st-cell/st-cell.component.d.ts +69 -0
  126. package/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.d.ts +39 -0
  127. package/lib/renderer/components/st-column-filter/st-column-filter.component.d.ts +139 -0
  128. package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +81 -0
  129. package/lib/renderer/components/st-column-visibility/st-column-visibility.component.d.ts +44 -0
  130. package/lib/renderer/components/st-header/st-header.component.d.ts +93 -0
  131. package/lib/renderer/components/st-pagination/st-pagination.component.d.ts +42 -0
  132. package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +67 -0
  133. package/lib/renderer/components/st-sheet/st-sheet.component.d.ts +98 -0
  134. package/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.d.ts +58 -0
  135. package/lib/renderer/components/st-table/st-table.component.d.ts +349 -0
  136. package/lib/renderer/components/st-table-actions/st-table-actions.component.d.ts +77 -0
  137. package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +235 -0
  138. package/lib/renderer/directives/click-outside.directive.d.ts +10 -0
  139. package/lib/renderer/directives/st-column-resize.directive.d.ts +44 -0
  140. package/lib/renderer/directives/st-keyboard-navigation.directive.d.ts +15 -0
  141. package/lib/renderer/models/cell-state.interface.d.ts +118 -0
  142. package/lib/renderer/models/cell.class.d.ts +174 -0
  143. package/lib/renderer/models/row-validation-state.interface.d.ts +27 -0
  144. package/lib/renderer/models/sheet-state.class.d.ts +67 -0
  145. package/lib/renderer/models/sheet-state.interface.d.ts +55 -0
  146. package/lib/renderer/models/table-state.class.d.ts +313 -0
  147. package/lib/renderer/models/table-state.interface.d.ts +18 -0
  148. package/lib/renderer/models/table-types.d.ts +228 -0
  149. package/lib/renderer/models/table-validation-state.interface.d.ts +34 -0
  150. package/lib/renderer/models/workbook-state.class.d.ts +117 -0
  151. package/lib/renderer/models/workbook-state.interface.d.ts +71 -0
  152. package/lib/renderer/models/z-index.enum.d.ts +44 -0
  153. package/lib/schemas/table-config.schema.d.ts +455 -0
  154. package/lib/services/autosave.service.d.ts +73 -0
  155. package/lib/services/custom-validation-rules.util.d.ts +12 -0
  156. package/lib/services/json-schema-validator.service.d.ts +49 -0
  157. package/lib/services/row-validation.service.d.ts +17 -0
  158. package/lib/services/validation-logger.service.d.ts +87 -0
  159. package/lib/services/virtual-scroll.service.d.ts +44 -0
  160. package/lib/shared/shared-table-components.module.d.ts +9 -0
  161. package/lib/smart-table.module.d.ts +26 -0
  162. package/lib/strategies/default-editors.d.ts +109 -0
  163. package/lib/strategies/default-formatters.d.ts +116 -0
  164. package/lib/strategies/default-validators.d.ts +113 -0
  165. package/package.json +42 -0
  166. package/public-api.d.ts +70 -0
  167. package/src/lib/builder/README.md +30 -0
  168. package/src/lib/editors/README.md +303 -0
  169. package/src/lib/renderer/components/st-column-filter/README.md +286 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Custom validation rules utility
3
+ * Implements business logic validations that can't be expressed in JSON Schema
4
+ */
5
+ /**
6
+ * Validate custom business rules
7
+ * @param config Table configuration
8
+ * @returns Array of validation errors
9
+ */
10
+ export function validateCustomRules(config) {
11
+ const errors = [];
12
+ if (!config.columns || !Array.isArray(config.columns)) {
13
+ return errors; // Let schema validation handle this
14
+ }
15
+ // 1. Check for duplicate column keys
16
+ const keys = config.columns.map(col => col.key);
17
+ const keyCounts = new Map();
18
+ keys.forEach((key, index) => {
19
+ const count = keyCounts.get(key) || 0;
20
+ keyCounts.set(key, count + 1);
21
+ if (count > 0) {
22
+ errors.push({
23
+ path: `/columns/${index}/key`,
24
+ message: `Duplicate column key: "${key}". Column keys must be unique.`,
25
+ code: 'DUPLICATE_KEY',
26
+ value: key,
27
+ field: `columns[${index}].key`
28
+ });
29
+ }
30
+ });
31
+ // 2. Validate width constraints for each column
32
+ config.columns.forEach((column, index) => {
33
+ const prefix = `/columns/${index}`;
34
+ // Width constraint: minWidth <= width <= maxWidth
35
+ if (typeof column.width === 'number' &&
36
+ column.minWidth !== undefined &&
37
+ column.width < column.minWidth) {
38
+ errors.push({
39
+ path: `${prefix}/width`,
40
+ message: `Width (${column.width}) must be greater than or equal to minWidth (${column.minWidth})`,
41
+ code: 'WIDTH_CONSTRAINT_VIOLATION',
42
+ value: column.width,
43
+ field: `columns[${index}].width`
44
+ });
45
+ }
46
+ if (typeof column.width === 'number' &&
47
+ column.maxWidth !== undefined &&
48
+ column.width > column.maxWidth) {
49
+ errors.push({
50
+ path: `${prefix}/width`,
51
+ message: `Width (${column.width}) must be less than or equal to maxWidth (${column.maxWidth})`,
52
+ code: 'WIDTH_CONSTRAINT_VIOLATION',
53
+ value: column.width,
54
+ field: `columns[${index}].width`
55
+ });
56
+ }
57
+ // 3. Sticky columns must have defined width (not 'auto')
58
+ if (column.sticky && (column.sticky === 'left' || column.sticky === 'right')) {
59
+ if (column.width === undefined || column.width === 'auto') {
60
+ errors.push({
61
+ path: `${prefix}/width`,
62
+ message: `Sticky columns must have a defined width (not 'auto'). Column "${column.key}" is sticky but has no width.`,
63
+ code: 'STICKY_WIDTH_REQUIRED',
64
+ value: column.width,
65
+ field: `columns[${index}].width`
66
+ });
67
+ }
68
+ }
69
+ // 4. Column key format validation (should be valid identifier)
70
+ if (column.key && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(column.key)) {
71
+ errors.push({
72
+ path: `${prefix}/key`,
73
+ message: `Column key "${column.key}" must be a valid identifier (letters, numbers, underscore, dollar sign, starting with letter/underscore/dollar)`,
74
+ code: 'INVALID_KEY_FORMAT',
75
+ value: column.key,
76
+ field: `columns[${index}].key`
77
+ });
78
+ }
79
+ });
80
+ // 5. Validate pagination pageSize is in pageSizeOptions (if both provided)
81
+ if (config.pagination?.pageSize && config.pagination?.pageSizeOptions) {
82
+ if (!config.pagination.pageSizeOptions.includes(config.pagination.pageSize)) {
83
+ errors.push({
84
+ path: '/pagination/pageSize',
85
+ message: `pageSize (${config.pagination.pageSize}) must be one of the pageSizeOptions: [${config.pagination.pageSizeOptions.join(', ')}]`,
86
+ code: 'PAGE_SIZE_NOT_IN_OPTIONS',
87
+ value: config.pagination.pageSize,
88
+ field: 'pagination.pageSize'
89
+ });
90
+ }
91
+ }
92
+ // 6. Validate initial state sortBy keys exist in columns
93
+ if (config.initialState?.sortBy) {
94
+ const columnKeys = new Set(config.columns.map(col => col.key));
95
+ config.initialState.sortBy.forEach((sort, index) => {
96
+ if (!columnKeys.has(sort.key)) {
97
+ errors.push({
98
+ path: `/initialState/sortBy/${index}/key`,
99
+ message: `Sort key "${sort.key}" does not exist in columns`,
100
+ code: 'INVALID_SORT_KEY',
101
+ value: sort.key,
102
+ field: `initialState.sortBy[${index}].key`
103
+ });
104
+ }
105
+ });
106
+ }
107
+ // 7. Validate initial state filter keys exist in columns
108
+ if (config.initialState?.filters) {
109
+ const columnKeys = new Set(config.columns.map(col => col.key));
110
+ config.initialState.filters.forEach((filter, index) => {
111
+ if (!columnKeys.has(filter.key)) {
112
+ errors.push({
113
+ path: `/initialState/filters/${index}/key`,
114
+ message: `Filter key "${filter.key}" does not exist in columns`,
115
+ code: 'INVALID_FILTER_KEY',
116
+ value: filter.key,
117
+ field: `initialState.filters[${index}].key`
118
+ });
119
+ }
120
+ });
121
+ }
122
+ return errors;
123
+ }
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLXZhbGlkYXRpb24tcnVsZXMudXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvc2VydmljZXMvY3VzdG9tLXZhbGlkYXRpb24tcnVsZXMudXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFLSDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLE1BQW1CO0lBQ3JELE1BQU0sTUFBTSxHQUE0QixFQUFFLENBQUM7SUFFM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUNyRCxPQUFPLE1BQU0sQ0FBQyxDQUFDLG9DQUFvQztLQUNwRDtJQUVELHFDQUFxQztJQUNyQyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFO1FBQzFCLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM5QixJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUU7WUFDYixNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUNWLElBQUksRUFBRSxZQUFZLEtBQUssTUFBTTtnQkFDN0IsT0FBTyxFQUFFLDBCQUEwQixHQUFHLGdDQUFnQztnQkFDdEUsSUFBSSxFQUFFLGVBQWU7Z0JBQ3JCLEtBQUssRUFB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RyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQy9CLE1BQU0sQ0FBQyxJQUFJLENBQUM7b0JBQ1YsSUFBSSxFQUFFLHlCQUF5QixLQUFLLE1BQU07b0JBQzFDLE9BQU8sRUFBRSxlQUFlLE1BQU0sQ0FBQyxHQUFHLDZCQUE2QjtvQkFDL0QsSUFBSSxFQUFFLG9CQUFvQjtvQkFDMUIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHO29CQUNqQixLQUFLLEVBQUUsd0JBQXdCLEtBQUssT0FBTztpQkFDNUMsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLENBQUMsQ0FBQztLQUNKO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ3VzdG9tIHZhbGlkYXRpb24gcnVsZXMgdXRpbGl0eVxuICogSW1wbGVtZW50cyBidXNpbmVzcyBsb2dpYyB2YWxpZGF0aW9ucyB0aGF0IGNhbid0IGJlIGV4cHJlc3NlZCBpbiBKU09OIFNjaGVtYVxuICovXG5cbmltcG9ydCB7IFRhYmxlQ29uZmlnIH0gZnJvbSAnLi4vbW9kZWxzL3RhYmxlLWNvbmZpZy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgU2NoZW1hVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vbW9kZWxzL3NjaGVtYS12YWxpZGF0aW9uLmludGVyZmFjZSc7XG5cbi8qKlxuICogVmFsaWRhdGUgY3VzdG9tIGJ1c2luZXNzIHJ1bGVzXG4gKiBAcGFyYW0gY29uZmlnIFRhYmxlIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIEFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUN1c3RvbVJ1bGVzKGNvbmZpZzogVGFibGVDb25maWcpOiBTY2hlbWFWYWxpZGF0aW9uRXJyb3JbXSB7XG4gIGNvbnN0IGVycm9yczogU2NoZW1hVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcblxuICBpZiAoIWNvbmZpZy5jb2x1bW5zIHx8ICFBcnJheS5pc0FycmF5KGNvbmZpZy5jb2x1bW5zKSkge1xuICAgIHJldHVybiBlcnJvcnM7IC8vIExldCBzY2hlbWEgdmFsaWRhdGlvbiBoYW5kbGUgdGhpc1xuICB9XG5cbiAgLy8gMS4gQ2hlY2sgZm9yIGR1cGxpY2F0ZSBjb2x1bW4ga2V5c1xuICBjb25zdCBrZXlzID0gY29uZmlnLmNvbHVtbnMubWFwKGNvbCA9PiBjb2wua2V5KTtcbiAgY29uc3Qga2V5Q291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAga2V5cy5mb3JFYWNoKChrZXksIGluZGV4KSA9PiB7XG4gICAgY29uc3QgY291bnQgPSBrZXlDb3VudHMuZ2V0KGtleSkgfHwgMDtcbiAgICBrZXlDb3VudHMuc2V0KGtleSwgY291bnQgKyAxKTtcbiAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IGAvY29sdW1ucy8ke2luZGV4fS9rZXlgLFxuICAgICAgICBtZXNzYWdlOiBgRHVwbGljYXRlIGNvbHVtbiBrZXk6IFwiJHtrZXl9XCIuIENvbHVtbiBrZXlzIG11c3QgYmUgdW5pcXVlLmAsXG4gICAgICAgIGNvZGU6ICdEVVBMSUNBVEVfS0VZJyxcbiAgICAgICAgdmFsdWU6IGtleSxcbiAgICAgICAgZmllbGQ6IGBjb2x1bW5zWyR7aW5kZXh9XS5rZXlgXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIDIuIFZhbGlkYXRlIHdpZHRoIGNvbnN0cmFpbnRzIGZvciBlYWNoIGNvbHVtblxuICBjb25maWcuY29sdW1ucy5mb3JFYWNoKChjb2x1bW4sIGluZGV4KSA9PiB7XG4gICAgY29uc3QgcHJlZml4ID0gYC9jb2x1bW5zLyR7aW5kZXh9YDtcbiAgICBcbiAgICAvLyBXaWR0aCBjb25zdHJhaW50OiBtaW5XaWR0aCA8PSB3aWR0aCA8PSBtYXhXaWR0aFxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBjb2x1bW4ud2lkdGggPT09ICdudW1iZXInICYmXG4gICAgICBjb2x1bW4ubWluV2lkdGggIT09IHVuZGVmaW5lZCAmJlxuICAgICAgY29sdW1uLndpZHRoIDwgY29sdW1uLm1pbldpZHRoXG4gICAgKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IGAke3ByZWZpeH0vd2lkdGhgLFxuICAgICAgICBtZXNzYWdlOiBgV2lkdGggKCR7Y29sdW1uLndpZHRofSkgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gbWluV2lkdGggKCR7Y29sdW1uLm1pbldpZHRofSlgLFxuICAgICAgICBjb2RlOiAnV0lEVEhfQ09OU1RSQUlOVF9WSU9MQVRJT04nLFxuICAgICAgICB2YWx1ZTogY29sdW1uLndpZHRoLFxuICAgICAgICBmaWVsZDogYGNvbHVtbnNbJHtpbmRleH1dLndpZHRoYFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZW9mIGNvbHVtbi53aWR0aCA9PT0gJ251bWJlcicgJiZcbiAgICAgIGNvbHVtbi5tYXhXaWR0aCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBjb2x1bW4ud2lkdGggPiBjb2x1bW4ubWF4V2lkdGhcbiAgICApIHtcbiAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgcGF0aDogYCR7cHJlZml4fS93aWR0aGAsXG4gICAgICAgIG1lc3NhZ2U6IGBXaWR0aCAoJHtjb2x1bW4ud2lkdGh9KSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtYXhXaWR0aCAoJHtjb2x1bW4ubWF4V2lkdGh9KWAsXG4gICAgICAgIGNvZGU6ICdXSURUSF9DT05TVFJBSU5UX1ZJT0xBVElPTicsXG4gICAgICAgIHZhbHVlOiBjb2x1bW4ud2lkdGgsXG4gICAgICAgIGZpZWxkOiBgY29sdW1uc1ske2luZGV4fV0ud2lkdGhgXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyAzLiBTdGlja3kgY29sdW1ucyBtdXN0IGhhdmUgZGVmaW5lZCB3aWR0aCAobm90ICdhdXRvJylcbiAgICBpZiAoY29sdW1uLnN0aWNreSAmJiAoY29sdW1uLnN0aWNreSA9PT0gJ2xlZnQnIHx8IGNvbHVtbi5zdGlja3kgPT09ICdyaWdodCcpKSB7XG4gICAgICBpZiAoY29sdW1uLndpZHRoID09PSB1bmRlZmluZWQgfHwgY29sdW1uLndpZHRoID09PSAnYXV0bycpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goe1xuICAgICAgICAgIHBhdGg6IGAke3ByZWZpeH0vd2lkdGhgLFxuICAgICAgICAgIG1lc3NhZ2U6IGBTdGlja3kgY29sdW1ucyBtdXN0IGhhdmUgYSBkZWZpbmVkIHdpZHRoIChub3QgJ2F1dG8nKS4gQ29sdW1uIFwiJHtjb2x1bW4ua2V5fVwiIGlzIHN0aWNreSBidXQgaGFzIG5vIHdpZHRoLmAsXG4gICAgICAgICAgY29kZTogJ1NUSUNLWV9XSURUSF9SRVFVSVJFRCcsXG4gICAgICAgICAgdmFsdWU6IGNvbHVtbi53aWR0aCxcbiAgICAgICAgICBmaWVsZDogYGNvbHVtbnNbJHtpbmRleH1dLndpZHRoYFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyA0LiBDb2x1bW4ga2V5IGZvcm1hdCB2YWxpZGF0aW9uIChzaG91bGQgYmUgdmFsaWQgaWRlbnRpZmllcilcbiAgICBpZiAoY29sdW1uLmtleSAmJiAhL15bYS16QS1aXyRdW2EtekEtWjAtOV8kXSokLy50ZXN0KGNvbHVtbi5rZXkpKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IGAke3ByZWZpeH0va2V5YCxcbiAgICAgICAgbWVzc2FnZTogYENvbHVtbiBrZXkgXCIke2NvbHVtbi5rZXl9XCIgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXIgKGxldHRlcnMsIG51bWJlcnMsIHVuZGVyc2NvcmUsIGRvbGxhciBzaWduLCBzdGFydGluZyB3aXRoIGxldHRlci91bmRlcnNjb3JlL2RvbGxhcilgLFxuICAgICAgICBjb2RlOiAnSU5WQUxJRF9LRVlfRk9STUFUJyxcbiAgICAgICAgdmFsdWU6IGNvbHVtbi5rZXksXG4gICAgICAgIGZpZWxkOiBgY29sdW1uc1ske2luZGV4fV0ua2V5YFxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICAvLyA1LiBWYWxpZGF0ZSBwYWdpbmF0aW9uIHBhZ2VTaXplIGlzIGluIHBhZ2VTaXplT3B0aW9ucyAoaWYgYm90aCBwcm92aWRlZClcbiAgaWYgKGNvbmZpZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZSAmJiBjb25maWcucGFnaW5hdGlvbj8ucGFnZVNpemVPcHRpb25zKSB7XG4gICAgaWYgKCFjb25maWcucGFnaW5hdGlvbi5wYWdlU2l6ZU9wdGlvbnMuaW5jbHVkZXMoY29uZmlnLnBhZ2luYXRpb24ucGFnZVNpemUpKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6ICcvcGFnaW5hdGlvbi9wYWdlU2l6ZScsXG4gICAgICAgIG1lc3NhZ2U6IGBwYWdlU2l6ZSAoJHtjb25maWcucGFnaW5hdGlvbi5wYWdlU2l6ZX0pIG11c3QgYmUgb25lIG9mIHRoZSBwYWdlU2l6ZU9wdGlvbnM6IFske2NvbmZpZy5wYWdpbmF0aW9uLnBhZ2VTaXplT3B0aW9ucy5qb2luKCcsICcpfV1gLFxuICAgICAgICBjb2RlOiAnUEFHRV9TSVpFX05PVF9JTl9PUFRJT05TJyxcbiAgICAgICAgdmFsdWU6IGNvbmZpZy5wYWdpbmF0aW9uLnBhZ2VTaXplLFxuICAgICAgICBmaWVsZDogJ3BhZ2luYXRpb24ucGFnZVNpemUnXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyA2LiBWYWxpZGF0ZSBpbml0aWFsIHN0YXRlIHNvcnRCeSBrZXlzIGV4aXN0IGluIGNvbHVtbnNcbiAgaWYgKGNvbmZpZy5pbml0aWFsU3RhdGU/LnNvcnRCeSkge1xuICAgIGNvbnN0IGNvbHVtbktleXMgPSBuZXcgU2V0KGNvbmZpZy5jb2x1bW5zLm1hcChjb2wgPT4gY29sLmtleSkpO1xuICAgIGNvbmZpZy5pbml0aWFsU3RhdGUuc29ydEJ5LmZvckVhY2goKHNvcnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWNvbHVtbktleXMuaGFzKHNvcnQua2V5KSkge1xuICAgICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgICAgcGF0aDogYC9pbml0aWFsU3RhdGUvc29ydEJ5LyR7aW5kZXh9L2tleWAsXG4gICAgICAgICAgbWVzc2FnZTogYFNvcnQga2V5IFwiJHtzb3J0LmtleX1cIiBkb2VzIG5vdCBleGlzdCBpbiBjb2x1bW5zYCxcbiAgICAgICAgICBjb2RlOiAnSU5WQUxJRF9TT1JUX0tFWScsXG4gICAgICAgICAgdmFsdWU6IHNvcnQua2V5LFxuICAgICAgICAgIGZpZWxkOiBgaW5pdGlhbFN0YXRlLnNvcnRCeVske2luZGV4fV0ua2V5YFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIDcuIFZhbGlkYXRlIGluaXRpYWwgc3RhdGUgZmlsdGVyIGtleXMgZXhpc3QgaW4gY29sdW1uc1xuICBpZiAoY29uZmlnLmluaXRpYWxTdGF0ZT8uZmlsdGVycykge1xuICAgIGNvbnN0IGNvbHVtbktleXMgPSBuZXcgU2V0KGNvbmZpZy5jb2x1bW5zLm1hcChjb2wgPT4gY29sLmtleSkpO1xuICAgIGNvbmZpZy5pbml0aWFsU3RhdGUuZmlsdGVycy5mb3JFYWNoKChmaWx0ZXIsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWNvbHVtbktleXMuaGFzKGZpbHRlci5rZXkpKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgICBwYXRoOiBgL2luaXRpYWxTdGF0ZS9maWx0ZXJzLyR7aW5kZXh9L2tleWAsXG4gICAgICAgICAgbWVzc2FnZTogYEZpbHRlciBrZXkgXCIke2ZpbHRlci5rZXl9XCIgZG9lcyBub3QgZXhpc3QgaW4gY29sdW1uc2AsXG4gICAgICAgICAgY29kZTogJ0lOVkFMSURfRklMVEVSX0tFWScsXG4gICAgICAgICAgdmFsdWU6IGZpbHRlci5rZXksXG4gICAgICAgICAgZmllbGQ6IGBpbml0aWFsU3RhdGUuZmlsdGVyc1ske2luZGV4fV0ua2V5YFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBlcnJvcnM7XG59XG5cbiJdfQ==
@@ -0,0 +1,216 @@
1
+ /**
2
+ * JSON Schema Validation Service
3
+ * Validates TableConfig JSON against JSON Schema using ajv
4
+ *
5
+ */
6
+ import { Injectable } from '@angular/core';
7
+ import { tableConfigSchema } from '../schemas/table-config.schema';
8
+ import { validateCustomRules } from './custom-validation-rules.util';
9
+ import Ajv from 'ajv';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "./validation-logger.service";
12
+ export class JsonSchemaValidatorService {
13
+ constructor(logger) {
14
+ this.logger = logger;
15
+ this.ajv = null;
16
+ this.validateFn = null;
17
+ this.ajvAvailable = false;
18
+ this.initialized = false;
19
+ }
20
+ /**
21
+ * Ensure ajv is initialized (lazy initialization)
22
+ */
23
+ ensureInitialized() {
24
+ if (!this.initialized) {
25
+ this.initializeAjv();
26
+ this.initialized = true;
27
+ }
28
+ }
29
+ /**
30
+ * Initialize ajv validator
31
+ */
32
+ initializeAjv() {
33
+ try {
34
+ // Try to load ajv - use require for compatibility with Angular build system
35
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
36
+ this.ajv = new Ajv({
37
+ allErrors: true,
38
+ verbose: true,
39
+ strict: false,
40
+ validateSchema: false // Don't validate the schema itself
41
+ });
42
+ // Compile schema (convert const to regular object for ajv)
43
+ const schema = JSON.parse(JSON.stringify(tableConfigSchema));
44
+ this.validateFn = this.ajv.compile(schema);
45
+ this.ajvAvailable = true;
46
+ }
47
+ catch (error) {
48
+ // ajv is optional - if not installed, validation will use custom rules only
49
+ console.warn('ajv library not found. JSON schema validation will be disabled. Install with: npm install ajv');
50
+ this.ajvAvailable = false;
51
+ }
52
+ }
53
+ /**
54
+ * Validate JSON data against TableConfig schema
55
+ * @param data JSON data to validate
56
+ * @param includeCustomRules Whether to include custom business rule validations
57
+ * @param enableLogging Whether to log validation errors (default: true)
58
+ * @returns Validation result
59
+ */
60
+ validate(data, includeCustomRules = true, enableLogging = true) {
61
+ // Ensure ajv is initialized before validation
62
+ this.ensureInitialized();
63
+ const allErrors = [];
64
+ // 1. JSON Schema validation (if ajv is available)
65
+ if (this.ajvAvailable) {
66
+ const isValid = this.validateFn(data);
67
+ if (!isValid) {
68
+ // Convert ajv errors to our format
69
+ const schemaErrors = (this.validateFn.errors || []).map((error) => {
70
+ const path = error.instancePath || error.schemaPath || '';
71
+ const field = this.pathToFieldName(path);
72
+ return {
73
+ path: path,
74
+ message: this.formatErrorMessage(error, field),
75
+ code: error.keyword || 'VALIDATION_ERROR',
76
+ value: error.data,
77
+ field: field
78
+ };
79
+ });
80
+ allErrors.push(...schemaErrors);
81
+ }
82
+ }
83
+ else {
84
+ // If ajv is not available, add a warning but continue with custom rules
85
+ allErrors.push({
86
+ path: '',
87
+ message: 'JSON schema validation is not available. Please install ajv: npm install ajv',
88
+ code: 'AJV_NOT_AVAILABLE',
89
+ field: 'root'
90
+ });
91
+ }
92
+ // 2. Custom business rule validation
93
+ if (includeCustomRules && data && typeof data === 'object') {
94
+ try {
95
+ const customErrors = validateCustomRules(data);
96
+ allErrors.push(...customErrors);
97
+ }
98
+ catch (error) {
99
+ allErrors.push({
100
+ path: '',
101
+ message: `Custom validation failed: ${error.message}`,
102
+ code: 'CUSTOM_VALIDATION_ERROR',
103
+ field: 'root'
104
+ });
105
+ }
106
+ }
107
+ const result = {
108
+ valid: allErrors.length === 0,
109
+ errors: allErrors,
110
+ ajvAvailable: this.ajvAvailable
111
+ };
112
+ // Log validation errors if validation failed and logging is enabled
113
+ if (!result.valid && enableLogging) {
114
+ this.logger.logValidationErrors(allErrors, 'schema-validation');
115
+ }
116
+ return result;
117
+ }
118
+ /**
119
+ * Validate JSON string
120
+ * @param jsonString JSON string to validate
121
+ * @param includeCustomRules Whether to include custom business rule validations
122
+ * @param enableLogging Whether to log validation errors (default: true)
123
+ * @returns Validation result
124
+ */
125
+ validateJSONString(jsonString, includeCustomRules = true, enableLogging = true) {
126
+ try {
127
+ const data = JSON.parse(jsonString);
128
+ return this.validate(data, includeCustomRules, enableLogging);
129
+ }
130
+ catch (error) {
131
+ const result = {
132
+ valid: false,
133
+ errors: [{
134
+ path: '',
135
+ message: `Invalid JSON: ${error.message}`,
136
+ code: 'JSON_PARSE_ERROR',
137
+ value: jsonString,
138
+ field: 'root'
139
+ }],
140
+ ajvAvailable: this.ajvAvailable
141
+ };
142
+ // Log JSON parse errors if logging is enabled
143
+ if (enableLogging) {
144
+ this.logger.logValidationErrors(result.errors, 'schema-validation', {
145
+ configSnippet: jsonString.substring(0, 200) // Include first 200 chars as context
146
+ });
147
+ }
148
+ return result;
149
+ }
150
+ }
151
+ /**
152
+ * Check if ajv is available
153
+ */
154
+ isAvailable() {
155
+ this.ensureInitialized();
156
+ return this.ajvAvailable;
157
+ }
158
+ /**
159
+ * Convert JSON path to user-friendly field name
160
+ */
161
+ pathToFieldName(path) {
162
+ if (!path)
163
+ return 'root';
164
+ // Remove leading slash
165
+ let field = path.replace(/^\//, '');
166
+ // Replace array indices with brackets
167
+ field = field.replace(/\/(\d+)/g, '[$1]');
168
+ // Replace slashes with dots
169
+ field = field.replace(/\//g, '.');
170
+ return field || 'root';
171
+ }
172
+ /**
173
+ * Format error message from ajv error
174
+ */
175
+ formatErrorMessage(error, field) {
176
+ const keyword = error.keyword;
177
+ const params = error.params || {};
178
+ switch (keyword) {
179
+ case 'required':
180
+ return `Field '${field}' is required but missing`;
181
+ case 'type':
182
+ return `Field '${field}' must be of type ${params.type}, but got ${typeof error.data}`;
183
+ case 'enum':
184
+ return `Field '${field}' must be one of: ${params.allowedValues?.join(', ') || 'allowed values'}`;
185
+ case 'pattern':
186
+ return `Field '${field}' does not match required pattern: ${params.pattern}`;
187
+ case 'minimum':
188
+ return `Field '${field}' must be at least ${params.limit}`;
189
+ case 'maximum':
190
+ return `Field '${field}' must be at most ${params.limit}`;
191
+ case 'minLength':
192
+ return `Field '${field}' must have at least ${params.limit} items`;
193
+ case 'maxLength':
194
+ return `Field '${field}' must have at most ${params.limit} items`;
195
+ case 'minItems':
196
+ return `Array '${field}' must have at least ${params.limit} items`;
197
+ case 'maxItems':
198
+ return `Array '${field}' must have at most ${params.limit} items`;
199
+ case 'additionalProperties':
200
+ return `Field '${field}' contains unknown property: ${params.additionalProperty}`;
201
+ case 'oneOf':
202
+ return `Field '${field}' does not match any of the allowed types`;
203
+ default:
204
+ return error.message || `Field '${field}' is invalid`;
205
+ }
206
+ }
207
+ }
208
+ JsonSchemaValidatorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JsonSchemaValidatorService, deps: [{ token: i1.ValidationLoggerService }], target: i0.ɵɵFactoryTarget.Injectable });
209
+ JsonSchemaValidatorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JsonSchemaValidatorService, providedIn: 'root' });
210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JsonSchemaValidatorService, decorators: [{
211
+ type: Injectable,
212
+ args: [{
213
+ providedIn: 'root'
214
+ }]
215
+ }], ctorParameters: function () { return [{ type: i1.ValidationLoggerService }]; } });
216
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEtdmFsaWRhdG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zbWFydC10YWJsZS9zcmMvbGliL3NlcnZpY2VzL2pzb24tc2NoZW1hLXZhbGlkYXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBR3JFLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQzs7O0FBTXRCLE1BQU0sT0FBTywwQkFBMEI7SUFNckMsWUFBb0IsTUFBK0I7UUFBL0IsV0FBTSxHQUFOLE1BQU0sQ0FBeUI7UUFMM0MsUUFBRyxHQUFRLElBQUksQ0FBQztRQUNoQixlQUFVLEdBQVEsSUFBSSxDQUFDO1FBQ3ZCLGlCQUFZLEdBQVksS0FBSyxDQUFDO1FBQzlCLGdCQUFXLEdBQVksS0FBSyxDQUFDO0lBR3JDLENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNyQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7U0FDekI7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxhQUFhO1FBQ25CLElBQUk7WUFDRiw0RUFBNEU7WUFDNUUsdUVBQXVFO1lBQ3ZFLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7Z0JBQ2pCLFNBQVMsRUFBRSxJQUFJO2dCQUNmLE9BQU8sRUFBRSxJQUFJO2dCQUNiLE1BQU0sRUFBRSxLQUFLO2dCQUNiLGNBQWMsRUFBRSxLQUFLLENBQUMsbUNBQW1DO2FBQzFELENB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c0IsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRTdELEtBQUssU0FBUztnQkFDWixPQUFPLFVBQVUsS0FBSyxxQkFBcUIsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRTVELEtBQUssV0FBVztnQkFDZCxPQUFPLFVBQVUsS0FBSyx3QkFBd0IsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXJFLEtBQUssV0FBVztnQkFDZCxPQUFPLFVBQVUsS0FBSyx1QkFBdUIsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXBFLEtBQUssVUFBVTtnQkFDYixPQUFPLFVBQVUsS0FBSyx3QkFBd0IsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXJFLEtBQUssVUFBVTtnQkFDYixPQUFPLFVBQVUsS0FBSyx1QkFBdUIsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXBFLEtBQUssc0JBQXNCO2dCQUN6QixPQUFPLFVBQVUsS0FBSyxnQ0FBZ0MsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFFcEYsS0FBSyxPQUFPO2dCQUNWLE9BQU8sVUFBVSxLQUFLLDJDQUEyQyxDQUFDO1lBRXBFO2dCQUNFLE9BQU8sS0FBSyxDQUFDLE9BQU8sSUFBSSxVQUFVLEtBQUssY0FBYyxDQUFDO1NBQ3pEO0lBQ0gsQ0FBQzs7dUhBak9VLDBCQUEwQjsySEFBMUIsMEJBQTBCLGNBRnpCLE1BQU07MkZBRVAsMEJBQTBCO2tCQUh0QyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSlNPTiBTY2hlbWEgVmFsaWRhdGlvbiBTZXJ2aWNlXG4gKiBWYWxpZGF0ZXMgVGFibGVDb25maWcgSlNPTiBhZ2FpbnN0IEpTT04gU2NoZW1hIHVzaW5nIGFqdlxuICogXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFibGVDb25maWdTY2hlbWEgfSBmcm9tICcuLi9zY2hlbWFzL3RhYmxlLWNvbmZpZy5zY2hlbWEnO1xuaW1wb3J0IHsgdmFsaWRhdGVDdXN0b21SdWxlcyB9IGZyb20gJy4vY3VzdG9tLXZhbGlkYXRpb24tcnVsZXMudXRpbCc7XG5pbXBvcnQgeyBWYWxpZGF0aW9uTG9nZ2VyU2VydmljZSB9IGZyb20gJy4vdmFsaWRhdGlvbi1sb2dnZXIuc2VydmljZSc7XG5pbXBvcnQgeyBTY2hlbWFWYWxpZGF0aW9uRXJyb3IsIFNjaGVtYVZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuLi9tb2RlbHMvc2NoZW1hLXZhbGlkYXRpb24uaW50ZXJmYWNlJztcbmltcG9ydCBBanYgZnJvbSAnYWp2JztcblxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBKc29uU2NoZW1hVmFsaWRhdG9yU2VydmljZSB7XG4gIHByaXZhdGUgYWp2OiBhbnkgPSBudWxsO1xuICBwcml2YXRlIHZhbGlkYXRlRm46IGFueSA9IG51bGw7XG4gIHByaXZhdGUgYWp2QXZhaWxhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgaW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGxvZ2dlcjogVmFsaWRhdGlvbkxvZ2dlclNlcnZpY2UpIHtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmUgYWp2IGlzIGluaXRpYWxpemVkIChsYXp5IGluaXRpYWxpemF0aW9uKVxuICAgKi9cbiAgcHJpdmF0ZSBlbnN1cmVJbml0aWFsaXplZCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUFqdigpO1xuICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgYWp2IHZhbGlkYXRvclxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQWp2KCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICAvLyBUcnkgdG8gbG9hZCBhanYgLSB1c2UgcmVxdWlyZSBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIEFuZ3VsYXIgYnVpbGQgc3lzdGVtXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAgICAgIFxuICAgICAgdGhpcy5hanYgPSBuZXcgQWp2KHtcbiAgICAgICAgYWxsRXJyb3JzOiB0cnVlLFxuICAgICAgICB2ZXJib3NlOiB0cnVlLFxuICAgICAgICBzdHJpY3Q6IGZhbHNlLFxuICAgICAgICB2YWxpZGF0ZVNjaGVtYTogZmFsc2UgLy8gRG9uJ3QgdmFsaWRhdGUgdGhlIHNjaGVtYSBpdHNlbGZcbiAgICAgIH0pO1xuXG4gICAgICAvLyBDb21waWxlIHNjaGVtYSAoY29udmVydCBjb25zdCB0byByZWd1bGFyIG9iamVjdCBmb3IgYWp2KVxuICAgICAgY29uc3Qgc2NoZW1hID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0YWJsZUNvbmZpZ1NjaGVtYSkpO1xuICAgICAgdGhpcy52YWxpZGF0ZUZuID0gdGhpcy5hanYuY29tcGlsZShzY2hlbWEpO1xuICAgICAgdGhpcy5hanZBdmFpbGFibGUgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBhanYgaXMgb3B0aW9uYWwgLSBpZiBub3QgaW5zdGFsbGVkLCB2YWxpZGF0aW9uIHdpbGwgdXNlIGN1c3RvbSBydWxlcyBvbmx5XG4gICAgICBjb25zb2xlLndhcm4oJ2FqdiBsaWJyYXJ5IG5vdCBmb3VuZC4gSlNPTiBzY2hlbWEgdmFsaWRhdGlvbiB3aWxsIGJlIGRpc2FibGVkLiBJbnN0YWxsIHdpdGg6IG5wbSBpbnN0YWxsIGFqdicpO1xuICAgICAgdGhpcy5hanZBdmFpbGFibGUgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgSlNPTiBkYXRhIGFnYWluc3QgVGFibGVDb25maWcgc2NoZW1hXG4gICAqIEBwYXJhbSBkYXRhIEpTT04gZGF0YSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0gaW5jbHVkZUN1c3RvbVJ1bGVzIFdoZXRoZXIgdG8gaW5jbHVkZSBjdXN0b20gYnVzaW5lc3MgcnVsZSB2YWxpZGF0aW9uc1xuICAgKiBAcGFyYW0gZW5hYmxlTG9nZ2luZyBXaGV0aGVyIHRvIGxvZyB2YWxpZGF0aW9uIGVycm9ycyAoZGVmYXVsdDogdHJ1ZSlcbiAgICogQHJldHVybnMgVmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIHZhbGlkYXRlKGRhdGE6IGFueSwgaW5jbHVkZUN1c3RvbVJ1bGVzOiBib29sZWFuID0gdHJ1ZSwgZW5hYmxlTG9nZ2luZzogYm9vbGVhbiA9IHRydWUpOiBTY2hlbWFWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICAvLyBFbnN1cmUgYWp2IGlzIGluaXRpYWxpemVkIGJlZm9yZSB2YWxpZGF0aW9uXG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIFxuICAgIGNvbnN0IGFsbEVycm9yczogU2NoZW1hVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcblxuICAgIC8vIDEuIEpTT04gU2NoZW1hIHZhbGlkYXRpb24gKGlmIGFqdiBpcyBhdmFpbGFibGUpXG4gICAgaWYgKHRoaXMuYWp2QXZhaWxhYmxlKSB7XG4gICAgICBjb25zdCBpc1ZhbGlkID0gdGhpcy52YWxpZGF0ZUZuKGRhdGEpO1xuXG4gICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgLy8gQ29udmVydCBhanYgZXJyb3JzIHRvIG91ciBmb3JtYXRcbiAgICAgICAgY29uc3Qgc2NoZW1hRXJyb3JzOiBTY2hlbWFWYWxpZGF0aW9uRXJyb3JbXSA9ICh0aGlzLnZhbGlkYXRlRm4uZXJyb3JzIHx8IFtdKS5tYXAoKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgICBjb25zdCBwYXRoID0gZXJyb3IuaW5zdGFuY2VQYXRoIHx8IGVycm9yLnNjaGVtYVBhdGggfHwgJyc7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSB0aGlzLnBhdGhUb0ZpZWxkTmFtZShwYXRoKTtcbiAgICAgICAgICBcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IHRoaXMuZm9ybWF0RXJyb3JNZXNzYWdlKGVycm9yLCBmaWVsZCksXG4gICAgICAgICAgICBjb2RlOiBlcnJvci5rZXl3b3JkIHx8ICdWQUxJREFUSU9OX0VSUk9SJyxcbiAgICAgICAgICAgIHZhbHVlOiBlcnJvci5kYXRhLFxuICAgICAgICAgICAgZmllbGQ6IGZpZWxkXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYWxsRXJyb3JzLnB1c2goLi4uc2NoZW1hRXJyb3JzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgYWp2IGlzIG5vdCBhdmFpbGFibGUsIGFkZCBhIHdhcm5pbmcgYnV0IGNvbnRpbnVlIHdpdGggY3VzdG9tIHJ1bGVzXG4gICAgICBhbGxFcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6ICcnLFxuICAgICAgICBtZXNzYWdlOiAnSlNPTiBzY2hlbWEgdmFsaWRhdGlvbiBpcyBub3QgYXZhaWxhYmxlLiBQbGVhc2UgaW5zdGFsbCBhanY6IG5wbSBpbnN0YWxsIGFqdicsXG4gICAgICAgIGNvZGU6ICdBSlZfTk9UX0FWQUlMQUJMRScsXG4gICAgICAgIGZpZWxkOiAncm9vdCdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIDIuIEN1c3RvbSBidXNpbmVzcyBydWxlIHZhbGlkYXRpb25cbiAgICBpZiAoaW5jbHVkZUN1c3RvbVJ1bGVzICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjdXN0b21FcnJvcnMgPSB2YWxpZGF0ZUN1c3RvbVJ1bGVzKGRhdGEgYXMgYW55KTtcbiAgICAgICAgYWxsRXJyb3JzLnB1c2goLi4uY3VzdG9tRXJyb3JzKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgYWxsRXJyb3JzLnB1c2goe1xuICAgICAgICAgIHBhdGg6ICcnLFxuICAgICAgICAgIG1lc3NhZ2U6IGBDdXN0b20gdmFsaWRhdGlvbiBmYWlsZWQ6ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgIGNvZGU6ICdDVVNUT01fVkFMSURBVElPTl9FUlJPUicsXG4gICAgICAgICAgZmllbGQ6ICdyb290J1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICB2YWxpZDogYWxsRXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICAgIGVycm9yczogYWxsRXJyb3JzLFxuICAgICAgYWp2QXZhaWxhYmxlOiB0aGlzLmFqdkF2YWlsYWJsZVxuICAgIH07XG5cbiAgICAvLyBMb2cgdmFsaWRhdGlvbiBlcnJvcnMgaWYgdmFsaWRhdGlvbiBmYWlsZWQgYW5kIGxvZ2dpbmcgaXMgZW5hYmxlZFxuICAgIGlmICghcmVzdWx0LnZhbGlkICYmIGVuYWJsZUxvZ2dpbmcpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmxvZ1ZhbGlkYXRpb25FcnJvcnMoYWxsRXJyb3JzLCAnc2NoZW1hLXZhbGlkYXRpb24nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIEpTT04gc3RyaW5nXG4gICAqIEBwYXJhbSBqc29uU3RyaW5nIEpTT04gc3RyaW5nIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBpbmNsdWRlQ3VzdG9tUnVsZXMgV2hldGhlciB0byBpbmNsdWRlIGN1c3RvbSBidXNpbmVzcyBydWxlIHZhbGlkYXRpb25zXG4gICAqIEBwYXJhbSBlbmFibGVMb2dnaW5nIFdoZXRoZXIgdG8gbG9nIHZhbGlkYXRpb24gZXJyb3JzIChkZWZhdWx0OiB0cnVlKVxuICAgKiBAcmV0dXJucyBWYWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgdmFsaWRhdGVKU09OU3RyaW5nKGpzb25TdHJpbmc6IHN0cmluZywgaW5jbHVkZUN1c3RvbVJ1bGVzOiBib29sZWFuID0gdHJ1ZSwgZW5hYmxlTG9nZ2luZzogYm9vbGVhbiA9IHRydWUpOiBTY2hlbWFWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoanNvblN0cmluZyk7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShkYXRhLCBpbmNsdWRlQ3VzdG9tUnVsZXMsIGVuYWJsZUxvZ2dpbmcpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBlcnJvcnM6IFt7XG4gICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgbWVzc2FnZTogYEludmFsaWQgSlNPTjogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgICAgY29kZTogJ0pTT05fUEFSU0VfRVJST1InLFxuICAgICAgICAgIHZhbHVlOiBqc29uU3RyaW5nLFxuICAgICAgICAgIGZpZWxkOiAncm9vdCdcbiAgICAgICAgfV0sXG4gICAgICAgIGFqdkF2YWlsYWJsZTogdGhpcy5hanZBdmFpbGFibGVcbiAgICAgIH07XG5cbiAgICAgIC8vIExvZyBKU09OIHBhcnNlIGVycm9ycyBpZiBsb2dnaW5nIGlzIGVuYWJsZWRcbiAgICAgIGlmIChlbmFibGVMb2dnaW5nKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmxvZ1ZhbGlkYXRpb25FcnJvcnMocmVzdWx0LmVycm9ycywgJ3NjaGVtYS12YWxpZGF0aW9uJywge1xuICAgICAgICAgIGNvbmZpZ1NuaXBwZXQ6IGpzb25TdHJpbmcuc3Vic3RyaW5nKDAsIDIwMCkgLy8gSW5jbHVkZSBmaXJzdCAyMDAgY2hhcnMgYXMgY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYWp2IGlzIGF2YWlsYWJsZVxuICAgKi9cbiAgaXNBdmFpbGFibGUoKTogYm9vbGVhbiB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIHJldHVybiB0aGlzLmFqdkF2YWlsYWJsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IEpTT04gcGF0aCB0byB1c2VyLWZyaWVuZGx5IGZpZWxkIG5hbWVcbiAgICovXG4gIHByaXZhdGUgcGF0aFRvRmllbGROYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFwYXRoKSByZXR1cm4gJ3Jvb3QnO1xuICAgIFxuICAgIC8vIFJlbW92ZSBsZWFkaW5nIHNsYXNoXG4gICAgbGV0IGZpZWxkID0gcGF0aC5yZXBsYWNlKC9eXFwvLywgJycpO1xuICAgIFxuICAgIC8vIFJlcGxhY2UgYXJyYXkgaW5kaWNlcyB3aXRoIGJyYWNrZXRzXG4gICAgZmllbGQgPSBmaWVsZC5yZXBsYWNlKC9cXC8oXFxkKykvZywgJ1skMV0nKTtcbiAgICBcbiAgICAvLyBSZXBsYWNlIHNsYXNoZXMgd2l0aCBkb3RzXG4gICAgZmllbGQgPSBmaWVsZC5yZXBsYWNlKC9cXC8vZywgJy4nKTtcbiAgICBcbiAgICByZXR1cm4gZmllbGQgfHwgJ3Jvb3QnO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBlcnJvciBtZXNzYWdlIGZyb20gYWp2IGVycm9yXG4gICAqL1xuICBwcml2YXRlIGZvcm1hdEVycm9yTWVzc2FnZShlcnJvcjogYW55LCBmaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBrZXl3b3JkID0gZXJyb3Iua2V5d29yZDtcbiAgICBjb25zdCBwYXJhbXMgPSBlcnJvci5wYXJhbXMgfHwge307XG4gICAgXG4gICAgc3dpdGNoIChrZXl3b3JkKSB7XG4gICAgICBjYXNlICdyZXF1aXJlZCc6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBpcyByZXF1aXJlZCBidXQgbWlzc2luZ2A7XG4gICAgICBcbiAgICAgIGNhc2UgJ3R5cGUnOlxuICAgICAgICByZXR1cm4gYEZpZWxkICcke2ZpZWxkfScgbXVzdCBiZSBvZiB0eXBlICR7cGFyYW1zLnR5cGV9LCBidXQgZ290ICR7dHlwZW9mIGVycm9yLmRhdGF9YDtcbiAgICAgIFxuICAgICAgY2FzZSAnZW51bSc6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBtdXN0IGJlIG9uZSBvZjogJHtwYXJhbXMuYWxsb3dlZFZhbHVlcz8uam9pbignLCAnKSB8fCAnYWxsb3dlZCB2YWx1ZXMnfWA7XG4gICAgICBcbiAgICAgIGNhc2UgJ3BhdHRlcm4nOlxuICAgICAgICByZXR1cm4gYEZpZWxkICcke2ZpZWxkfScgZG9lcyBub3QgbWF0Y2ggcmVxdWlyZWQgcGF0dGVybjogJHtwYXJhbXMucGF0dGVybn1gO1xuICAgICAgXG4gICAgICBjYXNlICdtaW5pbXVtJzpcbiAgICAgICAgcmV0dXJuIGBGaWVsZCAnJHtmaWVsZH0nIG11c3QgYmUgYXQgbGVhc3QgJHtwYXJhbXMubGltaXR9YDtcbiAgICAgIFxuICAgICAgY2FzZSAnbWF4aW11bSc6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBtdXN0IGJlIGF0IG1vc3QgJHtwYXJhbXMubGltaXR9YDtcbiAgICAgIFxuICAgICAgY2FzZSAnbWluTGVuZ3RoJzpcbiAgICAgICAgcmV0dXJuIGBGaWVsZCAnJHtmaWVsZH0nIG11c3QgaGF2ZSBhdCBsZWFzdCAke3BhcmFtcy5saW1pdH0gaXRlbXNgO1xuICAgICAgXG4gICAgICBjYXNlICdtYXhMZW5ndGgnOlxuICAgICAgICByZXR1cm4gYEZpZWxkICcke2ZpZWxkfScgbXVzdCBoYXZlIGF0IG1vc3QgJHtwYXJhbXMubGltaXR9IGl0ZW1zYDtcbiAgICAgIFxuICAgICAgY2FzZSAnbWluSXRlbXMnOlxuICAgICAgICByZXR1cm4gYEFycmF5ICcke2ZpZWxkfScgbXVzdCBoYXZlIGF0IGxlYXN0ICR7cGFyYW1zLmxpbWl0fSBpdGVtc2A7XG4gICAgICBcbiAgICAgIGNhc2UgJ21heEl0ZW1zJzpcbiAgICAgICAgcmV0dXJuIGBBcnJheSAnJHtmaWVsZH0nIG11c3QgaGF2ZSBhdCBtb3N0ICR7cGFyYW1zLmxpbWl0fSBpdGVtc2A7XG4gICAgICBcbiAgICAgIGNhc2UgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJzpcbiAgICAgICAgcmV0dXJuIGBGaWVsZCAnJHtmaWVsZH0nIGNvbnRhaW5zIHVua25vd24gcHJvcGVydHk6ICR7cGFyYW1zLmFkZGl0aW9uYWxQcm9wZXJ0eX1gO1xuICAgICAgXG4gICAgICBjYXNlICdvbmVPZic6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBkb2VzIG5vdCBtYXRjaCBhbnkgb2YgdGhlIGFsbG93ZWQgdHlwZXNgO1xuICAgICAgXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZXJyb3IubWVzc2FnZSB8fCBgRmllbGQgJyR7ZmllbGR9JyBpcyBpbnZhbGlkYDtcbiAgICB9XG4gIH1cbn1cblxuIl19
@@ -0,0 +1,42 @@
1
+ import { Injectable } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class RowValidationService {
4
+ /**
5
+ * Validate a single row
6
+ */
7
+ validateRow(rowData, cells, rowIndex, validator) {
8
+ try {
9
+ return validator.validateRow(rowData, cells, rowIndex);
10
+ }
11
+ catch (error) {
12
+ return {
13
+ valid: false,
14
+ error: `Validation error: ${error.message}`,
15
+ errors: [error.message]
16
+ };
17
+ }
18
+ }
19
+ /**
20
+ * Validate entire table
21
+ */
22
+ validateTable(rows, config, validator, rowValidationResults) {
23
+ try {
24
+ return validator.validateTable(rows, config, rowValidationResults);
25
+ }
26
+ catch (error) {
27
+ return {
28
+ valid: false,
29
+ globalErrors: [`Table validation error: ${error.message}`]
30
+ };
31
+ }
32
+ }
33
+ }
34
+ RowValidationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: RowValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
35
+ RowValidationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: RowValidationService, providedIn: 'root' });
36
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: RowValidationService, decorators: [{
37
+ type: Injectable,
38
+ args: [{
39
+ providedIn: 'root'
40
+ }]
41
+ }] });
42
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm93LXZhbGlkYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvc2VydmljZXMvcm93LXZhbGlkYXRpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVMzQyxNQUFNLE9BQU8sb0JBQW9CO0lBQy9COztPQUVHO0lBQ0gsV0FBVyxDQUNULE9BQVksRUFDWixLQUFhLEVBQ2IsUUFBZ0IsRUFDaEIsU0FBdUI7UUFFdkIsSUFBSTtZQUNGLE9BQU8sU0FBUyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ3hEO1FBQUMsT0FBTyxLQUFVLEVBQUU7WUFDbkIsT0FBTztnQkFDTCxLQUFLLEVBQUUsS0FBSztnQkFDWixLQUFLLEVBQUUscUJBQXFCLEtBQUssQ0FBQyxPQUFPLEVBQUU7Z0JBQzNDLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7YUFDeEIsQ0FBQztTQUNIO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYSxDQUNYLElBQVcsRUFDWCxNQUFtQixFQUNuQixTQUF5QixFQUN6QixvQkFBdUQ7UUFFdkQsSUFBSTtZQUNGLE9BQU8sU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLG9CQUFvQixDQUFDLENBQUM7U0FDcEU7UUFBQyxPQUFPLEtBQVUsRUFBRTtZQUNuQixPQUFPO2dCQUNMLEtBQUssRUFBRSxLQUFLO2dCQUNaLFlBQVksRUFBRSxDQUFDLDJCQUEyQixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDM0QsQ0FBQztTQUNIO0lBQ0gsQ0FBQzs7aUhBdENVLG9CQUFvQjtxSEFBcEIsb0JBQW9CLGNBRm5CLE1BQU07MkZBRVAsb0JBQW9CO2tCQUhoQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENlbGwgfSBmcm9tICcuLi9yZW5kZXJlci9tb2RlbHMvY2VsbC5jbGFzcyc7XG5pbXBvcnQgeyBSb3dWYWxpZGF0b3IsIFJvd1ZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuLi9tb2RlbHMvcm93LXZhbGlkYXRvci5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGFibGVWYWxpZGF0b3IsIFRhYmxlVmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJy4uL21vZGVscy90YWJsZS12YWxpZGF0b3IuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRhYmxlQ29uZmlnIH0gZnJvbSAnLi4vbW9kZWxzL3RhYmxlLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBSb3dWYWxpZGF0aW9uU2VydmljZSB7XG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIHNpbmdsZSByb3dcbiAgICovXG4gIHZhbGlkYXRlUm93KFxuICAgIHJvd0RhdGE6IGFueSxcbiAgICBjZWxsczogQ2VsbFtdLFxuICAgIHJvd0luZGV4OiBudW1iZXIsXG4gICAgdmFsaWRhdG9yOiBSb3dWYWxpZGF0b3JcbiAgKTogUm93VmFsaWRhdGlvblJlc3VsdCB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGVSb3cocm93RGF0YSwgY2VsbHMsIHJvd0luZGV4KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIGVycm9yOiBgVmFsaWRhdGlvbiBlcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgIGVycm9yczogW2Vycm9yLm1lc3NhZ2VdXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFZhbGlkYXRlIGVudGlyZSB0YWJsZVxuICAgKi9cbiAgdmFsaWRhdGVUYWJsZShcbiAgICByb3dzOiBhbnlbXSxcbiAgICBjb25maWc6IFRhYmxlQ29uZmlnLFxuICAgIHZhbGlkYXRvcjogVGFibGVWYWxpZGF0b3IsXG4gICAgcm93VmFsaWRhdGlvblJlc3VsdHM/OiBNYXA8bnVtYmVyLCBSb3dWYWxpZGF0aW9uUmVzdWx0PlxuICApOiBUYWJsZVZhbGlkYXRpb25SZXN1bHQge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRlVGFibGUocm93cywgY29uZmlnLCByb3dWYWxpZGF0aW9uUmVzdWx0cyk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBnbG9iYWxFcnJvcnM6IFtgVGFibGUgdmFsaWRhdGlvbiBlcnJvcjogJHtlcnJvci5tZXNzYWdlfWBdXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuXG4iXX0=
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Validation Logger Service
3
+ * Automatically logs validation errors and provides functionality to download them as a log file
4
+ */
5
+ import { Injectable } from '@angular/core';
6
+ import * as i0 from "@angular/core";
7
+ export class ValidationLoggerService {
8
+ constructor() {
9
+ this.logEntries = [];
10
+ this.downloadTimeoutId = null;
11
+ this.DOWNLOAD_DELAY_MS = 500; // Wait 500ms after last error before downloading
12
+ }
13
+ /**
14
+ * Log validation errors
15
+ * @param errors Array of validation errors
16
+ * @param source Source of validation (e.g., 'import', 'renderer', 'schema-validation')
17
+ * @param context Optional context information
18
+ * @param autoDownload Whether to automatically download log file (default: true)
19
+ */
20
+ logValidationErrors(errors, source, context, autoDownload = true) {
21
+ if (errors.length === 0) {
22
+ return; // Don't log if there are no errors
23
+ }
24
+ const entry = {
25
+ timestamp: new Date().toISOString(),
26
+ source: source,
27
+ errors: errors,
28
+ context: context
29
+ };
30
+ this.logEntries.push(entry);
31
+ // Schedule automatic download after errors accumulate (debounced)
32
+ if (autoDownload) {
33
+ this.scheduleDownload();
34
+ }
35
+ }
36
+ /**
37
+ * Schedule log file download with debounce
38
+ * This ensures we only download once after all errors are accumulated
39
+ */
40
+ scheduleDownload() {
41
+ // Clear any existing timeout
42
+ if (this.downloadTimeoutId !== null) {
43
+ clearTimeout(this.downloadTimeoutId);
44
+ }
45
+ // Schedule download after delay
46
+ // If more errors come in before timeout fires, this will be cancelled and rescheduled
47
+ this.downloadTimeoutId = setTimeout(() => {
48
+ this.downloadLogFileOnError();
49
+ this.downloadTimeoutId = null;
50
+ }, this.DOWNLOAD_DELAY_MS);
51
+ }
52
+ /**
53
+ * Download log file with timestamped filename
54
+ * Called automatically when validation errors occur (after debounce delay)
55
+ */
56
+ downloadLogFileOnError() {
57
+ // Generate filename with timestamp to avoid overwriting
58
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5); // Format: 2024-01-15T10-30-45
59
+ const filename = `smart-table-validation-errors-${timestamp}.log`;
60
+ this.downloadLogFile(filename);
61
+ }
62
+ /**
63
+ * Get all log entries
64
+ * @returns Array of all log entries
65
+ */
66
+ getLogEntries() {
67
+ return [...this.logEntries];
68
+ }
69
+ /**
70
+ * Format all log entries as plain text
71
+ * @returns Formatted log text
72
+ */
73
+ formatLogAsText() {
74
+ if (this.logEntries.length === 0) {
75
+ return 'No validation errors logged.\n';
76
+ }
77
+ let logText = `Smart Table Validation Error Log\n`;
78
+ logText += `Generated: ${new Date().toISOString()}\n`;
79
+ logText += `Total Validation Failures: ${this.logEntries.length}\n`;
80
+ logText += `${'='.repeat(80)}\n\n`;
81
+ this.logEntries.forEach((entry, index) => {
82
+ logText += this.formatLogEntry(entry, index + 1);
83
+ logText += '\n';
84
+ });
85
+ return logText;
86
+ }
87
+ /**
88
+ * Format a single log entry as plain text
89
+ * @param entry Log entry to format
90
+ * @param entryNumber Entry number (for display)
91
+ * @returns Formatted entry text
92
+ */
93
+ formatLogEntry(entry, entryNumber) {
94
+ let text = `[${entry.timestamp}] Validation Failed - Source: ${entry.source}\n`;
95
+ // Add context information if available
96
+ if (entry.context) {
97
+ if (entry.context.fileName) {
98
+ text += `File: ${entry.context.fileName}\n`;
99
+ }
100
+ if (entry.context.storageKey) {
101
+ text += `Storage Key: ${entry.context.storageKey}\n`;
102
+ }
103
+ if (entry.context.configSnippet) {
104
+ text += `Config Snippet: ${entry.context.configSnippet}\n`;
105
+ }
106
+ }
107
+ text += `${'━'.repeat(80)}\n`;
108
+ // Format each error
109
+ entry.errors.forEach((error, errorIndex) => {
110
+ text += `Error ${errorIndex + 1}:\n`;
111
+ if (error.field) {
112
+ text += ` Field: ${error.field}\n`;
113
+ }
114
+ if (error.path) {
115
+ text += ` Path: ${error.path}\n`;
116
+ }
117
+ if (error.code) {
118
+ text += ` Code: ${error.code}\n`;
119
+ }
120
+ if (error.message) {
121
+ text += ` Message: ${error.message}\n`;
122
+ }
123
+ if (error.value !== undefined && error.value !== null) {
124
+ const valueStr = typeof error.value === 'object'
125
+ ? JSON.stringify(error.value, null, 2).split('\n').map(line => ` ${line}`).join('\n')
126
+ : String(error.value);
127
+ text += ` Value: ${valueStr}\n`;
128
+ }
129
+ text += '\n';
130
+ });
131
+ text += `${'━'.repeat(80)}\n`;
132
+ return text;
133
+ }
134
+ /**
135
+ * Download log file
136
+ * @param filename Optional filename (default: 'smart-table-validation-errors.log')
137
+ */
138
+ downloadLogFile(filename = 'smart-table-validation-errors.log') {
139
+ const logText = this.formatLogAsText();
140
+ const blob = new Blob([logText], { type: 'text/plain' });
141
+ const url = URL.createObjectURL(blob);
142
+ const link = document.createElement('a');
143
+ link.href = url;
144
+ link.download = filename;
145
+ document.body.appendChild(link);
146
+ link.click();
147
+ document.body.removeChild(link);
148
+ URL.revokeObjectURL(url);
149
+ }
150
+ /**
151
+ * Clear all log entries
152
+ */
153
+ clearLog() {
154
+ // Cancel any pending download
155
+ if (this.downloadTimeoutId !== null) {
156
+ clearTimeout(this.downloadTimeoutId);
157
+ this.downloadTimeoutId = null;
158
+ }
159
+ this.logEntries = [];
160
+ }
161
+ /**
162
+ * Get number of log entries
163
+ * @returns Number of log entries
164
+ */
165
+ getLogSize() {
166
+ return this.logEntries.length;
167
+ }
168
+ }
169
+ ValidationLoggerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ValidationLoggerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
170
+ ValidationLoggerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ValidationLoggerService, providedIn: 'root' });
171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ValidationLoggerService, decorators: [{
172
+ type: Injectable,
173
+ args: [{
174
+ providedIn: 'root'
175
+ }]
176
+ }] });
177
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1sb2dnZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvc2VydmljZXMvdmFsaWRhdGlvbi1sb2dnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQW1DM0MsTUFBTSxPQUFPLHVCQUF1QjtJQUhwQztRQUlVLGVBQVUsR0FBeUIsRUFBRSxDQUFDO1FBQ3RDLHNCQUFpQixHQUFRLElBQUksQ0FBQztRQUNyQixzQkFBaUIsR0FBRyxHQUFHLENBQUMsQ0FBQyxpREFBaUQ7S0FnTTVGO0lBOUxDOzs7Ozs7T0FNRztJQUNILG1CQUFtQixDQUNqQixNQUErQixFQUMvQixNQUFjLEVBQ2QsT0FJQyxFQUNELGVBQXdCLElBQUk7UUFFNUIsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUN2QixPQUFPLENBQUMsbUNBQW1DO1NBQzVDO1FBRUQsTUFBTSxLQUFLLEdBQXVCO1lBQ2hDLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUNuQyxNQUFNLEVBQUUsTUFBTTtZQUNkLE1BQU0sRUFBRSxNQUFNO1lBQ2QsT0FBTyxFQUFFLE9BQU87U0FDakIsQ0FBQztRQUVGLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTVCLGtFQUFrRTtRQUNsRSxJQUFJLFlBQVksRUFBRTtZQUNoQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QjtJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSyxnQkFBZ0I7UUFDdEIsNkJBQTZCO1FBQzdCLElBQUksSUFBSSxDQUFDLGlCQUFpQixLQUFLLElBQUksRUFBRTtZQUNuQyxZQUFZLENBQUMsSUFBSSxDQUFDLGlCQUFp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IFNlcnZpY2VcbiAqIEF1dG9tYXRpY2FsbHkgbG9ncyB2YWxpZGF0aW9uIGVycm9ycyBhbmQgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSB0byBkb3dubG9hZCB0aGVtIGFzIGEgbG9nIGZpbGVcbiAqL1xuXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTY2hlbWFWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuLi9tb2RlbHMvc2NoZW1hLXZhbGlkYXRpb24uaW50ZXJmYWNlJztcblxuLyoqXG4gKiBWYWxpZGF0aW9uIGxvZyBlbnRyeSBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uTG9nRW50cnkge1xuICAvKipcbiAgICogSVNPIHRpbWVzdGFtcCB3aGVuIHZhbGlkYXRpb24gZmFpbGVkXG4gICAqL1xuICB0aW1lc3RhbXA6IHN0cmluZztcblxuICAvKipcbiAgICogU291cmNlIG9mIHZhbGlkYXRpb24gKGUuZy4sICdpbXBvcnQnLCAncmVuZGVyZXInLCAnc2NoZW1hLXZhbGlkYXRpb24nKVxuICAgKi9cbiAgc291cmNlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3JzXG4gICAqL1xuICBlcnJvcnM6IFNjaGVtYVZhbGlkYXRpb25FcnJvcltdO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBjb250ZXh0IGluZm9ybWF0aW9uXG4gICAqL1xuICBjb250ZXh0Pzoge1xuICAgIGZpbGVOYW1lPzogc3RyaW5nO1xuICAgIGNvbmZpZ1NuaXBwZXQ/OiBzdHJpbmc7XG4gICAgc3RvcmFnZUtleT86IHN0cmluZztcbiAgfTtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkxvZ2dlclNlcnZpY2Uge1xuICBwcml2YXRlIGxvZ0VudHJpZXM6IFZhbGlkYXRpb25Mb2dFbnRyeVtdID0gW107XG4gIHByaXZhdGUgZG93bmxvYWRUaW1lb3V0SWQ6IGFueSA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgRE9XTkxPQURfREVMQVlfTVMgPSA1MDA7IC8vIFdhaXQgNTAwbXMgYWZ0ZXIgbGFzdCBlcnJvciBiZWZvcmUgZG93bmxvYWRpbmdcblxuICAvKipcbiAgICogTG9nIHZhbGlkYXRpb24gZXJyb3JzXG4gICAqIEBwYXJhbSBlcnJvcnMgQXJyYXkgb2YgdmFsaWRhdGlvbiBlcnJvcnNcbiAgICogQHBhcmFtIHNvdXJjZSBTb3VyY2Ugb2YgdmFsaWRhdGlvbiAoZS5nLiwgJ2ltcG9ydCcsICdyZW5kZXJlcicsICdzY2hlbWEtdmFsaWRhdGlvbicpXG4gICAqIEBwYXJhbSBjb250ZXh0IE9wdGlvbmFsIGNvbnRleHQgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIGF1dG9Eb3dubG9hZCBXaGV0aGVyIHRvIGF1dG9tYXRpY2FsbHkgZG93bmxvYWQgbG9nIGZpbGUgKGRlZmF1bHQ6IHRydWUpXG4gICAqL1xuICBsb2dWYWxpZGF0aW9uRXJyb3JzKFxuICAgIGVycm9yczogU2NoZW1hVmFsaWRhdGlvbkVycm9yW10sXG4gICAgc291cmNlOiBzdHJpbmcsXG4gICAgY29udGV4dD86IHtcbiAgICAgIGZpbGVOYW1lPzogc3RyaW5nO1xuICAgICAgY29uZmlnU25pcHBldD86IHN0cmluZztcbiAgICAgIHN0b3JhZ2VLZXk/OiBzdHJpbmc7XG4gICAgfSxcbiAgICBhdXRvRG93bmxvYWQ6IGJvb2xlYW4gPSB0cnVlXG4gICk6IHZvaWQge1xuICAgIGlmIChlcnJvcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47IC8vIERvbid0IGxvZyBpZiB0aGVyZSBhcmUgbm8gZXJyb3JzXG4gICAgfVxuXG4gICAgY29uc3QgZW50cnk6IFZhbGlkYXRpb25Mb2dFbnRyeSA9IHtcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICBlcnJvcnM6IGVycm9ycyxcbiAgICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgICB9O1xuXG4gICAgdGhpcy5sb2dFbnRyaWVzLnB1c2goZW50cnkpO1xuXG4gICAgLy8gU2NoZWR1bGUgYXV0b21hdGljIGRvd25sb2FkIGFmdGVyIGVycm9ycyBhY2N1bXVsYXRlIChkZWJvdW5jZWQpXG4gICAgaWYgKGF1dG9Eb3dubG9hZCkge1xuICAgICAgdGhpcy5zY2hlZHVsZURvd25sb2FkKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNjaGVkdWxlIGxvZyBmaWxlIGRvd25sb2FkIHdpdGggZGVib3VuY2VcbiAgICogVGhpcyBlbnN1cmVzIHdlIG9ubHkgZG93bmxvYWQgb25jZSBhZnRlciBhbGwgZXJyb3JzIGFyZSBhY2N1bXVsYXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZURvd25sb2FkKCk6IHZvaWQge1xuICAgIC8vIENsZWFyIGFueSBleGlzdGluZyB0aW1lb3V0XG4gICAgaWYgKHRoaXMuZG93bmxvYWRUaW1lb3V0SWQgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRvd25sb2FkVGltZW91dElkKTtcbiAgICB9XG5cbiAgICAvLyBTY2hlZHVsZSBkb3dubG9hZCBhZnRlciBkZWxheVxuICAgIC8vIElmIG1vcmUgZXJyb3JzIGNvbWUgaW4gYmVmb3JlIHRpbWVvdXQgZmlyZXMsIHRoaXMgd2lsbCBiZSBjYW5jZWxsZWQgYW5kIHJlc2NoZWR1bGVkXG4gICAgdGhpcy5kb3dubG9hZFRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5kb3dubG9hZExvZ0ZpbGVPbkVycm9yKCk7XG4gICAgICB0aGlzLmRvd25sb2FkVGltZW91dElkID0gbnVsbDtcbiAgICB9LCB0aGlzLkRPV05MT0FEX0RFTEFZX01TKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEb3dubG9hZCBsb2cgZmlsZSB3aXRoIHRpbWVzdGFtcGVkIGZpbGVuYW1lXG4gICAqIENhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdmFsaWRhdGlvbiBlcnJvcnMgb2NjdXIgKGFmdGVyIGRlYm91bmNlIGRlbGF5KVxuICAgKi9cbiAgcHJpdmF0ZSBkb3dubG9hZExvZ0ZpbGVPbkVycm9yKCk6IHZvaWQge1xuICAgIC8vIEdlbmVyYXRlIGZpbGVuYW1lIHdpdGggdGltZXN0YW1wIHRvIGF2b2lkIG92ZXJ3cml0aW5nXG4gICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1s6Ll0vZywgJy0nKS5zbGljZSgwLCAtNSk7IC8vIEZvcm1hdDogMjAyNC0wMS0xNVQxMC0zMC00NVxuICAgIGNvbnN0IGZpbGVuYW1lID0gYHNtYXJ0LXRhYmxlLXZhbGlkYXRpb24tZXJyb3JzLSR7dGltZXN0YW1wfS5sb2dgO1xuICAgIHRoaXMuZG93bmxvYWRMb2dGaWxlKGZpbGVuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIGFsbCBsb2cgZW50cmllc1xuICAgKi9cbiAgZ2V0TG9nRW50cmllcygpOiBWYWxpZGF0aW9uTG9nRW50cnlbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmxvZ0VudHJpZXNdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhbGwgbG9nIGVudHJpZXMgYXMgcGxhaW4gdGV4dFxuICAgKiBAcmV0dXJucyBGb3JtYXR0ZWQgbG9nIHRleHRcbiAgICovXG4gIGZvcm1hdExvZ0FzVGV4dCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmxvZ0VudHJpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJ05vIHZhbGlkYXRpb24gZXJyb3JzIGxvZ2dlZC5cXG4nO1xuICAgIH1cblxuICAgIGxldCBsb2dUZXh0ID0gYFNtYXJ0IFRhYmxlIFZhbGlkYXRpb24gRXJyb3IgTG9nXFxuYDtcbiAgICBsb2dUZXh0ICs9IGBHZW5lcmF0ZWQ6ICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfVxcbmA7XG4gICAgbG9nVGV4dCArPSBgVG90YWwgVmFsaWRhdGlvbiBGYWlsdXJlczogJHt0aGlzLmxvZ0VudHJpZXMubGVuZ3RofVxcbmA7XG4gICAgbG9nVGV4dCArPSBgJHsnPScucmVwZWF0KDgwKX1cXG5cXG5gO1xuXG4gICAgdGhpcy5sb2dFbnRyaWVzLmZvckVhY2goKGVudHJ5LCBpbmRleCkgPT4ge1xuICAgICAgbG9nVGV4dCArPSB0aGlzLmZvcm1hdExvZ0VudHJ5KGVudHJ5LCBpbmRleCArIDEpO1xuICAgICAgbG9nVGV4dCArPSAnXFxuJztcbiAgICB9KTtcblxuICAgIHJldHVybiBsb2dUZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhIHNpbmdsZSBsb2cgZW50cnkgYXMgcGxhaW4gdGV4dFxuICAgKiBAcGFyYW0gZW50cnkgTG9nIGVudHJ5IHRvIGZvcm1hdFxuICAgKiBAcGFyYW0gZW50cnlOdW1iZXIgRW50cnkgbnVtYmVyIChmb3IgZGlzcGxheSlcbiAgICogQHJldHVybnMgRm9ybWF0dGVkIGVudHJ5IHRleHRcbiAgICovXG4gIHByaXZhdGUgZm9ybWF0TG9nRW50cnkoZW50cnk6IFZhbGlkYXRpb25Mb2dFbnRyeSwgZW50cnlOdW1iZXI6IG51bWJlcik6IHN0cmluZyB7XG4gICAgbGV0IHRleHQgPSBgWyR7ZW50cnkudGltZXN0YW1wfV0gVmFsaWRhdGlvbiBGYWlsZWQgLSBTb3VyY2U6ICR7ZW50cnkuc291cmNlfVxcbmA7XG4gICAgXG4gICAgLy8gQWRkIGNvbnRleHQgaW5mb3JtYXRpb24gaWYgYXZhaWxhYmxlXG4gICAgaWYgKGVudHJ5LmNvbnRleHQpIHtcbiAgICAgIGlmIChlbnRyeS5jb250ZXh0LmZpbGVOYW1lKSB7XG4gICAgICAgIHRleHQgKz0gYEZpbGU6ICR7ZW50cnkuY29udGV4dC5maWxlTmFtZX1cXG5gO1xuICAgICAgfVxuICAgICAgaWYgKGVudHJ5LmNvbnRleHQuc3RvcmFnZUtleSkge1xuICAgICAgICB0ZXh0ICs9IGBTdG9yYWdlIEtleTogJHtlbnRyeS5jb250ZXh0LnN0b3JhZ2VLZXl9XFxuYDtcbiAgICAgIH1cbiAgICAgIGlmIChlbnRyeS5jb250ZXh0LmNvbmZpZ1NuaXBwZXQpIHtcbiAgICAgICAgdGV4dCArPSBgQ29uZmlnIFNuaXBwZXQ6ICR7ZW50cnkuY29udGV4dC5jb25maWdTbmlwcGV0fVxcbmA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGV4dCArPSBgJHsn4pSBJy5yZXBlYXQoODApfVxcbmA7XG5cbiAgICAvLyBGb3JtYXQgZWFjaCBlcnJvclxuICAgIGVudHJ5LmVycm9ycy5mb3JFYWNoKChlcnJvciwgZXJyb3JJbmRleCkgPT4ge1xuICAgICAgdGV4dCArPSBgRXJyb3IgJHtlcnJvckluZGV4ICsgMX06XFxuYDtcbiAgICAgIFxuICAgICAgaWYgKGVycm9yLmZpZWxkKSB7XG4gICAgICAgIHRleHQgKz0gYCAgRmllbGQ6ICR7ZXJyb3IuZmllbGR9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLnBhdGgpIHtcbiAgICAgICAgdGV4dCArPSBgICBQYXRoOiAke2Vycm9yLnBhdGh9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLmNvZGUpIHtcbiAgICAgICAgdGV4dCArPSBgICBDb2RlOiAke2Vycm9yLmNvZGV9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgdGV4dCArPSBgICBNZXNzYWdlOiAke2Vycm9yLm1lc3NhZ2V9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgZXJyb3IudmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgdmFsdWVTdHIgPSB0eXBlb2YgZXJyb3IudmFsdWUgPT09ICdvYmplY3QnIFxuICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkoZXJyb3IudmFsdWUsIG51bGwsIDIpLnNwbGl0KCdcXG4nKS5tYXAobGluZSA9PiBgICAgICR7bGluZX1gKS5qb2luKCdcXG4nKVxuICAgICAgICAgIDogU3RyaW5nKGVycm9yLnZhbHVlKTtcbiAgICAgICAgdGV4dCArPSBgICBWYWx1ZTogJHt2YWx1ZVN0cn1cXG5gO1xuICAgICAgfVxuICAgICAgXG4gICAgICB0ZXh0ICs9ICdcXG4nO1xuICAgIH0pO1xuXG4gICAgdGV4dCArPSBgJHsn4pSBJy5yZXBlYXQoODApfVxcbmA7XG5cbiAgICByZXR1cm4gdGV4dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEb3dubG9hZCBsb2cgZmlsZVxuICAgKiBAcGFyYW0gZmlsZW5hbWUgT3B0aW9uYWwgZmlsZW5hbWUgKGRlZmF1bHQ6ICdzbWFydC10YWJsZS12YWxpZGF0aW9uLWVycm9ycy5sb2cnKVxuICAgKi9cbiAgZG93bmxvYWRMb2dGaWxlKGZpbGVuYW1lOiBzdHJpbmcgPSAnc21hcnQtdGFibGUtdmFsaWRhdGlvbi1lcnJvcnMubG9nJyk6IHZvaWQge1xuICAgIGNvbnN0IGxvZ1RleHQgPSB0aGlzLmZvcm1hdExvZ0FzVGV4dCgpO1xuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbbG9nVGV4dF0sIHsgdHlwZTogJ3RleHQvcGxhaW4nIH0pO1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBsaW5rLmhyZWYgPSB1cmw7XG4gICAgbGluay5kb3dubG9hZCA9IGZpbGVuYW1lO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBsb2cgZW50cmllc1xuICAgKi9cbiAgY2xlYXJMb2coKTogdm9pZCB7XG4gICAgLy8gQ2FuY2VsIGFueSBwZW5kaW5nIGRvd25sb2FkXG4gICAgaWYgKHRoaXMuZG93bmxvYWRUaW1lb3V0SWQgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRvd25sb2FkVGltZW91dElkKTtcbiAgICAgIHRoaXMuZG93bmxvYWRUaW1lb3V0SWQgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmxvZ0VudHJpZXMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgbnVtYmVyIG9mIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm5zIE51bWJlciBvZiBsb2cgZW50cmllc1xuICAgKi9cbiAgZ2V0TG9nU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmxvZ0VudHJpZXMubGVuZ3RoO1xuICB9XG59XG5cbiJdfQ==