@slickgrid-universal/sql 0.0.1 → 10.4.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 (33) hide show
  1. package/README.md +11 -39
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +2 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/interfaces/index.d.ts +4 -0
  7. package/dist/interfaces/index.d.ts.map +1 -0
  8. package/dist/interfaces/index.js +4 -0
  9. package/dist/interfaces/index.js.map +1 -0
  10. package/dist/interfaces/sqlResult.interface.d.ts +6 -0
  11. package/dist/interfaces/sqlResult.interface.d.ts.map +1 -0
  12. package/dist/interfaces/sqlResult.interface.js +2 -0
  13. package/dist/interfaces/sqlResult.interface.js.map +1 -0
  14. package/dist/interfaces/sqlServiceApi.interface.d.ts +22 -0
  15. package/dist/interfaces/sqlServiceApi.interface.d.ts.map +1 -0
  16. package/dist/interfaces/sqlServiceApi.interface.js +2 -0
  17. package/dist/interfaces/sqlServiceApi.interface.js.map +1 -0
  18. package/dist/interfaces/sqlServiceOption.interface.d.ts +54 -0
  19. package/dist/interfaces/sqlServiceOption.interface.d.ts.map +1 -0
  20. package/dist/interfaces/sqlServiceOption.interface.js +2 -0
  21. package/dist/interfaces/sqlServiceOption.interface.js.map +1 -0
  22. package/dist/services/sql.service.d.ts +69 -0
  23. package/dist/services/sql.service.d.ts.map +1 -0
  24. package/dist/services/sql.service.js +600 -0
  25. package/dist/services/sql.service.js.map +1 -0
  26. package/package.json +44 -7
  27. package/src/index.ts +2 -0
  28. package/src/interfaces/index.ts +3 -0
  29. package/src/interfaces/sqlResult.interface.ts +6 -0
  30. package/src/interfaces/sqlServiceApi.interface.ts +27 -0
  31. package/src/interfaces/sqlServiceOption.interface.ts +61 -0
  32. package/src/services/__tests__/sql.service.spec.ts +1819 -0
  33. package/src/services/sql.service.ts +691 -0
@@ -0,0 +1,600 @@
1
+ import { getHtmlStringOutput, stripTags } from '@slickgrid-universal/utils';
2
+ const DEFAULT_TOTAL_COUNT_FIELD = 'totalCount';
3
+ const DEFAULT_ITEMS_PER_PAGE = 25;
4
+ const DEFAULT_PAGE_SIZE = 20;
5
+ /**
6
+ * SqlService implements BackendService for SQL query generation.
7
+ * This is a basic implementation; extend as needed for your SQL dialect.
8
+ */
9
+ export class SqlService {
10
+ constructor() {
11
+ this._currentFilters = [];
12
+ this._currentPagination = null;
13
+ this._currentSorters = [];
14
+ }
15
+ /** Getter for the Grid Options pulled through the Grid Object */
16
+ get _gridOptions() {
17
+ return this._grid?.getOptions() ?? {};
18
+ }
19
+ init(serviceOptions, pagination, grid) {
20
+ this.options = serviceOptions || { tableName: '' };
21
+ this._grid = grid;
22
+ if (typeof grid?.getColumns === 'function') {
23
+ this._columns = grid.getColumns() ?? [];
24
+ }
25
+ if (pagination) {
26
+ this._currentPagination = {
27
+ pageNumber: pagination.pageNumber ?? 1,
28
+ pageSize: pagination.pageSize ?? DEFAULT_PAGE_SIZE,
29
+ };
30
+ // Save the full pagination object for totalItems
31
+ this.pagination = pagination;
32
+ }
33
+ else {
34
+ this._currentPagination = {
35
+ pageNumber: 1,
36
+ pageSize: DEFAULT_PAGE_SIZE,
37
+ };
38
+ this.pagination = undefined;
39
+ }
40
+ }
41
+ buildQuery() {
42
+ if (!this.options || !this.options.tableName || !Array.isArray(this._columns)) {
43
+ throw new Error('SQL Service requires the "tableName" property and columns to properly build the SQL query');
44
+ }
45
+ // Use datasetName as schema/database prefix if provided, and escape identifiers per DB style
46
+ const table = this.options.datasetName
47
+ ? `${this.escapeIdentifier(this.options.datasetName)}.${this.escapeIdentifier(this.options.tableName)}`
48
+ : this.escapeIdentifier(this.options.tableName);
49
+ // Build the list of fields for SELECT, escaping identifiers
50
+ let selectFields = [];
51
+ for (const col of this._columns) {
52
+ // Only flat fields (no dot notation)
53
+ if (typeof col.field === 'string' && !col.field.includes('.')) {
54
+ if (!col.excludeFromQuery && !col.excludeFieldFromQuery) {
55
+ selectFields.push(this.escapeIdentifier(col.field));
56
+ }
57
+ }
58
+ // Add extra fields from the 'fields' property if present (and flat)
59
+ if (Array.isArray(col.fields)) {
60
+ for (const extraField of col.fields) {
61
+ if (typeof extraField === 'string' && !extraField.includes('.')) {
62
+ selectFields.push(this.escapeIdentifier(extraField));
63
+ }
64
+ }
65
+ }
66
+ }
67
+ // Remove duplicates
68
+ selectFields = Array.from(new Set(selectFields));
69
+ // If all flat fields are included and no extra fields, use SELECT *
70
+ const allFlatCols = this._columns.filter((col) => typeof col.field === 'string' && !col.field.includes('.'));
71
+ const allIncluded = selectFields.length === allFlatCols.length && allFlatCols.every((col) => selectFields.includes(this.escapeIdentifier(col.field)));
72
+ let selectCols = allIncluded && selectFields.length > 0 ? '*' : selectFields.join(', ');
73
+ if (!selectCols || selectCols.trim() === '') {
74
+ selectCols = '*';
75
+ }
76
+ // Pagination logic
77
+ let pageSize = this._currentPagination?.pageSize || DEFAULT_PAGE_SIZE;
78
+ let pageNumber = this._currentPagination?.pageNumber;
79
+ if (!pageNumber && pageNumber !== 0) {
80
+ pageNumber = 1;
81
+ }
82
+ // Infinite scroll: use fetchSize if provided, else pageSize
83
+ const infiniteScroll = this.options?.infiniteScroll;
84
+ let effectivePageSize = pageSize;
85
+ if (infiniteScroll && typeof infiniteScroll === 'object' && typeof infiniteScroll.fetchSize === 'number') {
86
+ effectivePageSize = infiniteScroll.fetchSize;
87
+ }
88
+ let limit = '';
89
+ let offset = '';
90
+ if (this._gridOptions.enablePagination) {
91
+ limit = effectivePageSize ? `LIMIT ${effectivePageSize}` : '';
92
+ // Offset should never be below zero
93
+ const calcOffset = Math.max(0, ((pageNumber ?? 1) - 1) * (effectivePageSize ?? DEFAULT_ITEMS_PER_PAGE));
94
+ offset = effectivePageSize ? `OFFSET ${calcOffset}` : '';
95
+ }
96
+ // Allow user to customize the total count field name
97
+ const totalCountField = this.options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
98
+ // Add the total count window function (escape count field)
99
+ const selectWithCount = `${selectCols === '*' ? '*' : selectCols}, COUNT(*) OVER() AS ${this.escapeIdentifier(totalCountField)}`;
100
+ const where = this.buildWhereClause();
101
+ const order = this.buildOrderByClause();
102
+ return `SELECT ${selectWithCount} FROM ${table}${where}${order} ${limit} ${offset}`.trim();
103
+ }
104
+ /**
105
+ * Post-process the SQL result to extract total count for pagination.
106
+ * Uses the configured totalCountField option (default: 'totalCount').
107
+ */
108
+ postProcess(processResult) {
109
+ if (this.pagination) {
110
+ const totalCountField = this.options?.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
111
+ // SQL: result is SqlResult<T>
112
+ if (processResult && Array.isArray(processResult.data) && processResult.data.length > 0) {
113
+ const firstRow = processResult.data[0];
114
+ if (firstRow && typeof firstRow[totalCountField] === 'number') {
115
+ this.pagination.totalItems = firstRow[totalCountField];
116
+ return;
117
+ }
118
+ }
119
+ // SQL: result is an array of rows
120
+ if (Array.isArray(processResult) && processResult.length > 0 && typeof processResult[0][totalCountField] === 'number') {
121
+ this.pagination.totalItems = processResult[0][totalCountField];
122
+ return;
123
+ }
124
+ // Fallback: flat totalCount
125
+ if (typeof processResult[totalCountField] === 'number') {
126
+ this.pagination.totalItems = processResult[totalCountField];
127
+ }
128
+ }
129
+ }
130
+ clearFilters() {
131
+ this._currentFilters = [];
132
+ this.updateOptions({ filteringOptions: [] });
133
+ }
134
+ clearSorters() {
135
+ this._currentSorters = [];
136
+ this.updateOptions({ sortingOptions: [] });
137
+ }
138
+ /** Get the dataset name */
139
+ getDatasetName() {
140
+ return this.options?.datasetName || '';
141
+ }
142
+ /** Get the table name */
143
+ getTableName() {
144
+ return this.options?.tableName || '';
145
+ }
146
+ /** Get the Filters that are currently used by the grid */
147
+ getCurrentFilters() {
148
+ return this._currentFilters;
149
+ }
150
+ /** Get the Pagination that is currently used by the grid */
151
+ getCurrentPagination() {
152
+ return this._currentPagination;
153
+ }
154
+ /** Get the Sorters that are currently used by the grid */
155
+ getCurrentSorters() {
156
+ return this._currentSorters;
157
+ }
158
+ /**
159
+ * Returns the initial pagination options for SQL queries.
160
+ * Returns { pageSize, offset } based on current or default pagination.
161
+ */
162
+ getInitPaginationOptions() {
163
+ let pageSize = this._currentPagination?.pageSize ?? DEFAULT_PAGE_SIZE;
164
+ let pageNumber = this._currentPagination?.pageNumber ?? 1;
165
+ const offset = Math.max(0, (pageNumber - 1) * pageSize);
166
+ return { pageSize, offset };
167
+ }
168
+ /* Reset the pagination options */
169
+ resetPaginationOptions() {
170
+ if (this._currentPagination) {
171
+ this._currentPagination.pageNumber = 1;
172
+ }
173
+ }
174
+ /**
175
+ * Update column filters by looping through all columns to inspect filters & update backend service filteringOptions
176
+ * @param columnFilters
177
+ */
178
+ updateFilters(columnFilters, isUpdatedByPresetOrDynamically) {
179
+ const filteringOptions = [];
180
+ if (isUpdatedByPresetOrDynamically) {
181
+ this._currentFilters = this.castFilterToColumnFilters(columnFilters);
182
+ }
183
+ for (const columnId in columnFilters) {
184
+ if (columnId in columnFilters) {
185
+ const columnFilter = columnFilters[columnId];
186
+ let columnDef;
187
+ if (isUpdatedByPresetOrDynamically && Array.isArray(this._columns)) {
188
+ columnDef = this._columns.find((col) => col.id === columnFilter.columnId);
189
+ }
190
+ else {
191
+ columnDef = columnFilter.columnDef;
192
+ }
193
+ if (!columnDef) {
194
+ throw new Error('[SQL Service]: Something went wrong in trying to get the column definition');
195
+ }
196
+ let fieldName = columnDef.filter?.queryField || columnDef.queryFieldFilter || columnDef.queryField || columnDef.field || columnDef.name || '';
197
+ if (fieldName instanceof HTMLElement) {
198
+ fieldName = stripTags(fieldName.innerHTML);
199
+ }
200
+ const fieldType = columnDef.type || 'string';
201
+ let searchTerms = (columnFilter?.searchTerms ? [...columnFilter.searchTerms] : null) || [];
202
+ let fieldSearchValue = Array.isArray(searchTerms) && searchTerms.length === 1 ? searchTerms[0] : '';
203
+ if (typeof fieldSearchValue === 'undefined') {
204
+ fieldSearchValue = '';
205
+ }
206
+ if (!fieldName) {
207
+ throw new Error('SQL filter could not find the field name to query the search, your column definition must include a valid "field" or "name" (optionally you can also use the "queryfield").');
208
+ }
209
+ if (this.options?.useVerbatimSearchTerms || columnFilter.verbatimSearchTerms) {
210
+ let vbOperator = columnFilter.operator || '';
211
+ let vbValue = columnFilter.searchTerms;
212
+ if (Array.isArray(columnFilter.searchTerms)) {
213
+ if (columnFilter.searchTerms.length === 1) {
214
+ vbOperator = '=';
215
+ vbValue = columnFilter.searchTerms[0];
216
+ }
217
+ else {
218
+ vbOperator = 'IN';
219
+ vbValue = columnFilter.searchTerms;
220
+ }
221
+ }
222
+ filteringOptions.push({
223
+ field: getHtmlStringOutput(fieldName),
224
+ operator: vbOperator,
225
+ value: vbValue,
226
+ type: fieldType,
227
+ });
228
+ continue;
229
+ }
230
+ fieldSearchValue = fieldSearchValue === undefined || fieldSearchValue === null ? '' : `${fieldSearchValue}`;
231
+ // run regex to find possible filter operators unless the user disabled the feature
232
+ const autoParseInputFilterOperator = columnDef.autoParseInputFilterOperator ?? this._gridOptions.autoParseInputFilterOperator;
233
+ // group (2): comboStartsWith, (3): comboEndsWith, (4): Operator, (1 or 5): searchValue, (6): last char is '*' (meaning starts with, ex.: abc*)
234
+ const matches = autoParseInputFilterOperator !== false
235
+ ? fieldSearchValue.match(/^((.*[^\\*\r\n])[*]{1}(.*[^*\r\n]))|^([<>!=*]{0,2})(.*[^<>!=*])([*]?)$/) || []
236
+ : [fieldSearchValue, '', '', '', '', fieldSearchValue, ''];
237
+ const comboStartsWith = matches?.[2] || '';
238
+ const comboEndsWith = matches?.[3] || '';
239
+ let operator = columnFilter.operator || matches?.[4];
240
+ let searchVal = matches?.[1] || matches?.[5] || '';
241
+ const lastValueChar = matches?.[6] || operator === '*z' || operator === 'EndsWith' ? '*' : '';
242
+ // no need to query if search value is empty
243
+ if (fieldName && searchVal === '' && searchTerms.length === 0) {
244
+ continue;
245
+ }
246
+ // StartsWith + EndsWith combo
247
+ if (comboStartsWith && comboEndsWith) {
248
+ searchTerms = [comboStartsWith, comboEndsWith];
249
+ operator = 'StartsWithEndsWith';
250
+ }
251
+ else if (Array.isArray(searchTerms) &&
252
+ searchTerms.length === 1 &&
253
+ typeof searchTerms[0] === 'string' &&
254
+ searchTerms[0].indexOf('..') >= 0) {
255
+ if (operator !== 'RangeInclusive' && operator !== 'RangeExclusive') {
256
+ operator = this._gridOptions.defaultFilterRangeOperator ?? 'RangeInclusive';
257
+ }
258
+ searchTerms = searchTerms[0].split('..', 2);
259
+ if (searchTerms[0] === '') {
260
+ operator = operator === 'RangeInclusive' ? '<=' : operator === 'RangeExclusive' ? '<' : operator;
261
+ searchTerms = searchTerms.slice(1);
262
+ searchVal = searchTerms[0];
263
+ }
264
+ else if (searchTerms[1] === '') {
265
+ operator = operator === 'RangeInclusive' ? '>=' : operator === 'RangeExclusive' ? '>' : operator;
266
+ searchTerms = searchTerms.slice(0, 1);
267
+ searchVal = searchTerms[0];
268
+ }
269
+ }
270
+ if (typeof searchVal === 'string') {
271
+ if (operator === '*' || operator === 'a*' || operator === '*z' || lastValueChar === '*') {
272
+ operator = (operator === '*' || operator === '*z' ? 'EndsWith' : 'StartsWith');
273
+ }
274
+ }
275
+ // if we didn't find an Operator but we have a Column Operator inside the Filter (DOM Element), we should use its default Operator
276
+ if (!operator && columnDef.filter?.operator) {
277
+ operator = columnDef.filter.operator;
278
+ }
279
+ // No operator and 2 search terms should lead to default range operator.
280
+ if (!operator && Array.isArray(searchTerms) && searchTerms.length === 2 && searchTerms[0] && searchTerms[1]) {
281
+ operator = this._gridOptions.defaultFilterRangeOperator;
282
+ }
283
+ // Range with 1 searchterm should lead to equals for a date field.
284
+ if ((operator === 'RangeInclusive' || operator === 'RangeExclusive') &&
285
+ Array.isArray(searchTerms) &&
286
+ searchTerms.length === 1 &&
287
+ fieldType === 'date') {
288
+ operator = 'EQ';
289
+ }
290
+ // if we still don't have an operator find the proper Operator to use according to field type
291
+ if (!operator) {
292
+ operator = fieldType === 'number' || fieldType === 'integer' || fieldType === 'float' ? '=' : 'LIKE';
293
+ }
294
+ // Normalize all search values
295
+ searchVal = this.normalizeSearchValue(fieldType, searchVal);
296
+ if (Array.isArray(searchTerms)) {
297
+ searchTerms.forEach((_part, index) => {
298
+ searchTerms[index] = this.normalizeSearchValue(fieldType, searchTerms[index]);
299
+ });
300
+ }
301
+ // StartsWith + EndsWith combo
302
+ if (operator === 'StartsWithEndsWith' && Array.isArray(searchTerms) && searchTerms.length === 2) {
303
+ filteringOptions.push({ field: getHtmlStringOutput(fieldName), operator: 'LIKE', value: `${searchTerms[0]}%`, type: fieldType });
304
+ filteringOptions.push({ field: getHtmlStringOutput(fieldName), operator: 'LIKE', value: `%${searchTerms[1]}`, type: fieldType });
305
+ continue;
306
+ }
307
+ // IN/NOT IN
308
+ if (searchTerms?.length > 1 && (operator === 'IN' || operator === 'NIN' || operator === 'NOT_IN')) {
309
+ filteringOptions.push({
310
+ field: getHtmlStringOutput(fieldName),
311
+ operator: operator === 'IN' ? 'IN' : 'NOT IN',
312
+ value: searchTerms,
313
+ type: fieldType,
314
+ });
315
+ continue;
316
+ }
317
+ else if (searchTerms?.length === 2 && (operator === 'RangeExclusive' || operator === 'RangeInclusive')) {
318
+ filteringOptions.push({
319
+ field: getHtmlStringOutput(fieldName),
320
+ operator: operator === 'RangeInclusive' ? '>=' : '>',
321
+ value: searchTerms[0],
322
+ type: fieldType,
323
+ });
324
+ filteringOptions.push({
325
+ field: getHtmlStringOutput(fieldName),
326
+ operator: operator === 'RangeInclusive' ? '<=' : '<',
327
+ value: searchTerms[1],
328
+ type: fieldType,
329
+ });
330
+ continue;
331
+ }
332
+ // Always map these string operators
333
+ if (fieldType === 'string' || fieldType === 'text' || fieldType === 'readonly') {
334
+ if (operator === '<>' || operator === 'Not_Contains' || operator === 'NOT_CONTAINS') {
335
+ // prettier-ignore
336
+ filteringOptions.push({ field: getHtmlStringOutput(fieldName), operator: 'NOT LIKE', value: `%${searchVal}%`, type: fieldType });
337
+ continue;
338
+ }
339
+ if (operator === 'Contains' || operator === 'CONTAINS') {
340
+ filteringOptions.push({ field: getHtmlStringOutput(fieldName), operator: 'LIKE', value: `%${searchVal}%`, type: fieldType });
341
+ continue;
342
+ }
343
+ if (operator === '*' || operator === '*z' || operator === 'EndsWith') {
344
+ filteringOptions.push({ field: getHtmlStringOutput(fieldName), operator: 'LIKE', value: `%${searchVal}`, type: fieldType });
345
+ continue;
346
+ }
347
+ if (operator === 'StartsWith' || operator === 'a*' || lastValueChar === '*') {
348
+ filteringOptions.push({ field: getHtmlStringOutput(fieldName), operator: 'LIKE', value: `${searchVal}%`, type: fieldType });
349
+ continue;
350
+ }
351
+ }
352
+ // Fallback: use field/operator/value
353
+ filteringOptions.push({ field: getHtmlStringOutput(fieldName), operator: operator ?? '=', value: searchVal, type: fieldType });
354
+ }
355
+ }
356
+ this.updateOptions({ filteringOptions });
357
+ }
358
+ updatePagination(newPage, pageSize, _cursorArgs) {
359
+ const finalPageSize = pageSize || DEFAULT_PAGE_SIZE;
360
+ this._currentPagination = { pageNumber: newPage, pageSize: finalPageSize };
361
+ this.updateOptions({ paginationOptions: { pageNumber: newPage, pageSize: finalPageSize } });
362
+ }
363
+ updateSorters(sortColumns, presetSorters) {
364
+ let currentSorters = [];
365
+ const sqlSorters = [];
366
+ if (!sortColumns && presetSorters) {
367
+ // make the presets the current sorters, also make sure that all direction are in uppercase
368
+ currentSorters = presetSorters.map((sorter) => ({
369
+ columnId: sorter.columnId,
370
+ direction: sorter.direction.toUpperCase(),
371
+ }));
372
+ // display the correct sorting icons on the UI, for that it requires (columnId, sortAsc) properties
373
+ const tmpSorterArray = currentSorters.map((sorter) => {
374
+ const columnDef = this._columns?.find((column) => column.id === sorter.columnId);
375
+ sqlSorters.push({
376
+ field: columnDef ? (columnDef.queryFieldSorter || columnDef.queryField || columnDef.field) + '' : sorter.columnId + '',
377
+ direction: sorter.direction,
378
+ });
379
+ // return only the column(s) found in the Column Definitions ELSE null
380
+ if (columnDef) {
381
+ return {
382
+ columnId: sorter.columnId,
383
+ sortAsc: sorter.direction.toUpperCase() === 'ASC',
384
+ };
385
+ }
386
+ return null;
387
+ });
388
+ // set the sort icons, but also make sure to filter out null values (that happens when columnDef is not found)
389
+ if (Array.isArray(tmpSorterArray) && this._grid) {
390
+ this._grid.setSortColumns(tmpSorterArray.filter((sorter) => sorter) || []);
391
+ }
392
+ }
393
+ else if (sortColumns && !presetSorters) {
394
+ // build the orderBy array, it could be multisort, example
395
+ // orderBy:[{field: lastName, direction: ASC}, {field: firstName, direction: DESC}]
396
+ if (Array.isArray(sortColumns) && sortColumns.length > 0) {
397
+ for (const sortColumn of sortColumns) {
398
+ if (sortColumn && sortColumn.sortCol) {
399
+ currentSorters.push({
400
+ columnId: String(sortColumn.sortCol.id),
401
+ direction: sortColumn.sortAsc ? 'ASC' : 'DESC',
402
+ });
403
+ const fieldName = (sortColumn.sortCol.queryFieldSorter || sortColumn.sortCol.queryField || sortColumn.sortCol.field || '') + '';
404
+ if (fieldName) {
405
+ sqlSorters.push({
406
+ field: fieldName,
407
+ direction: sortColumn.sortAsc ? 'ASC' : 'DESC',
408
+ });
409
+ }
410
+ }
411
+ }
412
+ }
413
+ }
414
+ // keep current Sorters and update the service options with the new sorting
415
+ this._currentSorters = currentSorters;
416
+ this.updateOptions({ sortingOptions: sqlSorters });
417
+ }
418
+ updateOptions(serviceOptions) {
419
+ this.options = {
420
+ ...this.options,
421
+ ...serviceOptions,
422
+ datasetName: this.options?.datasetName || '',
423
+ tableName: this.options?.tableName || '',
424
+ };
425
+ }
426
+ processOnFilterChanged(_event, args) {
427
+ if (!args || !args.grid) {
428
+ throw new Error('SQLService: "args" is not populated correctly');
429
+ }
430
+ // keep current filters & always save it as an array (columnFilters can be an object when it is dealt by SlickGrid Filter)
431
+ this._currentFilters = this.castFilterToColumnFilters(args.columnFilters);
432
+ // loop through all columns to inspect filters & set the query
433
+ this.updateFilters(args.columnFilters, false);
434
+ this.resetPaginationOptions();
435
+ return this.buildQuery();
436
+ }
437
+ processOnPaginationChanged(_event, args) {
438
+ // Use current pageSize if not provided in args
439
+ const pageSize = args.pageSize ?? this._currentPagination?.pageSize ?? DEFAULT_PAGE_SIZE;
440
+ this.updatePagination(args.newPage, pageSize);
441
+ return this.buildQuery();
442
+ }
443
+ processOnSortChanged(_event, args) {
444
+ if ('sortCols' in args) {
445
+ // MultiColumnSort: pass the array of SingleColumnSort
446
+ this.updateSorters(args.sortCols);
447
+ }
448
+ else {
449
+ // SingleColumnSort: wrap in array
450
+ this.updateSorters([args]);
451
+ }
452
+ return this.buildQuery();
453
+ }
454
+ // --
455
+ // PROTECTED METHODS
456
+ // --
457
+ buildWhereClause() {
458
+ // Build WHERE clause from filteringOptions
459
+ const filteringOptions = this.options?.filteringOptions || [];
460
+ if (!Array.isArray(filteringOptions) || filteringOptions.length === 0) {
461
+ return '';
462
+ }
463
+ const clauses = [];
464
+ for (const filter of filteringOptions) {
465
+ const { field, operator, value, type } = filter;
466
+ if (field && operator) {
467
+ let sqlOperator = operator === 'EQ' ? '=' : operator;
468
+ if (sqlOperator === 'NOT_CONTAINS') {
469
+ sqlOperator = 'NOT LIKE';
470
+ }
471
+ else if (sqlOperator === 'Contains') {
472
+ sqlOperator = 'LIKE';
473
+ }
474
+ const fieldExpr = this.escapeIdentifier(field);
475
+ if (sqlOperator === '=' && value === null) {
476
+ clauses.push(`${fieldExpr} IS NULL`);
477
+ }
478
+ else if (sqlOperator === 'IN' || sqlOperator === 'NOT IN') {
479
+ if (Array.isArray(value)) {
480
+ if (value.length === 0) {
481
+ continue;
482
+ }
483
+ const inList = value.map((v) => this._escapeSql(v, type)).join(',');
484
+ clauses.push(`${fieldExpr} ${sqlOperator} (${inList})`);
485
+ }
486
+ else {
487
+ clauses.push(`${fieldExpr} ${sqlOperator} (${this._escapeSql(value, type)})`);
488
+ }
489
+ }
490
+ else if (sqlOperator === 'LIKE' || sqlOperator === 'NOT LIKE') {
491
+ let likeValue = value;
492
+ if (typeof likeValue === 'string' && !likeValue.includes('%')) {
493
+ likeValue = `%${likeValue}%`;
494
+ }
495
+ clauses.push(`${fieldExpr} ${sqlOperator} ${this._escapeSql(likeValue, type)}`);
496
+ }
497
+ else {
498
+ clauses.push(`${fieldExpr} ${sqlOperator} ${this._escapeSql(value, type)}`);
499
+ }
500
+ }
501
+ }
502
+ return clauses.length ? ` WHERE ${clauses.join(' AND ')}` : '';
503
+ }
504
+ buildOrderByClause() {
505
+ if (!this.options || !this.options.tableName || !Array.isArray(this._columns)) {
506
+ throw new Error('SQL Service requires the "tableName" property to properly build the SQL query');
507
+ }
508
+ const order = this.options.sortingOptions
509
+ ?.map((s) => {
510
+ // Find the column definition by id
511
+ const colDef = this._columns?.find((col) => col.id === s.field);
512
+ let sortField = colDef
513
+ ? String(colDef.queryFieldSorter || colDef.queryField || colDef.field || colDef.id || s.field)
514
+ : String(s.field);
515
+ // Only include flat fields (no dot notation)
516
+ if (!sortField.includes('.')) {
517
+ return `${this.escapeIdentifier(sortField)} ${s.direction}`;
518
+ }
519
+ return '';
520
+ })
521
+ .join(', ');
522
+ return order ? ` ORDER BY ${order}` : '';
523
+ }
524
+ castFilterToColumnFilters(columnFilters) {
525
+ if (Array.isArray(columnFilters)) {
526
+ // Ensure all columnId are strings for CurrentFilter
527
+ return columnFilters.map((f) => ({
528
+ ...f,
529
+ columnId: String(f.columnId),
530
+ }));
531
+ }
532
+ // For object form, ensure columnId is string
533
+ return Object.keys(columnFilters).map((key) => {
534
+ const filter = columnFilters[key];
535
+ return {
536
+ ...filter,
537
+ columnId: String(filter.columnId),
538
+ };
539
+ });
540
+ }
541
+ _escapeSql(val, type) {
542
+ if (type === 'number' || type === 'integer' || type === 'float' || typeof val === 'number') {
543
+ return val.toString();
544
+ }
545
+ if (val === null || val === undefined) {
546
+ return 'NULL';
547
+ }
548
+ if (val === '') {
549
+ return "''";
550
+ }
551
+ // Escape single quotes for SQL
552
+ return `'${String(val).replace(/'/g, "''")}'`;
553
+ }
554
+ /** Escapes SQL identifiers (table, column, etc.) based on the configured escape style. */
555
+ escapeIdentifier(identifier) {
556
+ const escapeStyle = this.options?.identifierEscapeStyle || 'doubleQuote';
557
+ if (!identifier)
558
+ return '';
559
+ switch (escapeStyle) {
560
+ case 'backtick':
561
+ return `\`${String(identifier).replace(/`/g, '``')}\``;
562
+ case 'bracket':
563
+ return `[${String(identifier).replace(/]/g, ']]')}]`;
564
+ case 'doubleQuote':
565
+ default:
566
+ return `"${String(identifier).replace(/"/g, '""')}"`;
567
+ }
568
+ }
569
+ /** Normalizes the search value according to field type. */
570
+ normalizeSearchValue(fieldType, searchValue) {
571
+ switch (fieldType) {
572
+ case 'date':
573
+ case 'string':
574
+ case 'text':
575
+ case 'readonly':
576
+ if (typeof searchValue === 'string') {
577
+ // escape single quotes by doubling them
578
+ searchValue = searchValue.replace(/'/g, `''`);
579
+ }
580
+ break;
581
+ case 'integer':
582
+ case 'number':
583
+ case 'float':
584
+ if (typeof searchValue === 'string') {
585
+ // Parse a valid decimal from the string.
586
+ searchValue = searchValue.replace(/\.{2,}/g, '.'); // Replace double dots with single dot
587
+ searchValue = searchValue.replace(/\.+$/g, ''); // Remove trailing dot(s)
588
+ searchValue = searchValue.replace(/^\.+/g, '0.'); // Prefix leading dot with 0.
589
+ searchValue = searchValue.replace(/^-+\.+/g, '-0.'); // Prefix leading dash dot with -0.
590
+ searchValue = searchValue.replace(/(?!^-)[^\d.]/g, ''); // Remove non valid decimal chars
591
+ if (searchValue === '' || searchValue === '-') {
592
+ searchValue = '0';
593
+ }
594
+ }
595
+ break;
596
+ }
597
+ return searchValue;
598
+ }
599
+ }
600
+ //# sourceMappingURL=sql.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.service.js","sourceRoot":"","sources":["../../src/services/sql.service.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAI5E,MAAM,yBAAyB,GAAG,YAAY,CAAC;AAC/C,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B;;;GAGG;AACH,MAAM,OAAO,UAAU;IAAvB;QACY,oBAAe,GAAoC,EAAE,CAAC;QACtD,uBAAkB,GAA6B,IAAI,CAAC;QACpD,oBAAe,GAAoB,EAAE,CAAC;IAipBlD,CAAC;IA3oBC,iEAAiE;IACjE,IAAc,YAAY;QACxB,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAK,EAAiB,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,cAAiC,EAAE,UAAuB,EAAE,IAAgB;QAC/E,IAAI,CAAC,OAAO,GAAG,cAAc,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QACnD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,OAAO,IAAI,EAAE,UAAU,KAAK,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;QAC1C,CAAC;QACD,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,kBAAkB,GAAG;gBACxB,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,CAAC;gBACtC,QAAQ,EAAE,UAAU,CAAC,QAAQ,IAAI,iBAAiB;aACnD,CAAC;YACF,iDAAiD;YACjD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,kBAAkB,GAAG;gBACxB,UAAU,EAAE,CAAC;gBACb,QAAQ,EAAE,iBAAiB;aAC5B,CAAC;YACF,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;QAC/G,CAAC;QACD,6FAA6F;QAC7F,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW;YACpC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YACvG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAElD,4DAA4D;QAC5D,IAAI,YAAY,GAAa,EAAE,CAAC;QAChC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,qCAAqC;YACrC,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9D,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;oBACxD,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;YACD,oEAAoE;YACpE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,KAAK,MAAM,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;oBACpC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;oBACvD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QAEjD,oEAAoE;QACpE,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7G,MAAM,WAAW,GACf,YAAY,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpI,IAAI,UAAU,GAAG,WAAW,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxF,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC5C,UAAU,GAAG,GAAG,CAAC;QACnB,CAAC;QAED,mBAAmB;QACnB,IAAI,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,QAAQ,IAAI,iBAAiB,CAAC;QACtE,IAAI,UAAU,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC;QACrD,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACpC,UAAU,GAAG,CAAC,CAAC;QACjB,CAAC;QAED,4DAA4D;QAC5D,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC;QACpD,IAAI,iBAAiB,GAAG,QAAQ,CAAC;QACjC,IAAI,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,OAAO,cAAc,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzG,iBAAiB,GAAG,cAAc,CAAC,SAAS,CAAC;QAC/C,CAAC;QAED,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;YACvC,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,oCAAoC;YACpC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,iBAAiB,IAAI,sBAAsB,CAAC,CAAC,CAAC;YACxG,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,UAAU,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,CAAC;QAED,qDAAqD;QACrD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,yBAAyB,CAAC;QAClF,2DAA2D;QAC3D,MAAM,eAAe,GAAG,GAAG,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,wBAAwB,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,CAAC;QAEjI,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxC,OAAO,UAAU,eAAe,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAC7F,CAAC;IAED;;;OAGG;IACH,WAAW,CAAU,aAAsE;QACzF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,IAAI,yBAAyB,CAAC;YACnF,8BAA8B;YAC9B,IAAI,aAAa,IAAI,KAAK,CAAC,OAAO,CAAE,aAA8B,CAAC,IAAI,CAAC,IAAK,aAA8B,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5H,MAAM,QAAQ,GAAI,aAA8B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACzD,IAAI,QAAQ,IAAI,OAAQ,QAAgB,CAAC,eAAe,CAAC,KAAK,QAAQ,EAAE,CAAC;oBACvE,IAAI,CAAC,UAAU,CAAC,UAAU,GAAI,QAAgB,CAAC,eAAe,CAAC,CAAC;oBAChE,OAAO;gBACT,CAAC;YACH,CAAC;YACD,kCAAkC;YAClC,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,OAAQ,aAAa,CAAC,CAAC,CAAS,CAAC,eAAe,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC/H,IAAI,CAAC,UAAU,CAAC,UAAU,GAAI,aAAa,CAAC,CAAC,CAAS,CAAC,eAAe,CAAC,CAAC;gBACxE,OAAO;YACT,CAAC;YACD,4BAA4B;YAC5B,IAAI,OAAQ,aAAqB,CAAC,eAAe,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAChE,IAAI,CAAC,UAAU,CAAC,UAAU,GAAI,aAAqB,CAAC,eAAe,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,aAAa,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,YAAY;QACV,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,2BAA2B;IAC3B,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,yBAAyB;IACzB,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,0DAA0D;IAC1D,iBAAiB;QACf,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,4DAA4D;IAC5D,oBAAoB;QAClB,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED,0DAA0D;IAC1D,iBAAiB;QACf,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,wBAAwB;QACtB,IAAI,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,QAAQ,IAAI,iBAAiB,CAAC;QACtE,IAAI,UAAU,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,IAAI,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;QACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,kCAAkC;IAClC,sBAAsB;QACpB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC,kBAAkB,CAAC,UAAU,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,aAA8C,EAAE,8BAAuC;QACnG,MAAM,gBAAgB,GAAyB,EAAE,CAAC;QAClD,IAAI,8BAA8B,EAAE,CAAC;YACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC;QACvE,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;YACrC,IAAI,QAAQ,IAAI,aAAa,EAAE,CAAC;gBAC9B,MAAM,YAAY,GAAI,aAAqB,CAAC,QAAQ,CAAC,CAAC;gBAEtD,IAAI,SAA6B,CAAC;gBAClC,IAAI,8BAA8B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACnE,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACpF,CAAC;qBAAM,CAAC;oBACN,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC;gBACrC,CAAC;gBACD,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;gBAChG,CAAC;gBAED,IAAI,SAAS,GACX,SAAS,CAAC,MAAM,EAAE,UAAU,IAAI,SAAS,CAAC,gBAAgB,IAAI,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC;gBAChI,IAAI,SAAS,YAAY,WAAW,EAAE,CAAC;oBACrC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC7C,CAAC;gBACD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,IAAI,QAAQ,CAAC;gBAC7C,IAAI,WAAW,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC3F,IAAI,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpG,IAAI,OAAO,gBAAgB,KAAK,WAAW,EAAE,CAAC;oBAC5C,gBAAgB,GAAG,EAAE,CAAC;gBACxB,CAAC;gBAED,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CACb,6KAA6K,CAC9K,CAAC;gBACJ,CAAC;gBAED,IAAI,IAAI,CAAC,OAAO,EAAE,sBAAsB,IAAI,YAAY,CAAC,mBAAmB,EAAE,CAAC;oBAC7E,IAAI,UAAU,GAAG,YAAY,CAAC,QAAQ,IAAI,EAAE,CAAC;oBAC7C,IAAI,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC;oBAEvC,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;wBAC5C,IAAI,YAAY,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BAC1C,UAAU,GAAG,GAAG,CAAC;4BACjB,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;wBACxC,CAAC;6BAAM,CAAC;4BACN,UAAU,GAAG,IAAI,CAAC;4BAClB,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC;wBACrC,CAAC;oBACH,CAAC;oBAED,gBAAgB,CAAC,IAAI,CAAC;wBACpB,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC;wBACrC,QAAQ,EAAE,UAAU;wBACpB,KAAK,EAAE,OAAO;wBACd,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBAED,gBAAgB,GAAG,gBAAgB,KAAK,SAAS,IAAI,gBAAgB,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,gBAAgB,EAAE,CAAC;gBAE5G,mFAAmF;gBACnF,MAAM,4BAA4B,GAAG,SAAS,CAAC,4BAA4B,IAAI,IAAI,CAAC,YAAY,CAAC,4BAA4B,CAAC;gBAE9H,+IAA+I;gBAC/I,MAAM,OAAO,GACX,4BAA4B,KAAK,KAAK;oBACpC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,wEAAwE,CAAC,IAAI,EAAE;oBACxG,CAAC,CAAC,CAAC,gBAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;gBAE/D,MAAM,eAAe,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC3C,MAAM,aAAa,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzC,IAAI,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;gBACrD,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACnD,MAAM,aAAa,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAE9F,4CAA4C;gBAC5C,IAAI,SAAS,IAAI,SAAS,KAAK,EAAE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC9D,SAAS;gBACX,CAAC;gBAED,8BAA8B;gBAC9B,IAAI,eAAe,IAAI,aAAa,EAAE,CAAC;oBACrC,WAAW,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;oBAC/C,QAAQ,GAAG,oBAAoB,CAAC;gBAClC,CAAC;qBAAM,IACL,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;oBAC1B,WAAW,CAAC,MAAM,KAAK,CAAC;oBACxB,OAAO,WAAW,CAAC,CAAC,CAAC,KAAK,QAAQ;oBAClC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EACjC,CAAC;oBACD,IAAI,QAAQ,KAAK,gBAAgB,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;wBACnE,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,0BAA0B,IAAI,gBAAgB,CAAC;oBAC9E,CAAC;oBACD,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC5C,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;wBAC1B,QAAQ,GAAG,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;wBACjG,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBACnC,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;oBAC7B,CAAC;yBAAM,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;wBACjC,QAAQ,GAAG,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;wBACjG,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBACtC,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;oBAC7B,CAAC;gBACH,CAAC;gBAED,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAClC,IAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;wBACxF,QAAQ,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAiB,CAAC;oBACjG,CAAC;gBACH,CAAC;gBAED,kIAAkI;gBAClI,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC5C,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;gBACvC,CAAC;gBAED,wEAAwE;gBACxE,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC5G,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,0BAA0C,CAAC;gBAC1E,CAAC;gBAED,kEAAkE;gBAClE,IACE,CAAC,QAAQ,KAAK,gBAAgB,IAAI,QAAQ,KAAK,gBAAgB,CAAC;oBAChE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;oBAC1B,WAAW,CAAC,MAAM,KAAK,CAAC;oBACxB,SAAS,KAAK,MAAM,EACpB,CAAC;oBACD,QAAQ,GAAG,IAAI,CAAC;gBAClB,CAAC;gBAED,6FAA6F;gBAC7F,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,QAAQ,GAAG,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;gBACvG,CAAC;gBAED,8BAA8B;gBAC9B,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;gBAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC/B,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;wBACnC,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;oBAChF,CAAC,CAAC,CAAC;gBACL,CAAC;gBAED,8BAA8B;gBAC9B,IAAI,QAAQ,KAAK,oBAAoB,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAChG,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;oBACjI,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;oBACjI,SAAS;gBACX,CAAC;gBACD,YAAY;gBACZ,IAAI,WAAW,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC;oBAClG,gBAAgB,CAAC,IAAI,CAAC;wBACpB,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC;wBACrC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;wBAC7C,KAAK,EAAE,WAAW;wBAClB,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;qBAAM,IAAI,WAAW,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,gBAAgB,IAAI,QAAQ,KAAK,gBAAgB,CAAC,EAAE,CAAC;oBACzG,gBAAgB,CAAC,IAAI,CAAC;wBACpB,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC;wBACrC,QAAQ,EAAE,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;wBACpD,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;wBACrB,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;oBACH,gBAAgB,CAAC,IAAI,CAAC;wBACpB,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC;wBACrC,QAAQ,EAAE,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;wBACpD,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;wBACrB,IAAI,EAAE,SAAS;qBAChB,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBAED,oCAAoC;gBACpC,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;oBAC/E,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,cAAc,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;wBACpF,kBAAkB;wBAClB,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,SAAS,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;wBACjI,SAAS;oBACX,CAAC;oBACD,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACvD,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,SAAS,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;wBAC7H,SAAS;oBACX,CAAC;oBACD,IAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACrE,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;wBAC5H,SAAS;oBACX,CAAC;oBACD,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,IAAI,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;wBAC5E,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;wBAC5H,SAAS;oBACX,CAAC;gBACH,CAAC;gBAED,qCAAqC;gBACrC,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YACjI,CAAC;QACH,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,gBAAgB,CAAC,OAAe,EAAE,QAAgB,EAAE,WAAyC;QAC3F,MAAM,aAAa,GAAG,QAAQ,IAAI,iBAAiB,CAAC;QACpD,IAAI,CAAC,kBAAkB,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;QAC3E,IAAI,CAAC,aAAa,CAAC,EAAE,iBAAiB,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,aAAa,CAAC,WAAqC,EAAE,aAA+B;QAClF,IAAI,cAAc,GAAoB,EAAE,CAAC;QACzC,MAAM,UAAU,GAAuB,EAAE,CAAC;QAE1C,IAAI,CAAC,WAAW,IAAI,aAAa,EAAE,CAAC;YAClC,2FAA2F;YAC3F,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC9C,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW,EAAmB;aAC3D,CAAC,CAAC,CAAC;YAEJ,mGAAmG;YACnG,MAAM,cAAc,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACnD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACzF,UAAU,CAAC,IAAI,CAAC;oBACd,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,IAAI,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,EAAE;oBACtH,SAAS,EAAE,MAAM,CAAC,SAAS;iBAC5B,CAAC,CAAC;gBAEH,sEAAsE;gBACtE,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO;wBACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,KAAK;qBAClD,CAAC;gBACJ,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAA6D,CAAC;YAE/D,8GAA8G;YAC9G,IAAI,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAChD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;aAAM,IAAI,WAAW,IAAI,CAAC,aAAa,EAAE,CAAC;YACzC,0DAA0D;YAC1D,mFAAmF;YACnF,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;oBACrC,IAAI,UAAU,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;wBACrC,cAAc,CAAC,IAAI,CAAC;4BAClB,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;4BACvC,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;yBAC/C,CAAC,CAAC;wBAEH,MAAM,SAAS,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,gBAAgB,IAAI,UAAU,CAAC,OAAO,CAAC,UAAU,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC;wBAChI,IAAI,SAAS,EAAE,CAAC;4BACd,UAAU,CAAC,IAAI,CAAC;gCACd,KAAK,EAAE,SAAS;gCAChB,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;6BAC/C,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;QACtC,IAAI,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,aAAa,CAAC,cAA0C;QACtD,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,IAAI,CAAC,OAAO;YACf,GAAG,cAAc;YACjB,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE;YAC5C,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE;SACzC,CAAC;IACJ,CAAC;IAED,sBAAsB,CAAC,MAAyC,EAAE,IAAuB;QACvF,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,0HAA0H;QAC1H,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE1E,8DAA8D;QAC9D,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IAED,0BAA0B,CACxB,MAAyB,EACzB,IAAmF;QAEnF,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,QAAQ,IAAI,iBAAiB,CAAC;QACzF,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IAED,oBAAoB,CAAC,MAAyB,EAAE,IAAwC;QACtF,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,sDAAsD;YACtD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAA8B,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,kCAAkC;YAClC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAwB,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK;IACL,oBAAoB;IACpB,KAAK;IAEK,gBAAgB;QACxB,2CAA2C;QAC3C,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,gBAAgB,IAAI,EAAE,CAAC;QAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;YACtC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;YAChD,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;gBACtB,IAAI,WAAW,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACrD,IAAI,WAAW,KAAK,cAAc,EAAE,CAAC;oBACnC,WAAW,GAAG,UAAU,CAAC;gBAC3B,CAAC;qBAAM,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;oBACtC,WAAW,GAAG,MAAM,CAAC;gBACvB,CAAC;gBACD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAC/C,IAAI,WAAW,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC;gBACvC,CAAC;qBAAM,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;oBAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;wBACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BACvB,SAAS;wBACX,CAAC;wBACD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBACpE,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,WAAW,KAAK,MAAM,GAAG,CAAC,CAAC;oBAC1D,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,WAAW,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;oBAChF,CAAC;gBACH,CAAC;qBAAM,IAAI,WAAW,KAAK,MAAM,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;oBAChE,IAAI,SAAS,GAAG,KAAK,CAAC;oBACtB,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC9D,SAAS,GAAG,IAAI,SAAS,GAAG,CAAC;oBAC/B,CAAC;oBACD,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAClF,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC9E,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,CAAC;IAES,kBAAkB;QAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;QACnG,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc;YACvC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACV,mCAAmC;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;YAChE,IAAI,SAAS,GAAG,MAAM;gBACpB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC;gBAC9F,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAEpB,6CAA6C;YAC7C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAC9D,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,KAAK,CAAC,CAAC,CAAC,aAAa,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC;IAES,yBAAyB,CAAC,aAA8C;QAChF,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,oDAAoD;YACpD,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,GAAG,CAAC;gBACJ,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;aAC7B,CAAC,CAAC,CAAC;QACN,CAAC;QAED,6CAA6C;QAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO;gBACL,GAAG,MAAM;gBACT,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;aAClC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAES,UAAU,CAAC,GAAQ,EAAE,IAAa;QAC1C,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3F,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QAED,+BAA+B;QAC/B,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IAChD,CAAC;IAED,0FAA0F;IAChF,gBAAgB,CAAC,UAAmB;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,qBAAqB,IAAI,aAAa,CAAC;QACzE,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAC3B,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,UAAU;gBACb,OAAO,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;YACzD,KAAK,SAAS;gBACZ,OAAO,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;YACvD,KAAK,aAAa,CAAC;YACnB;gBACE,OAAO,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;QACzD,CAAC;IACH,CAAC;IAED,2DAA2D;IACjD,oBAAoB,CAAC,SAAiB,EAAE,WAAgB;QAChE,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC;YACZ,KAAK,QAAQ,CAAC;YACd,KAAK,MAAM,CAAC;YACZ,KAAK,UAAU;gBACb,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;oBACpC,wCAAwC;oBACxC,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,CAAC;gBACD,MAAM;YACR,KAAK,SAAS,CAAC;YACf,KAAK,QAAQ,CAAC;YACd,KAAK,OAAO;gBACV,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;oBACpC,yCAAyC;oBACzC,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,sCAAsC;oBACzF,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,yBAAyB;oBACzE,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,6BAA6B;oBAC/E,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,mCAAmC;oBACxF,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,iCAAiC;oBACzF,IAAI,WAAW,KAAK,EAAE,IAAI,WAAW,KAAK,GAAG,EAAE,CAAC;wBAC9C,WAAW,GAAG,GAAG,CAAC;oBACpB,CAAC;gBACH,CAAC;gBACD,MAAM;QACV,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;CACF"}