hledger-lsp 0.1.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +632 -0
  3. package/out/extension.d.ts +1 -0
  4. package/out/extension.d.ts.map +1 -0
  5. package/out/extension.js +2 -0
  6. package/out/extension.js.map +1 -0
  7. package/out/features/codeActions.d.ts +73 -0
  8. package/out/features/codeActions.d.ts.map +1 -0
  9. package/out/features/codeActions.js +417 -0
  10. package/out/features/codeActions.js.map +1 -0
  11. package/out/features/completion.d.ts +94 -0
  12. package/out/features/completion.d.ts.map +1 -0
  13. package/out/features/completion.js +323 -0
  14. package/out/features/completion.js.map +1 -0
  15. package/out/features/definition.d.ts +12 -0
  16. package/out/features/definition.d.ts.map +1 -0
  17. package/out/features/definition.js +61 -0
  18. package/out/features/definition.js.map +1 -0
  19. package/out/features/documentLinks.d.ts +17 -0
  20. package/out/features/documentLinks.d.ts.map +1 -0
  21. package/out/features/documentLinks.js +68 -0
  22. package/out/features/documentLinks.js.map +1 -0
  23. package/out/features/findReferences.d.ts +33 -0
  24. package/out/features/findReferences.d.ts.map +1 -0
  25. package/out/features/findReferences.js +79 -0
  26. package/out/features/findReferences.js.map +1 -0
  27. package/out/features/foldingRanges.d.ts +27 -0
  28. package/out/features/foldingRanges.d.ts.map +1 -0
  29. package/out/features/foldingRanges.js +111 -0
  30. package/out/features/foldingRanges.js.map +1 -0
  31. package/out/features/formatter.d.ts +70 -0
  32. package/out/features/formatter.d.ts.map +1 -0
  33. package/out/features/formatter.js +373 -0
  34. package/out/features/formatter.js.map +1 -0
  35. package/out/features/hover.d.ts +66 -0
  36. package/out/features/hover.d.ts.map +1 -0
  37. package/out/features/hover.js +387 -0
  38. package/out/features/hover.js.map +1 -0
  39. package/out/features/inlayHints.d.ts +43 -0
  40. package/out/features/inlayHints.d.ts.map +1 -0
  41. package/out/features/inlayHints.js +221 -0
  42. package/out/features/inlayHints.js.map +1 -0
  43. package/out/features/selectionRange.d.ts +47 -0
  44. package/out/features/selectionRange.d.ts.map +1 -0
  45. package/out/features/selectionRange.js +273 -0
  46. package/out/features/selectionRange.js.map +1 -0
  47. package/out/features/semanticTokens.d.ts +83 -0
  48. package/out/features/semanticTokens.d.ts.map +1 -0
  49. package/out/features/semanticTokens.js +370 -0
  50. package/out/features/semanticTokens.js.map +1 -0
  51. package/out/features/symbols.d.ts +47 -0
  52. package/out/features/symbols.d.ts.map +1 -0
  53. package/out/features/symbols.js +249 -0
  54. package/out/features/symbols.js.map +1 -0
  55. package/out/features/transactionAnalyzer.d.ts +63 -0
  56. package/out/features/transactionAnalyzer.d.ts.map +1 -0
  57. package/out/features/transactionAnalyzer.js +127 -0
  58. package/out/features/transactionAnalyzer.js.map +1 -0
  59. package/out/features/validator.d.ts +142 -0
  60. package/out/features/validator.d.ts.map +1 -0
  61. package/out/features/validator.js +633 -0
  62. package/out/features/validator.js.map +1 -0
  63. package/out/parser/ast.d.ts +37 -0
  64. package/out/parser/ast.d.ts.map +1 -0
  65. package/out/parser/ast.js +606 -0
  66. package/out/parser/ast.js.map +1 -0
  67. package/out/parser/includes.d.ts +25 -0
  68. package/out/parser/includes.d.ts.map +1 -0
  69. package/out/parser/includes.js +106 -0
  70. package/out/parser/includes.js.map +1 -0
  71. package/out/parser/index.d.ts +54 -0
  72. package/out/parser/index.d.ts.map +1 -0
  73. package/out/parser/index.js +146 -0
  74. package/out/parser/index.js.map +1 -0
  75. package/out/server/deps.d.ts +19 -0
  76. package/out/server/deps.d.ts.map +1 -0
  77. package/out/server/deps.js +77 -0
  78. package/out/server/deps.js.map +1 -0
  79. package/out/server/settings.d.ts +60 -0
  80. package/out/server/settings.d.ts.map +1 -0
  81. package/out/server/settings.js +110 -0
  82. package/out/server/settings.js.map +1 -0
  83. package/out/server.d.ts +3 -0
  84. package/out/server.d.ts.map +1 -0
  85. package/out/server.js +420 -0
  86. package/out/server.js.map +1 -0
  87. package/out/types.d.ts +84 -0
  88. package/out/types.d.ts.map +1 -0
  89. package/out/types.js +6 -0
  90. package/out/types.js.map +1 -0
  91. package/out/utils/index.d.ts +38 -0
  92. package/out/utils/index.d.ts.map +1 -0
  93. package/out/utils/index.js +89 -0
  94. package/out/utils/index.js.map +1 -0
  95. package/out/utils/uri.d.ts +32 -0
  96. package/out/utils/uri.d.ts.map +1 -0
  97. package/out/utils/uri.js +215 -0
  98. package/out/utils/uri.js.map +1 -0
  99. package/package.json +58 -0
@@ -0,0 +1,633 @@
1
+ "use strict";
2
+ /**
3
+ * Validator for hledger journal files
4
+ *
5
+ * Provides validation for:
6
+ * - Transaction balance
7
+ * - Undeclared items (accounts, payees, commodities, tags)
8
+ * - Missing amounts
9
+ * - Include directives
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.validator = exports.Validator = void 0;
13
+ const node_1 = require("vscode-languageserver/node");
14
+ const uri_1 = require("../utils/uri");
15
+ const settings_1 = require("../server/settings");
16
+ class Validator {
17
+ /**
18
+ * Validate a parsed hledger document
19
+ */
20
+ validate(document, parsedDoc, options) {
21
+ const diagnostics = [];
22
+ const settings = options?.settings;
23
+ // Helper to check if validation is enabled
24
+ // Uses provided settings, or falls back to default settings
25
+ const isEnabled = (key) => {
26
+ // If settings are provided, use them
27
+ if (settings?.validation?.[key] !== undefined) {
28
+ return settings.validation[key] === true;
29
+ }
30
+ // Otherwise use defaults
31
+ return settings_1.defaultSettings.validation?.[key] ?? true;
32
+ };
33
+ // Validate each transaction
34
+ for (const transaction of parsedDoc.transactions) {
35
+ // Check balance
36
+ if (isEnabled('balance')) {
37
+ const balanceIssues = this.validateBalance(transaction, document);
38
+ diagnostics.push(...balanceIssues);
39
+ }
40
+ // Check missing amounts
41
+ if (isEnabled('missingAmounts')) {
42
+ const amountIssues = this.validateMissingAmounts(transaction, document);
43
+ diagnostics.push(...amountIssues);
44
+ }
45
+ // Check empty transactions
46
+ if (isEnabled('emptyTransactions')) {
47
+ const emptyTxnIssues = this.validateEmptyTransaction(transaction, document);
48
+ diagnostics.push(...emptyTxnIssues);
49
+ }
50
+ // Check invalid date formats
51
+ if (isEnabled('invalidDates')) {
52
+ const invalidDateIssues = this.validateDateFormat(transaction, document);
53
+ diagnostics.push(...invalidDateIssues);
54
+ }
55
+ // Check future dates
56
+ if (isEnabled('futureDates')) {
57
+ const futureDateIssues = this.validateFutureDate(transaction, document);
58
+ diagnostics.push(...futureDateIssues);
59
+ }
60
+ // Check empty descriptions
61
+ if (isEnabled('emptyDescriptions')) {
62
+ const emptyDescIssues = this.validateEmptyDescription(transaction, document);
63
+ diagnostics.push(...emptyDescIssues);
64
+ }
65
+ }
66
+ // Check for undeclared items (each type can be enabled/disabled separately)
67
+ const undeclaredIssues = this.validateUndeclaredItems(document, parsedDoc, settings, isEnabled('undeclaredAccounts'), isEnabled('undeclaredPayees'), isEnabled('undeclaredCommodities'), isEnabled('undeclaredTags'));
68
+ diagnostics.push(...undeclaredIssues);
69
+ // Check date ordering
70
+ if (isEnabled('dateOrdering')) {
71
+ const dateOrderIssues = this.validateDateOrdering(parsedDoc.transactions, document);
72
+ diagnostics.push(...dateOrderIssues);
73
+ }
74
+ // Check balance assertions
75
+ if (isEnabled('balanceAssertions')) {
76
+ const assertionIssues = this.validateBalanceAssertions(parsedDoc.transactions, document, parsedDoc);
77
+ diagnostics.push(...assertionIssues);
78
+ }
79
+ // Check include directives
80
+ if (options?.fileReader && (isEnabled('includeFiles') || isEnabled('circularIncludes'))) {
81
+ const includeIssues = this.validateIncludeDirectives(document, parsedDoc, options, isEnabled('includeFiles'), isEnabled('circularIncludes'));
82
+ diagnostics.push(...includeIssues);
83
+ }
84
+ return { diagnostics };
85
+ }
86
+ /**
87
+ * Validate transaction balance
88
+ * Transactions must balance (all amounts sum to zero per commodity)
89
+ */
90
+ validateBalance(transaction, document) {
91
+ const diagnostics = [];
92
+ // Group postings by commodity
93
+ const balances = new Map();
94
+ // Count how many postings have amounts
95
+ let postingsWithAmounts = 0;
96
+ for (const posting of transaction.postings) {
97
+ if (posting.amount) {
98
+ postingsWithAmounts++;
99
+ // If posting has a cost, use the cost commodity for balance calculation
100
+ if (posting.cost) {
101
+ const costCommodity = posting.cost.amount.commodity || '';
102
+ let costValue;
103
+ if (posting.cost.type === 'unit') {
104
+ // @ unitPrice: total cost = quantity * unitPrice
105
+ costValue = posting.amount.quantity * posting.cost.amount.quantity;
106
+ }
107
+ else {
108
+ // @@ totalPrice: use total price directly
109
+ costValue = posting.cost.amount.quantity;
110
+ }
111
+ const current = balances.get(costCommodity) || 0;
112
+ balances.set(costCommodity, current + costValue);
113
+ }
114
+ else {
115
+ // No cost notation, use the posting's commodity
116
+ const commodity = posting.amount.commodity || '';
117
+ const current = balances.get(commodity) || 0;
118
+ balances.set(commodity, current + posting.amount.quantity);
119
+ }
120
+ }
121
+ }
122
+ // If all postings have amounts, check if they balance
123
+ if (postingsWithAmounts === transaction.postings.length) {
124
+ for (const [commodity, balance] of balances.entries()) {
125
+ // Allow for small floating point errors
126
+ if (Math.abs(balance) > 0.005) {
127
+ const commodityStr = commodity ? ` ${commodity}` : '';
128
+ diagnostics.push({
129
+ severity: node_1.DiagnosticSeverity.Error,
130
+ range: this.getTransactionRange(transaction, document),
131
+ message: `Transaction does not balance: ${balance.toFixed(2)}${commodityStr} off`,
132
+ source: 'hledger'
133
+ });
134
+ }
135
+ }
136
+ }
137
+ return diagnostics;
138
+ }
139
+ /**
140
+ * Validate missing amounts in transaction
141
+ * At most one posting can omit an amount
142
+ */
143
+ validateMissingAmounts(transaction, document) {
144
+ const diagnostics = [];
145
+ const postingsWithoutAmounts = transaction.postings.filter(p => !p.amount);
146
+ if (postingsWithoutAmounts.length > 1) {
147
+ diagnostics.push({
148
+ severity: node_1.DiagnosticSeverity.Error,
149
+ range: this.getTransactionRange(transaction, document),
150
+ message: `Transaction has ${postingsWithoutAmounts.length} postings without amounts (maximum 1 allowed)`,
151
+ source: 'hledger'
152
+ });
153
+ }
154
+ return diagnostics;
155
+ }
156
+ /**
157
+ * Validate undeclared items
158
+ * Warn when accounts, payees, commodities, or tags are used but not declared
159
+ */
160
+ validateUndeclaredItems(document, parsedDoc, settings, checkAccounts = true, checkPayees = true, checkCommodities = true, checkTags = true) {
161
+ const diagnostics = [];
162
+ // Helper to convert severity string to DiagnosticSeverity
163
+ const getSeverity = (severityStr) => {
164
+ switch (severityStr) {
165
+ case 'error': return node_1.DiagnosticSeverity.Error;
166
+ case 'warning': return node_1.DiagnosticSeverity.Warning;
167
+ case 'information': return node_1.DiagnosticSeverity.Information;
168
+ case 'hint': return node_1.DiagnosticSeverity.Hint;
169
+ default: return node_1.DiagnosticSeverity.Warning; // default
170
+ }
171
+ };
172
+ // Check undeclared accounts (if enabled)
173
+ if (checkAccounts) {
174
+ const undeclaredAccounts = parsedDoc.accounts.filter(a => !a.declared);
175
+ for (const account of undeclaredAccounts) {
176
+ const range = this.findFirstOccurrence(document, account.name);
177
+ if (range) {
178
+ diagnostics.push({
179
+ severity: getSeverity(settings?.severity?.undeclaredAccounts),
180
+ range,
181
+ message: `Account "${account.name}" is used but not declared with 'account' directive`,
182
+ source: 'hledger',
183
+ code: 'undeclared-account',
184
+ data: { accountName: account.name }
185
+ });
186
+ }
187
+ }
188
+ }
189
+ // Check undeclared payees (if enabled)
190
+ if (checkPayees) {
191
+ const undeclaredPayees = parsedDoc.payees.filter(p => !p.declared);
192
+ for (const payee of undeclaredPayees) {
193
+ const range = this.findFirstOccurrence(document, payee.name);
194
+ if (range) {
195
+ diagnostics.push({
196
+ severity: getSeverity(settings?.severity?.undeclaredPayees),
197
+ range,
198
+ message: `Payee "${payee.name}" is used but not declared with 'payee' directive`,
199
+ source: 'hledger',
200
+ code: 'undeclared-payee',
201
+ data: { payeeName: payee.name }
202
+ });
203
+ }
204
+ }
205
+ }
206
+ // Check undeclared commodities (if enabled)
207
+ if (checkCommodities) {
208
+ const undeclaredCommodities = parsedDoc.commodities.filter(c => !c.declared);
209
+ for (const commodity of undeclaredCommodities) {
210
+ const range = this.findFirstOccurrence(document, commodity.name);
211
+ if (range) {
212
+ diagnostics.push({
213
+ severity: getSeverity(settings?.severity?.undeclaredCommodities),
214
+ range,
215
+ message: `Commodity "${commodity.name}" is used but not declared with 'commodity' directive`,
216
+ source: 'hledger',
217
+ code: 'undeclared-commodity',
218
+ data: { commodityName: commodity.name }
219
+ });
220
+ }
221
+ }
222
+ }
223
+ // Check undeclared tags (if enabled)
224
+ if (checkTags) {
225
+ const undeclaredTags = parsedDoc.tags.filter(t => !t.declared);
226
+ for (const tag of undeclaredTags) {
227
+ const range = this.findFirstOccurrence(document, tag.name + ':');
228
+ if (range) {
229
+ diagnostics.push({
230
+ severity: getSeverity(settings?.severity?.undeclaredTags || 'information'),
231
+ range,
232
+ message: `Tag "${tag.name}" is used but not declared with 'tag' directive`,
233
+ source: 'hledger',
234
+ code: 'undeclared-tag',
235
+ data: { tagName: tag.name }
236
+ });
237
+ }
238
+ }
239
+ }
240
+ return diagnostics;
241
+ }
242
+ /**
243
+ * Get the range for a transaction (first line only for now)
244
+ */
245
+ getTransactionRange(transaction, document) {
246
+ const text = document.getText();
247
+ const lines = text.split('\n');
248
+ // Find the transaction in the document
249
+ for (let i = 0; i < lines.length; i++) {
250
+ const line = lines[i];
251
+ if (line.includes(transaction.date) && line.includes(transaction.description)) {
252
+ return {
253
+ start: { line: i, character: 0 },
254
+ end: { line: i, character: line.length }
255
+ };
256
+ }
257
+ }
258
+ // Fallback to first line if not found
259
+ return {
260
+ start: { line: 0, character: 0 },
261
+ end: { line: 0, character: 0 }
262
+ };
263
+ }
264
+ /**
265
+ * Find the first occurrence of a string in the document
266
+ */
267
+ findFirstOccurrence(document, searchStr) {
268
+ const text = document.getText();
269
+ const lines = text.split('\n');
270
+ for (let i = 0; i < lines.length; i++) {
271
+ const line = lines[i];
272
+ const index = line.indexOf(searchStr);
273
+ if (index !== -1) {
274
+ return {
275
+ start: { line: i, character: index },
276
+ end: { line: i, character: index + searchStr.length }
277
+ };
278
+ }
279
+ }
280
+ return null;
281
+ }
282
+ /**
283
+ * Validate date ordering
284
+ * Warn if transactions are not in chronological order
285
+ */
286
+ validateDateOrdering(transactions, document) {
287
+ const diagnostics = [];
288
+ for (let i = 1; i < transactions.length; i++) {
289
+ const prevDate = this.parseDate(transactions[i - 1].date);
290
+ const currDate = this.parseDate(transactions[i].date);
291
+ if (prevDate && currDate && currDate < prevDate) {
292
+ const range = this.getTransactionRange(transactions[i], document);
293
+ diagnostics.push({
294
+ severity: node_1.DiagnosticSeverity.Warning,
295
+ range,
296
+ message: `Transaction date ${transactions[i].date} is before previous transaction date ${transactions[i - 1].date}`,
297
+ source: 'hledger'
298
+ });
299
+ }
300
+ }
301
+ return diagnostics;
302
+ }
303
+ /**
304
+ * Format an amount with commodity according to declared format
305
+ */
306
+ formatAmountWithCommodity(quantity, commodityName, parsedDoc) {
307
+ // Find commodity format
308
+ const commodity = parsedDoc.commodities.find(c => c.name === commodityName);
309
+ if (!commodity?.format) {
310
+ // No format declared, use default: amount then commodity with space
311
+ return commodityName ? `${quantity.toFixed(2)} ${commodityName}` : quantity.toFixed(2);
312
+ }
313
+ const format = commodity.format;
314
+ const symbol = format.symbol || commodityName;
315
+ const symbolOnLeft = format.symbolOnLeft ?? false;
316
+ const spaceBetween = format.spaceBetween ?? true;
317
+ const space = spaceBetween ? ' ' : '';
318
+ // Use precision from format, or default to 2
319
+ const precision = format.precision ?? 2;
320
+ const formattedNumber = quantity.toFixed(precision);
321
+ if (symbolOnLeft) {
322
+ return `${symbol}${space}${formattedNumber}`;
323
+ }
324
+ else {
325
+ return `${formattedNumber}${space}${symbol}`;
326
+ }
327
+ }
328
+ /**
329
+ * Validate balance assertions
330
+ * Check if balance assertions match calculated balances
331
+ */
332
+ validateBalanceAssertions(transactions, document, parsedDoc) {
333
+ const diagnostics = [];
334
+ // Track running balances per account per commodity
335
+ const balances = new Map();
336
+ for (const transaction of transactions) {
337
+ for (const posting of transaction.postings) {
338
+ // Update running balance
339
+ // Note: Balance assertions check the ORIGINAL commodity (amount.commodity),
340
+ // not the cost commodity. So we always update balance in the amount's commodity.
341
+ if (posting.amount) {
342
+ const accountBalances = balances.get(posting.account) || new Map();
343
+ const commodity = posting.amount.commodity || '';
344
+ const currentBalance = accountBalances.get(commodity) || 0;
345
+ // Always use the original amount quantity for balance tracking,
346
+ // regardless of whether there's a cost notation
347
+ accountBalances.set(commodity, currentBalance + posting.amount.quantity);
348
+ balances.set(posting.account, accountBalances);
349
+ }
350
+ // Check assertion
351
+ if (posting.assertion) {
352
+ const accountBalances = balances.get(posting.account);
353
+ const commodity = posting.assertion.commodity || '';
354
+ const expectedBalance = posting.assertion.quantity;
355
+ const actualBalance = accountBalances?.get(commodity) || 0;
356
+ // Allow for small floating point errors
357
+ if (Math.abs(actualBalance - expectedBalance) > 0.005) {
358
+ const range = this.findPostingRange(transaction, posting, document);
359
+ const expectedFormatted = this.formatAmountWithCommodity(expectedBalance, commodity, parsedDoc);
360
+ const actualFormatted = this.formatAmountWithCommodity(actualBalance, commodity, parsedDoc);
361
+ diagnostics.push({
362
+ severity: node_1.DiagnosticSeverity.Error,
363
+ range,
364
+ message: `Balance assertion failed for ${posting.account}: expected ${expectedFormatted}, but calculated ${actualFormatted}`,
365
+ source: 'hledger'
366
+ });
367
+ }
368
+ }
369
+ }
370
+ }
371
+ return diagnostics;
372
+ }
373
+ /**
374
+ * Parse a date string to a Date object
375
+ */
376
+ parseDate(dateStr) {
377
+ // Handle both YYYY-MM-DD and YYYY/MM/DD formats
378
+ const normalized = dateStr.replace(/\//g, '-');
379
+ const date = new Date(normalized);
380
+ return isNaN(date.getTime()) ? null : date;
381
+ }
382
+ /**
383
+ * Find the range for a specific posting within a transaction
384
+ */
385
+ findPostingRange(transaction, posting, document) {
386
+ const text = document.getText();
387
+ const lines = text.split('\n');
388
+ // Find the transaction, then find the posting
389
+ let inTransaction = false;
390
+ for (let i = 0; i < lines.length; i++) {
391
+ const line = lines[i];
392
+ // Check if this is our transaction
393
+ if (line.includes(transaction.date) && line.includes(transaction.description)) {
394
+ inTransaction = true;
395
+ continue;
396
+ }
397
+ // If we're in the transaction, look for the posting
398
+ if (inTransaction && line.trim().startsWith(posting.account)) {
399
+ return {
400
+ start: { line: i, character: 0 },
401
+ end: { line: i, character: line.length }
402
+ };
403
+ }
404
+ // Stop if we hit another transaction or empty line after being in a transaction
405
+ if (inTransaction && (!line.trim() || line.match(/^\d{4}[-/]\d{2}[-/]\d{2}/))) {
406
+ break;
407
+ }
408
+ }
409
+ // Fallback to transaction range
410
+ return this.getTransactionRange(transaction, document);
411
+ }
412
+ /**
413
+ * Validate empty transactions
414
+ * Transactions must have at least 2 postings
415
+ */
416
+ validateEmptyTransaction(transaction, document) {
417
+ const diagnostics = [];
418
+ if (transaction.postings.length < 2) {
419
+ const range = this.getTransactionRange(transaction, document);
420
+ diagnostics.push({
421
+ severity: node_1.DiagnosticSeverity.Error,
422
+ range,
423
+ message: `Transaction has only ${transaction.postings.length} posting(s), minimum 2 required`,
424
+ source: 'hledger'
425
+ });
426
+ }
427
+ return diagnostics;
428
+ }
429
+ /**
430
+ * Validate date format
431
+ * Check for invalid dates like 2024-13-01 or 2024-02-30
432
+ */
433
+ validateDateFormat(transaction, document) {
434
+ const diagnostics = [];
435
+ const normalized = transaction.date.replace(/\//g, '-');
436
+ const parts = normalized.split('-');
437
+ if (parts.length !== 3) {
438
+ const range = this.getTransactionRange(transaction, document);
439
+ diagnostics.push({
440
+ severity: node_1.DiagnosticSeverity.Error,
441
+ range,
442
+ message: `Invalid date format: ${transaction.date}`,
443
+ source: 'hledger'
444
+ });
445
+ return diagnostics;
446
+ }
447
+ const year = parseInt(parts[0], 10);
448
+ const month = parseInt(parts[1], 10);
449
+ const day = parseInt(parts[2], 10);
450
+ // Check if values are in valid ranges
451
+ if (month < 1 || month > 12) {
452
+ const range = this.getTransactionRange(transaction, document);
453
+ diagnostics.push({
454
+ severity: node_1.DiagnosticSeverity.Error,
455
+ range,
456
+ message: `Invalid month in date: ${transaction.date} (month must be 1-12)`,
457
+ source: 'hledger'
458
+ });
459
+ return diagnostics;
460
+ }
461
+ if (day < 1 || day > 31) {
462
+ const range = this.getTransactionRange(transaction, document);
463
+ diagnostics.push({
464
+ severity: node_1.DiagnosticSeverity.Error,
465
+ range,
466
+ message: `Invalid day in date: ${transaction.date} (day must be 1-31)`,
467
+ source: 'hledger'
468
+ });
469
+ return diagnostics;
470
+ }
471
+ // Now try to parse the date
472
+ const parsedDate = this.parseDate(transaction.date);
473
+ if (!parsedDate) {
474
+ const range = this.getTransactionRange(transaction, document);
475
+ diagnostics.push({
476
+ severity: node_1.DiagnosticSeverity.Error,
477
+ range,
478
+ message: `Invalid date format: ${transaction.date}`,
479
+ source: 'hledger'
480
+ });
481
+ return diagnostics;
482
+ }
483
+ // Check if the date components match the parsed date
484
+ // This catches cases like Feb 30 which get corrected to Mar 2
485
+ if (parsedDate.getFullYear() !== year ||
486
+ parsedDate.getMonth() + 1 !== month ||
487
+ parsedDate.getDate() !== day) {
488
+ const range = this.getTransactionRange(transaction, document);
489
+ diagnostics.push({
490
+ severity: node_1.DiagnosticSeverity.Error,
491
+ range,
492
+ message: `Invalid date: ${transaction.date} (date does not exist in calendar)`,
493
+ source: 'hledger'
494
+ });
495
+ }
496
+ return diagnostics;
497
+ }
498
+ /**
499
+ * Validate future dates
500
+ * Warn about transactions dated in the future
501
+ */
502
+ validateFutureDate(transaction, document) {
503
+ const diagnostics = [];
504
+ const parsedDate = this.parseDate(transaction.date);
505
+ if (!parsedDate) {
506
+ return diagnostics; // Already handled by validateDateFormat
507
+ }
508
+ const today = new Date();
509
+ today.setHours(0, 0, 0, 0); // Reset time portion for date-only comparison
510
+ if (parsedDate > today) {
511
+ const range = this.getTransactionRange(transaction, document);
512
+ diagnostics.push({
513
+ severity: node_1.DiagnosticSeverity.Warning,
514
+ range,
515
+ message: `Transaction date ${transaction.date} is in the future`,
516
+ source: 'hledger'
517
+ });
518
+ }
519
+ return diagnostics;
520
+ }
521
+ /**
522
+ * Validate empty descriptions
523
+ * Warn about transactions with no description/payee
524
+ */
525
+ validateEmptyDescription(transaction, document) {
526
+ const diagnostics = [];
527
+ if (!transaction.description || transaction.description.trim() === '') {
528
+ const range = this.getTransactionRange(transaction, document);
529
+ diagnostics.push({
530
+ severity: node_1.DiagnosticSeverity.Warning,
531
+ range,
532
+ message: 'Transaction has no description',
533
+ source: 'hledger'
534
+ });
535
+ }
536
+ return diagnostics;
537
+ }
538
+ /**
539
+ * Validate include directives
540
+ * Check for missing files and circular includes
541
+ */
542
+ validateIncludeDirectives(document, parsedDoc, options, checkMissingFiles = true, checkCircularIncludes = true) {
543
+ const diagnostics = [];
544
+ const visited = new Set();
545
+ const baseUri = options.baseUri || document.uri;
546
+ const fileReader = options.fileReader;
547
+ // Find all include directives in the document
548
+ const includeDirectives = parsedDoc.directives.filter(d => d.type === 'include');
549
+ for (const directive of includeDirectives) {
550
+ const includePath = directive.value;
551
+ // Resolve the include path
552
+ const resolvedPath = (0, uri_1.resolveIncludePath)(includePath, baseUri);
553
+ // Check for duplicate includes in the same document
554
+ if (visited.has(resolvedPath)) {
555
+ const range = this.findFirstOccurrence(document, includePath);
556
+ if (range) {
557
+ diagnostics.push({
558
+ severity: node_1.DiagnosticSeverity.Warning,
559
+ range,
560
+ message: `Duplicate include: ${includePath}`,
561
+ source: 'hledger'
562
+ });
563
+ }
564
+ continue;
565
+ }
566
+ visited.add(resolvedPath);
567
+ // Check if file exists (if enabled)
568
+ const includeDoc = fileReader(resolvedPath);
569
+ if (!includeDoc && checkMissingFiles) {
570
+ // File doesn't exist
571
+ const range = this.findFirstOccurrence(document, includePath);
572
+ if (range) {
573
+ diagnostics.push({
574
+ severity: node_1.DiagnosticSeverity.Error,
575
+ range,
576
+ message: `Include file not found: ${includePath}`,
577
+ source: 'hledger'
578
+ });
579
+ }
580
+ }
581
+ // Check for circular includes (if enabled and file exists)
582
+ if (includeDoc && checkCircularIncludes) {
583
+ const circularCheck = this.checkCircularInclude(document.uri, includeDoc, fileReader, new Set([baseUri, resolvedPath]));
584
+ if (circularCheck) {
585
+ const range = this.findFirstOccurrence(document, includePath);
586
+ if (range) {
587
+ diagnostics.push({
588
+ severity: node_1.DiagnosticSeverity.Error,
589
+ range,
590
+ message: `Circular include detected: ${includePath}`,
591
+ source: 'hledger'
592
+ });
593
+ }
594
+ }
595
+ }
596
+ }
597
+ return diagnostics;
598
+ }
599
+ /**
600
+ * Check if a circular include exists by recursively following includes
601
+ */
602
+ checkCircularInclude(targetUri, document, fileReader, visited) {
603
+ const text = document.getText();
604
+ const lines = text.split('\n');
605
+ for (const line of lines) {
606
+ const trimmedLine = line.trim();
607
+ if (trimmedLine.startsWith('include ')) {
608
+ const includePath = trimmedLine.substring(8).trim();
609
+ const resolvedPath = (0, uri_1.resolveIncludePath)(includePath, document.uri);
610
+ // Check if this include points back to the target
611
+ if (resolvedPath === targetUri) {
612
+ return true;
613
+ }
614
+ // Avoid infinite recursion
615
+ if (visited.has(resolvedPath)) {
616
+ continue;
617
+ }
618
+ visited.add(resolvedPath);
619
+ // Recursively check this file
620
+ const includeDoc = fileReader(resolvedPath);
621
+ if (includeDoc) {
622
+ if (this.checkCircularInclude(targetUri, includeDoc, fileReader, visited)) {
623
+ return true;
624
+ }
625
+ }
626
+ }
627
+ }
628
+ return false;
629
+ }
630
+ }
631
+ exports.Validator = Validator;
632
+ exports.validator = new Validator();
633
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/features/validator.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,qDAA4E;AAI5E,sCAAkD;AAClD,iDAAqD;AAsDrD,MAAa,SAAS;IACpB;;OAEG;IACH,QAAQ,CAAC,QAAsB,EAAE,SAAyB,EAAE,OAA2B;QACrF,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAC;QAEnC,2CAA2C;QAC3C,4DAA4D;QAC5D,MAAM,SAAS,GAAG,CAAC,GAAwD,EAAW,EAAE;YACtF,qCAAqC;YACrC,IAAI,QAAQ,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC9C,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;YAC3C,CAAC;YACD,yBAAyB;YACzB,OAAO,0BAAe,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACnD,CAAC,CAAC;QAEF,4BAA4B;QAC5B,KAAK,MAAM,WAAW,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;YACjD,gBAAgB;YAChB,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzB,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAClE,WAAW,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;YACrC,CAAC;YAED,wBAAwB;YACxB,IAAI,SAAS,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAChC,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBACxE,WAAW,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;YACpC,CAAC;YAED,2BAA2B;YAC3B,IAAI,SAAS,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACnC,MAAM,cAAc,GAAG,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAC5E,WAAW,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;YACtC,CAAC;YAED,6BAA6B;YAC7B,IAAI,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC9B,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBACzE,WAAW,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,CAAC;YACzC,CAAC;YAED,qBAAqB;YACrB,IAAI,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBACxE,WAAW,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;YACxC,CAAC;YAED,2BAA2B;YAC3B,IAAI,SAAS,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACnC,MAAM,eAAe,GAAG,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAC7E,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,MAAM,gBAAgB,GAAG,IAAI,CAAC,uBAAuB,CACnD,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,SAAS,CAAC,oBAAoB,CAAC,EAC/B,SAAS,CAAC,kBAAkB,CAAC,EAC7B,SAAS,CAAC,uBAAuB,CAAC,EAClC,SAAS,CAAC,gBAAgB,CAAC,CAC5B,CAAC;QACF,WAAW,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;QAEtC,sBAAsB;QACtB,IAAI,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9B,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YACpF,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;QACvC,CAAC;QAED,2BAA2B;QAC3B,IAAI,SAAS,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACnC,MAAM,eAAe,GAAG,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACpG,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;QACvC,CAAC;QAED,2BAA2B;QAC3B,IAAI,OAAO,EAAE,UAAU,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC;YACxF,MAAM,aAAa,GAAG,IAAI,CAAC,yBAAyB,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC7I,WAAW,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACK,eAAe,CAAC,WAAwB,EAAE,QAAsB;QACtE,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,8BAA8B;QAC9B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE3C,uCAAuC;QACvC,IAAI,mBAAmB,GAAG,CAAC,CAAC;QAE5B,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC3C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,mBAAmB,EAAE,CAAC;gBAEtB,wEAAwE;gBACxE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;oBACjB,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;oBAC1D,IAAI,SAAiB,CAAC;oBAEtB,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wBACjC,iDAAiD;wBACjD,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;oBACrE,CAAC;yBAAM,CAAC;wBACN,0CAA0C;wBAC1C,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;oBAC3C,CAAC;oBAED,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;oBACjD,QAAQ,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;gBACnD,CAAC;qBAAM,CAAC;oBACN,gDAAgD;oBAChD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;oBACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC7C,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,IAAI,mBAAmB,KAAK,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACxD,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;gBACtD,wCAAwC;gBACxC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC;oBAC9B,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtD,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;wBAClC,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC;wBACtD,OAAO,EAAE,iCAAiC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,MAAM;wBACjF,MAAM,EAAE,SAAS;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,sBAAsB,CAAC,WAAwB,EAAE,QAAsB;QAC7E,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,MAAM,sBAAsB,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAE3E,IAAI,sBAAsB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;gBAClC,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC;gBACtD,OAAO,EAAE,mBAAmB,sBAAsB,CAAC,MAAM,+CAA+C;gBACxG,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,uBAAuB,CAC7B,QAAsB,EACtB,SAAyB,EACzB,QAAwC,EACxC,gBAAyB,IAAI,EAC7B,cAAuB,IAAI,EAC3B,mBAA4B,IAAI,EAChC,YAAqB,IAAI;QAEzB,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,0DAA0D;QAC1D,MAAM,WAAW,GAAG,CAAC,WAAoB,EAAsB,EAAE;YAC/D,QAAQ,WAAW,EAAE,CAAC;gBACpB,KAAK,OAAO,CAAC,CAAC,OAAO,yBAAkB,CAAC,KAAK,CAAC;gBAC9C,KAAK,SAAS,CAAC,CAAC,OAAO,yBAAkB,CAAC,OAAO,CAAC;gBAClD,KAAK,aAAa,CAAC,CAAC,OAAO,yBAAkB,CAAC,WAAW,CAAC;gBAC1D,KAAK,MAAM,CAAC,CAAC,OAAO,yBAAkB,CAAC,IAAI,CAAC;gBAC5C,OAAO,CAAC,CAAC,OAAO,yBAAkB,CAAC,OAAO,CAAC,CAAC,UAAU;YACxD,CAAC;QACH,CAAC,CAAC;QAEF,yCAAyC;QACzC,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,kBAAkB,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACvE,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC/D,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,CAAC;wBAC7D,KAAK;wBACL,OAAO,EAAE,YAAY,OAAO,CAAC,IAAI,qDAAqD;wBACtF,MAAM,EAAE,SAAS;wBACjB,IAAI,EAAE,oBAAoB;wBAC1B,IAAI,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE;qBACpC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACnE,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7D,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,CAAC;wBAC3D,KAAK;wBACL,OAAO,EAAE,UAAU,KAAK,CAAC,IAAI,mDAAmD;wBAChF,MAAM,EAAE,SAAS;wBACjB,IAAI,EAAE,kBAAkB;wBACxB,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE;qBAChC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,qBAAqB,GAAG,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC7E,KAAK,MAAM,SAAS,IAAI,qBAAqB,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBACjE,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,qBAAqB,CAAC;wBAChE,KAAK;wBACL,OAAO,EAAE,cAAc,SAAS,CAAC,IAAI,uDAAuD;wBAC5F,MAAM,EAAE,SAAS;wBACjB,IAAI,EAAE,sBAAsB;wBAC5B,IAAI,EAAE,EAAE,aAAa,EAAE,SAAS,CAAC,IAAI,EAAE;qBACxC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,qCAAqC;QACrC,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC/D,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;gBACjE,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,IAAI,aAAa,CAAC;wBAC1E,KAAK;wBACL,OAAO,EAAE,QAAQ,GAAG,CAAC,IAAI,iDAAiD;wBAC1E,MAAM,EAAE,SAAS;wBACjB,IAAI,EAAE,gBAAgB;wBACtB,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE;qBAC5B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,WAAwB,EAAE,QAAsB;QAC1E,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,uCAAuC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9E,OAAO;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;oBAChC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;iBACzC,CAAC;YACJ,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,OAAO;YACL,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;YAChC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;SAC/B,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,QAAsB,EAAE,SAAiB;QACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjB,OAAO;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE;oBACpC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE;iBACtD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACK,oBAAoB,CAAC,YAA2B,EAAE,QAAsB;QAC9E,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAEtD,IAAI,QAAQ,IAAI,QAAQ,IAAI,QAAQ,GAAG,QAAQ,EAAE,CAAC;gBAChD,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;gBAClE,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,yBAAkB,CAAC,OAAO;oBACpC,KAAK;oBACL,OAAO,EAAE,oBAAoB,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,wCAAwC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;oBACnH,MAAM,EAAE,SAAS;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,yBAAyB,CAC/B,QAAgB,EAChB,aAAqB,EACrB,SAAyB;QAEzB,wBAAwB;QACxB,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;QAE5E,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;YACvB,oEAAoE;YACpE,OAAO,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzF,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC;QAC9C,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,KAAK,CAAC;QAClD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC;QACjD,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAEtC,6CAA6C;QAC7C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;QACxC,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEpD,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,eAAe,EAAE,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,eAAe,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,yBAAyB,CAC/B,YAA2B,EAC3B,QAAsB,EACtB,SAAyB;QAEzB,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,mDAAmD;QACnD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA+B,CAAC;QAExD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC3C,yBAAyB;gBACzB,4EAA4E;gBAC5E,iFAAiF;gBACjF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBACnB,MAAM,eAAe,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;oBACnF,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;oBACjD,MAAM,cAAc,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC3D,gEAAgE;oBAChE,gDAAgD;oBAChD,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACzE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBACjD,CAAC;gBAED,kBAAkB;gBAClB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;oBACtB,MAAM,eAAe,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACtD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC;oBACpD,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC;oBACnD,MAAM,aAAa,GAAG,eAAe,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAE3D,wCAAwC;oBACxC,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,eAAe,CAAC,GAAG,KAAK,EAAE,CAAC;wBACtD,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;wBACpE,MAAM,iBAAiB,GAAG,IAAI,CAAC,yBAAyB,CAAC,eAAe,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;wBAChG,MAAM,eAAe,GAAG,IAAI,CAAC,yBAAyB,CAAC,aAAa,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;wBAE5F,WAAW,CAAC,IAAI,CAAC;4BACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;4BAClC,KAAK;4BACL,OAAO,EAAE,gCAAgC,OAAO,CAAC,OAAO,cAAc,iBAAiB,oBAAoB,eAAe,EAAE;4BAC5H,MAAM,EAAE,SAAS;yBAClB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,OAAe;QAC/B,gDAAgD;QAChD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7C,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,WAAwB,EAAE,OAAgB,EAAE,QAAsB;QACzF,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,8CAA8C;QAC9C,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEtB,mCAAmC;YACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9E,aAAa,GAAG,IAAI,CAAC;gBACrB,SAAS;YACX,CAAC;YAED,oDAAoD;YACpD,IAAI,aAAa,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7D,OAAO;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;oBAChC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;iBACzC,CAAC;YACJ,CAAC;YAED,gFAAgF;YAChF,IAAI,aAAa,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC;gBAC9E,MAAM;YACR,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,OAAO,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED;;;OAGG;IACK,wBAAwB,CAAC,WAAwB,EAAE,QAAsB;QAC/E,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;gBAClC,KAAK;gBACL,OAAO,EAAE,wBAAwB,WAAW,CAAC,QAAQ,CAAC,MAAM,iCAAiC;gBAC7F,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,kBAAkB,CAAC,WAAwB,EAAE,QAAsB;QACzE,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;gBAClC,KAAK;gBACL,OAAO,EAAE,wBAAwB,WAAW,CAAC,IAAI,EAAE;gBACnD,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEnC,sCAAsC;QACtC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;gBAClC,KAAK;gBACL,OAAO,EAAE,0BAA0B,WAAW,CAAC,IAAI,uBAAuB;gBAC1E,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;gBAClC,KAAK;gBACL,OAAO,EAAE,wBAAwB,WAAW,CAAC,IAAI,qBAAqB;gBACtE,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,4BAA4B;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;gBAClC,KAAK;gBACL,OAAO,EAAE,wBAAwB,WAAW,CAAC,IAAI,EAAE;gBACnD,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,qDAAqD;QACrD,8DAA8D;QAC9D,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,IAAI;YACjC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,KAAK;YACnC,UAAU,CAAC,OAAO,EAAE,KAAK,GAAG,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;gBAClC,KAAK;gBACL,OAAO,EAAE,iBAAiB,WAAW,CAAC,IAAI,oCAAoC;gBAC9E,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,kBAAkB,CAAC,WAAwB,EAAE,QAAsB;QACzE,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,WAAW,CAAC,CAAC,wCAAwC;QAC9D,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,8CAA8C;QAE1E,IAAI,UAAU,GAAG,KAAK,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,OAAO;gBACpC,KAAK;gBACL,OAAO,EAAE,oBAAoB,WAAW,CAAC,IAAI,mBAAmB;gBAChE,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,wBAAwB,CAAC,WAAwB,EAAE,QAAsB;QAC/E,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,CAAC,WAAW,CAAC,WAAW,IAAI,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACtE,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,yBAAkB,CAAC,OAAO;gBACpC,KAAK;gBACL,OAAO,EAAE,gCAAgC;gBACzC,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,yBAAyB,CAC/B,QAAsB,EACtB,SAAyB,EACzB,OAA0B,EAC1B,oBAA6B,IAAI,EACjC,wBAAiC,IAAI;QAErC,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC;QAChD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAW,CAAC;QAEvC,8CAA8C;QAC9C,MAAM,iBAAiB,GAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAEjF,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE,CAAC;YAC1C,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC;YAEpC,2BAA2B;YAC3B,MAAM,YAAY,GAAG,IAAA,wBAAkB,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAE9D,oDAAoD;YACpD,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBAC9D,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,yBAAkB,CAAC,OAAO;wBACpC,KAAK;wBACL,OAAO,EAAE,sBAAsB,WAAW,EAAE;wBAC5C,MAAM,EAAE,SAAS;qBAClB,CAAC,CAAC;gBACL,CAAC;gBACD,SAAS;YACX,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAE1B,oCAAoC;YACpC,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;YAE5C,IAAI,CAAC,UAAU,IAAI,iBAAiB,EAAE,CAAC;gBACrC,qBAAqB;gBACrB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBAC9D,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,CAAC,IAAI,CAAC;wBACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;wBAClC,KAAK;wBACL,OAAO,EAAE,2BAA2B,WAAW,EAAE;wBACjD,MAAM,EAAE,SAAS;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,2DAA2D;YAC3D,IAAI,UAAU,IAAI,qBAAqB,EAAE,CAAC;gBACxC,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;gBACxH,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;oBAC9D,IAAI,KAAK,EAAE,CAAC;wBACV,WAAW,CAAC,IAAI,CAAC;4BACf,QAAQ,EAAE,yBAAkB,CAAC,KAAK;4BAClC,KAAK;4BACL,OAAO,EAAE,8BAA8B,WAAW,EAAE;4BACpD,MAAM,EAAE,SAAS;yBAClB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,SAAiB,EAAE,QAAsB,EAAE,UAAsB,EAAE,OAAoB;QAClH,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,WAAW,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACvC,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpD,MAAM,YAAY,GAAG,IAAA,wBAAkB,EAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAEnE,kDAAkD;gBAClD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;oBAC/B,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,2BAA2B;gBAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC9B,SAAS;gBACX,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBAE1B,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;gBAC5C,IAAI,UAAU,EAAE,CAAC;oBACf,IAAI,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;wBAC1E,OAAO,IAAI,CAAC;oBACd,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CAEF;AAruBD,8BAquBC;AAEY,QAAA,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC"}