logicstamp-context 0.2.4 → 0.2.5

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 (101) hide show
  1. package/LLM_CONTEXT.md +2 -2
  2. package/README.md +23 -19
  3. package/dist/cli/commands/compare.d.ts.map +1 -1
  4. package/dist/cli/commands/compare.js +120 -13
  5. package/dist/cli/commands/compare.js.map +1 -1
  6. package/dist/cli/commands/context/fileWriter.d.ts.map +1 -1
  7. package/dist/cli/commands/context/fileWriter.js +68 -6
  8. package/dist/cli/commands/context/fileWriter.js.map +1 -1
  9. package/dist/cli/commands/context/tokenEstimator.d.ts.map +1 -1
  10. package/dist/cli/commands/context/tokenEstimator.js +12 -4
  11. package/dist/cli/commands/context/tokenEstimator.js.map +1 -1
  12. package/dist/cli/commands/context.d.ts.map +1 -1
  13. package/dist/cli/commands/context.js +71 -2
  14. package/dist/cli/commands/context.js.map +1 -1
  15. package/dist/cli/commands/validate.d.ts.map +1 -1
  16. package/dist/cli/commands/validate.js +84 -8
  17. package/dist/cli/commands/validate.js.map +1 -1
  18. package/dist/cli/handlers/compareHandler.d.ts.map +1 -1
  19. package/dist/cli/handlers/compareHandler.js +123 -9
  20. package/dist/cli/handlers/compareHandler.js.map +1 -1
  21. package/dist/core/astParser/detectors.d.ts.map +1 -1
  22. package/dist/core/astParser/detectors.js +130 -57
  23. package/dist/core/astParser/detectors.js.map +1 -1
  24. package/dist/core/astParser/extractors/componentExtractor.d.ts.map +1 -1
  25. package/dist/core/astParser/extractors/componentExtractor.js +89 -20
  26. package/dist/core/astParser/extractors/componentExtractor.js.map +1 -1
  27. package/dist/core/astParser/extractors/eventExtractor.d.ts.map +1 -1
  28. package/dist/core/astParser/extractors/eventExtractor.js +83 -28
  29. package/dist/core/astParser/extractors/eventExtractor.js.map +1 -1
  30. package/dist/core/astParser/extractors/propExtractor.d.ts.map +1 -1
  31. package/dist/core/astParser/extractors/propExtractor.js +130 -51
  32. package/dist/core/astParser/extractors/propExtractor.js.map +1 -1
  33. package/dist/core/astParser/extractors/stateExtractor.d.ts.map +1 -1
  34. package/dist/core/astParser/extractors/stateExtractor.js +95 -44
  35. package/dist/core/astParser/extractors/stateExtractor.js.map +1 -1
  36. package/dist/core/astParser.d.ts +1 -0
  37. package/dist/core/astParser.d.ts.map +1 -1
  38. package/dist/core/astParser.js +74 -26
  39. package/dist/core/astParser.js.map +1 -1
  40. package/dist/core/manifest.d.ts.map +1 -1
  41. package/dist/core/manifest.js +28 -1
  42. package/dist/core/manifest.js.map +1 -1
  43. package/dist/core/pack/loader.d.ts.map +1 -1
  44. package/dist/core/pack/loader.js +22 -2
  45. package/dist/core/pack/loader.js.map +1 -1
  46. package/dist/core/styleExtractor/index.d.ts +1 -0
  47. package/dist/core/styleExtractor/index.d.ts.map +1 -1
  48. package/dist/core/styleExtractor/index.js +1 -0
  49. package/dist/core/styleExtractor/index.js.map +1 -1
  50. package/dist/core/styleExtractor/layout.d.ts +13 -2
  51. package/dist/core/styleExtractor/layout.d.ts.map +1 -1
  52. package/dist/core/styleExtractor/layout.js +135 -65
  53. package/dist/core/styleExtractor/layout.js.map +1 -1
  54. package/dist/core/styleExtractor/material.d.ts.map +1 -1
  55. package/dist/core/styleExtractor/material.js +291 -66
  56. package/dist/core/styleExtractor/material.js.map +1 -1
  57. package/dist/core/styleExtractor/motion.d.ts +2 -2
  58. package/dist/core/styleExtractor/motion.d.ts.map +1 -1
  59. package/dist/core/styleExtractor/motion.js +425 -56
  60. package/dist/core/styleExtractor/motion.js.map +1 -1
  61. package/dist/core/styleExtractor/radix.d.ts +29 -0
  62. package/dist/core/styleExtractor/radix.d.ts.map +1 -0
  63. package/dist/core/styleExtractor/radix.js +315 -0
  64. package/dist/core/styleExtractor/radix.js.map +1 -0
  65. package/dist/core/styleExtractor/scss.d.ts.map +1 -1
  66. package/dist/core/styleExtractor/scss.js +37 -23
  67. package/dist/core/styleExtractor/scss.js.map +1 -1
  68. package/dist/core/styleExtractor/shadcn.d.ts +20 -0
  69. package/dist/core/styleExtractor/shadcn.d.ts.map +1 -0
  70. package/dist/core/styleExtractor/shadcn.js +345 -0
  71. package/dist/core/styleExtractor/shadcn.js.map +1 -0
  72. package/dist/core/styleExtractor/styleExtractor.d.ts.map +1 -1
  73. package/dist/core/styleExtractor/styleExtractor.js +267 -89
  74. package/dist/core/styleExtractor/styleExtractor.js.map +1 -1
  75. package/dist/core/styleExtractor/styled.d.ts +1 -1
  76. package/dist/core/styleExtractor/styled.d.ts.map +1 -1
  77. package/dist/core/styleExtractor/styled.js +308 -23
  78. package/dist/core/styleExtractor/styled.js.map +1 -1
  79. package/dist/core/styleExtractor/tailwind.d.ts +21 -3
  80. package/dist/core/styleExtractor/tailwind.d.ts.map +1 -1
  81. package/dist/core/styleExtractor/tailwind.js +279 -46
  82. package/dist/core/styleExtractor/tailwind.js.map +1 -1
  83. package/dist/types/UIFContract.d.ts +34 -0
  84. package/dist/types/UIFContract.d.ts.map +1 -1
  85. package/dist/types/UIFContract.js.map +1 -1
  86. package/dist/utils/config.d.ts.map +1 -1
  87. package/dist/utils/config.js +41 -2
  88. package/dist/utils/config.js.map +1 -1
  89. package/dist/utils/debug.d.ts +12 -0
  90. package/dist/utils/debug.d.ts.map +1 -0
  91. package/dist/utils/debug.js +16 -0
  92. package/dist/utils/debug.js.map +1 -0
  93. package/dist/utils/fsx.d.ts +2 -1
  94. package/dist/utils/fsx.d.ts.map +1 -1
  95. package/dist/utils/fsx.js +99 -28
  96. package/dist/utils/fsx.js.map +1 -1
  97. package/dist/utils/gitignore.d.ts.map +1 -1
  98. package/dist/utils/gitignore.js +28 -1
  99. package/dist/utils/gitignore.js.map +1 -1
  100. package/package.json +1 -1
  101. package/schema/logicstamp.context.schema.json +1 -1
@@ -1,31 +1,316 @@
1
1
  /**
2
2
  * Styled-components/Emotion extractor - Extracts CSS-in-JS library usage
3
3
  */
4
+ import { SyntaxKind } from 'ts-morph';
5
+ import { debugError } from '../../utils/debug.js';
4
6
  /**
5
- * Extract styled-components/emotion styled declarations
7
+ * Check if styled is imported from styled-components or emotion libraries
8
+ */
9
+ function hasStyledImport(source) {
10
+ try {
11
+ for (const imp of source.getImportDeclarations()) {
12
+ try {
13
+ const module = imp.getModuleSpecifierValue();
14
+ if (module === 'styled-components' ||
15
+ module === '@emotion/styled' ||
16
+ module === '@emotion/react') {
17
+ const named = imp.getNamedImports();
18
+ const defaultImport = imp.getDefaultImport();
19
+ if (defaultImport && defaultImport.getText() === 'styled') {
20
+ return true;
21
+ }
22
+ for (const n of named) {
23
+ if (n.getName() === 'styled') {
24
+ return true;
25
+ }
26
+ }
27
+ }
28
+ }
29
+ catch {
30
+ // Continue checking other imports
31
+ }
32
+ }
33
+ return false;
34
+ }
35
+ catch {
36
+ // Return false on unexpected errors - outer try/catch will handle logging
37
+ return false;
38
+ }
39
+ }
40
+ /**
41
+ * Extract styled-components/emotion styled declarations using AST
6
42
  */
7
43
  export function extractStyledComponents(source) {
8
- const sourceText = source.getFullText();
9
- const components = new Set();
10
- // Match styled.div`...` or styled(Component)`...` patterns
11
- const styledPatterns = [
12
- /styled\.(\w+)`/g,
13
- /styled\((\w+)\)`/g,
14
- ];
15
- for (const pattern of styledPatterns) {
16
- for (const match of sourceText.matchAll(pattern)) {
17
- if (match[1])
18
- components.add(match[1]);
19
- }
20
- }
21
- // Check for theme usage
22
- const hasTheme = /\$\{.*theme\./.test(sourceText) || /useTheme\(\)/.test(sourceText);
23
- // Check for css prop usage
24
- const hasCssProps = /css\s*=\s*\{/.test(sourceText) || /css`/.test(sourceText);
25
- return {
26
- components: Array.from(components).sort().slice(0, 10),
27
- hasTheme,
28
- hasCssProps,
29
- };
44
+ try {
45
+ const components = new Set();
46
+ let hasTheme = false;
47
+ let hasCssProps = false;
48
+ // Check if styled is imported from valid sources (styled-components/emotion)
49
+ let hasValidStyledImport = false;
50
+ try {
51
+ hasValidStyledImport = hasStyledImport(source);
52
+ }
53
+ catch {
54
+ // If import check fails, continue without styled import validation
55
+ }
56
+ // Find all tagged template expressions (e.g., styled.div`...` or styled(Component)`...`)
57
+ let taggedTemplates = [];
58
+ try {
59
+ taggedTemplates = source.getDescendantsOfKind(SyntaxKind.TaggedTemplateExpression);
60
+ }
61
+ catch (error) {
62
+ debugError('styled', 'extractStyledComponents', {
63
+ error: error instanceof Error ? error.message : String(error),
64
+ context: 'getTaggedTemplateExpressions',
65
+ });
66
+ // Keep taggedTemplates = [] and continue to theme/useTheme/css checks
67
+ }
68
+ for (const taggedTemplate of taggedTemplates) {
69
+ try {
70
+ const tag = taggedTemplate.getTag();
71
+ const template = taggedTemplate.getTemplate();
72
+ // Check if this is a styled component pattern (only if styled is from valid sources)
73
+ if (hasValidStyledImport) {
74
+ const componentName = extractStyledComponentName(tag);
75
+ if (componentName) {
76
+ components.add(componentName);
77
+ }
78
+ }
79
+ // Check for theme usage in template literals
80
+ if (!hasTheme) {
81
+ try {
82
+ if (containsThemeUsage(template)) {
83
+ hasTheme = true;
84
+ }
85
+ }
86
+ catch {
87
+ // Continue if theme check fails for this template
88
+ }
89
+ }
90
+ }
91
+ catch {
92
+ // Continue processing other tagged templates
93
+ }
94
+ }
95
+ // Check for useTheme() hook calls
96
+ if (!hasTheme) {
97
+ let callExpressions = [];
98
+ try {
99
+ callExpressions = source.getDescendantsOfKind(SyntaxKind.CallExpression);
100
+ }
101
+ catch (error) {
102
+ debugError('styled', 'extractStyledComponents', {
103
+ error: error instanceof Error ? error.message : String(error),
104
+ context: 'getCallExpressions',
105
+ });
106
+ // Continue with empty array
107
+ }
108
+ try {
109
+ for (const callExpr of callExpressions) {
110
+ try {
111
+ const expr = callExpr.getExpression();
112
+ if (expr.getKind() === SyntaxKind.Identifier && expr.getText() === 'useTheme') {
113
+ hasTheme = true;
114
+ break;
115
+ }
116
+ }
117
+ catch {
118
+ // Continue checking other call expressions
119
+ }
120
+ }
121
+ }
122
+ catch {
123
+ // Continue if call expression processing fails
124
+ }
125
+ }
126
+ // Check for css prop usage in JSX
127
+ if (!hasCssProps) {
128
+ let jsxElements = [];
129
+ try {
130
+ jsxElements = [
131
+ ...source.getDescendantsOfKind(SyntaxKind.JsxElement),
132
+ ...source.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement),
133
+ ];
134
+ }
135
+ catch (error) {
136
+ debugError('styled', 'extractStyledComponents', {
137
+ error: error instanceof Error ? error.message : String(error),
138
+ context: 'getJsxElements',
139
+ });
140
+ // Continue with empty array
141
+ }
142
+ try {
143
+ for (const element of jsxElements) {
144
+ try {
145
+ const openingElement = 'getOpeningElement' in element
146
+ ? element.getOpeningElement()
147
+ : element;
148
+ const attributes = openingElement.getAttributes();
149
+ for (const attr of attributes) {
150
+ if (attr.getKind() !== SyntaxKind.JsxAttribute)
151
+ continue;
152
+ const jsxAttr = attr;
153
+ const attrName = jsxAttr.getNameNode().getText();
154
+ if (attrName === 'css') {
155
+ hasCssProps = true;
156
+ break;
157
+ }
158
+ }
159
+ if (hasCssProps)
160
+ break;
161
+ }
162
+ catch {
163
+ // Continue checking other JSX elements
164
+ }
165
+ }
166
+ }
167
+ catch {
168
+ // Continue if JSX processing fails
169
+ }
170
+ }
171
+ return {
172
+ components: Array.from(components).sort().slice(0, 10),
173
+ hasTheme,
174
+ hasCssProps,
175
+ };
176
+ }
177
+ catch (error) {
178
+ debugError('styled', 'extractStyledComponents', {
179
+ error: error instanceof Error ? error.message : String(error),
180
+ });
181
+ return {
182
+ components: [],
183
+ hasTheme: false,
184
+ hasCssProps: false,
185
+ };
186
+ }
187
+ }
188
+ /**
189
+ * Extract component name from styled component tag
190
+ * Handles styled.div`...`, styled(Component)`...`, and styled('div')`...` patterns
191
+ */
192
+ function extractStyledComponentName(tag) {
193
+ try {
194
+ // Pattern 1: styled.div`...` (PropertyAccessExpression)
195
+ if (tag.getKind() === SyntaxKind.PropertyAccessExpression) {
196
+ const propAccess = tag.asKindOrThrow(SyntaxKind.PropertyAccessExpression);
197
+ const expression = propAccess.getExpression();
198
+ const name = propAccess.getNameNode().getText();
199
+ // Check if expression is 'styled'
200
+ if (expression.getKind() === SyntaxKind.Identifier && expression.getText() === 'styled') {
201
+ return name;
202
+ }
203
+ }
204
+ // Pattern 2: styled(Component)`...` or styled('div')`...` (CallExpression)
205
+ if (tag.getKind() === SyntaxKind.CallExpression) {
206
+ const callExpr = tag.asKindOrThrow(SyntaxKind.CallExpression);
207
+ const expression = callExpr.getExpression();
208
+ // Check if it's styled(...)
209
+ if (expression.getKind() === SyntaxKind.Identifier && expression.getText() === 'styled') {
210
+ const args = callExpr.getArguments();
211
+ if (args.length > 0) {
212
+ const firstArg = args[0];
213
+ // Extract identifier name from argument
214
+ if (firstArg.getKind() === SyntaxKind.Identifier) {
215
+ return firstArg.getText();
216
+ }
217
+ // Handle PropertyAccessExpression like styled(Some.Component)
218
+ if (firstArg.getKind() === SyntaxKind.PropertyAccessExpression) {
219
+ const propAccess = firstArg.asKindOrThrow(SyntaxKind.PropertyAccessExpression);
220
+ return propAccess.getNameNode().getText();
221
+ }
222
+ // Handle string literals like styled('div') or styled("section")
223
+ if (firstArg.getKind() === SyntaxKind.StringLiteral) {
224
+ const str = firstArg.asKindOrThrow(SyntaxKind.StringLiteral);
225
+ return str.getLiteralText();
226
+ }
227
+ }
228
+ }
229
+ }
230
+ return null;
231
+ }
232
+ catch {
233
+ // Return null on unexpected errors - outer try/catch will handle logging
234
+ return null;
235
+ }
236
+ }
237
+ /**
238
+ * Check if a template literal contains theme usage
239
+ * Looks for patterns like ${props => props.theme.colors.primary}
240
+ */
241
+ function containsThemeUsage(template) {
242
+ try {
243
+ // For NoSubstitutionTemplateLiteral, check for theme. in literal text
244
+ // (NoSubstitutionTemplateLiteral can't contain ${}, so just check for theme.)
245
+ if (template.getKind() === SyntaxKind.NoSubstitutionTemplateLiteral) {
246
+ const text = template.getLiteralText?.() ?? template.getText();
247
+ return /theme\./.test(text);
248
+ }
249
+ // For TemplateExpression, check all template spans for theme references
250
+ if (template.getKind() === SyntaxKind.TemplateExpression) {
251
+ const templateExpr = template.asKindOrThrow(SyntaxKind.TemplateExpression);
252
+ // Check head for theme references
253
+ const headText = templateExpr.getHead().getText();
254
+ if (/theme\./.test(headText)) {
255
+ return true;
256
+ }
257
+ // Check each span's expression for theme references
258
+ for (const span of templateExpr.getTemplateSpans()) {
259
+ try {
260
+ const expression = span.getExpression();
261
+ // Recursively check the expression for theme references
262
+ if (containsThemeInExpression(expression)) {
263
+ return true;
264
+ }
265
+ // Check literal part for theme references
266
+ const literalText = span.getLiteral().getText();
267
+ if (/theme\./.test(literalText)) {
268
+ return true;
269
+ }
270
+ }
271
+ catch {
272
+ // Continue checking other spans
273
+ }
274
+ }
275
+ }
276
+ return false;
277
+ }
278
+ catch {
279
+ // Return false on unexpected errors - outer try/catch will handle logging
280
+ return false;
281
+ }
282
+ }
283
+ /**
284
+ * Recursively check if an expression contains theme references
285
+ * Optimized to only check identifiers and property access expressions
286
+ */
287
+ function containsThemeInExpression(node) {
288
+ try {
289
+ // Only check identifiers and property access expressions for theme references
290
+ // This avoids calling getText() on every node recursively
291
+ if (node.getKind() === SyntaxKind.Identifier ||
292
+ node.getKind() === SyntaxKind.PropertyAccessExpression) {
293
+ const text = node.getText();
294
+ if (/theme\./.test(text)) {
295
+ return true;
296
+ }
297
+ }
298
+ // Recursively check child nodes
299
+ for (const child of node.getChildren()) {
300
+ try {
301
+ if (containsThemeInExpression(child)) {
302
+ return true;
303
+ }
304
+ }
305
+ catch {
306
+ // Continue checking other children
307
+ }
308
+ }
309
+ return false;
310
+ }
311
+ catch {
312
+ // Return false on unexpected errors - outer try/catch will handle logging
313
+ return false;
314
+ }
30
315
  }
31
316
  //# sourceMappingURL=styled.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styled.js","sourceRoot":"","sources":["../../../src/core/styleExtractor/styled.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAkB;IAKxD,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,2DAA2D;IAC3D,MAAM,cAAc,GAAG;QACrB,iBAAiB;QACjB,mBAAmB;KACpB,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,IAAI,KAAK,CAAC,CAAC,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAErF,2BAA2B;IAC3B,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAE/E,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACtD,QAAQ;QACR,WAAW;KACZ,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"styled.js","sourceRoot":"","sources":["../../../src/core/styleExtractor/styled.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,34 @@
1
1
  /**
2
2
  * Tailwind CSS extractor - Extracts and categorizes Tailwind utility classes
3
3
  */
4
+ import { SourceFile } from 'ts-morph';
4
5
  /**
5
- * Extract Tailwind classes from className attributes in JSX
6
+ * Extract Tailwind classes from className attributes in JSX (AST-based)
7
+ *
8
+ * Uses AST traversal to extract classes from:
9
+ * - Literal strings: className="flex p-4"
10
+ * - Template literals: className={`flex ${variable}`} (static segments extracted)
11
+ * - Function calls: className={cn('flex', isActive && 'bg-blue')}
12
+ * - Conditional expressions: className={isActive && 'bg-blue'}
13
+ *
14
+ * Note: Template literals are partially analyzed – static segments are extracted,
15
+ * dynamic expressions within ${} are ignored.
16
+ *
17
+ * Falls back to regex extraction for source text if AST is not available.
6
18
  */
7
- export declare function extractTailwindClasses(sourceText: string): string[];
19
+ export declare function extractTailwindClasses(source: SourceFile | string): string[];
8
20
  /**
9
21
  * Categorize Tailwind utility classes
22
+ *
23
+ * Returns a record mapping category names to arrays of class names (JSON-ready).
24
+ * Each class is categorized based on its base utility (after stripping variant prefixes).
10
25
  */
11
- export declare function categorizeTailwindClasses(classes: string[]): Record<string, Set<string>>;
26
+ export declare function categorizeTailwindClasses(classes: string[]): Record<string, string[]>;
12
27
  /**
13
28
  * Extract responsive breakpoints used in the component
29
+ *
30
+ * Finds breakpoints anywhere in class names, not just at the start.
31
+ * Handles cases like hover:sm:bg-red-500 (though uncommon in practice).
14
32
  */
15
33
  export declare function extractBreakpoints(classes: string[]): string[];
16
34
  //# sourceMappingURL=tailwind.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tailwind.d.ts","sourceRoot":"","sources":["../../../src/core/styleExtractor/tailwind.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBnE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CA6BxF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAY9D"}
1
+ {"version":3,"file":"tailwind.d.ts","sourceRoot":"","sources":["../../../src/core/styleExtractor/tailwind.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAkE,MAAM,UAAU,CAAC;AAiDtG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,EAAE,CA8D5E;AA0ID;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EAAE,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CA2C1B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAsB9D"}