@ereo/testing 0.1.6

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.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # @ereo/testing
2
+
3
+ Testing utilities for EreoJS applications. Makes testing loaders, actions, middleware, and components trivial with a clean, intuitive API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @ereo/testing
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { testLoader, testAction, createTestContext } from '@ereo/testing';
15
+ import { loader, action } from './routes/users';
16
+
17
+ // Test a loader
18
+ const result = await testLoader(loader, {
19
+ params: { id: '123' },
20
+ });
21
+ expect(result.data.user.id).toBe('123');
22
+
23
+ // Test an action
24
+ const actionResult = await testAction(action, {
25
+ method: 'POST',
26
+ formData: { name: 'John' },
27
+ });
28
+ expect(actionResult.status).toBe(200);
29
+ ```
30
+
31
+ ## Key Features
32
+
33
+ - **Loader Testing** - Test loaders with `testLoader` and `createLoaderTester`
34
+ - **Action Testing** - Test actions with `testAction` and `createActionTester`
35
+ - **Middleware Testing** - Test middleware with `testMiddleware` and `createMiddlewareTester`
36
+ - **Component Testing** - Render routes with `renderRoute` and `createRouteRenderer`
37
+ - **Mock Utilities** - Create mock requests with `createMockRequest` and `createFormRequest`
38
+ - **Assertions** - Built-in assertions: `assertRedirect`, `assertJson`, `assertStatus`
39
+ - **Snapshot Testing** - Snapshot loaders and actions with `snapshotLoader` and `snapshotAction`
40
+ - **Test Server** - Spin up a test server with `createTestServer`
41
+
42
+ ## Middleware Testing
43
+
44
+ ```typescript
45
+ import { testMiddleware, createMockRequest } from '@ereo/testing';
46
+
47
+ const result = await testMiddleware(authMiddleware, {
48
+ request: createMockRequest('/protected', {
49
+ headers: { Authorization: 'Bearer token' },
50
+ }),
51
+ });
52
+
53
+ expect(result.continued).toBe(true);
54
+ ```
55
+
56
+ ## Component Testing
57
+
58
+ ```typescript
59
+ import { renderRoute, assertStatus } from '@ereo/testing';
60
+
61
+ const result = await renderRoute('/users/123', {
62
+ loaderData: { user: { id: '123', name: 'John' } },
63
+ });
64
+
65
+ expect(result.html).toContain('John');
66
+ assertStatus(result.response, 200);
67
+ ```
68
+
69
+ ## Test Server
70
+
71
+ ```typescript
72
+ import { createTestServer } from '@ereo/testing';
73
+
74
+ const server = await createTestServer({
75
+ routesDir: './src/routes',
76
+ });
77
+
78
+ const response = await server.fetch('/api/users');
79
+ expect(response.status).toBe(200);
80
+
81
+ await server.close();
82
+ ```
83
+
84
+ ## Documentation
85
+
86
+ For full documentation, visit [https://ereojs.dev/docs/testing](https://ereojs.dev/docs/testing)
87
+
88
+ ## Part of EreoJS
89
+
90
+ This package is part of the [EreoJS](https://github.com/ereojs/ereo) monorepo - a modern full-stack framework built for Bun.
91
+
92
+ ## License
93
+
94
+ MIT
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @ereo/testing - Action Testing
3
+ *
4
+ * Utilities for testing route actions.
5
+ */
6
+ import type { ActionFunction, RouteParams } from '@ereo/core';
7
+ import { type TestContextOptions, type TestContext } from './context';
8
+ import { type MockRequestOptions } from './request';
9
+ /**
10
+ * Options for testing an action.
11
+ */
12
+ export interface ActionTestOptions<P = RouteParams> {
13
+ /** Route parameters */
14
+ params?: P;
15
+ /** Request options (method defaults to POST) */
16
+ request?: MockRequestOptions;
17
+ /** Context options */
18
+ context?: TestContextOptions;
19
+ /** Form data to submit */
20
+ formData?: Record<string, string | Blob>;
21
+ /** JSON body to submit */
22
+ body?: Record<string, unknown>;
23
+ }
24
+ /**
25
+ * Result of testing an action.
26
+ */
27
+ export interface ActionTestResult<T = unknown> {
28
+ /** The action's return value (parsed if Response) */
29
+ data: T;
30
+ /** The raw response if action returned a Response */
31
+ response: Response | null;
32
+ /** The test context (for inspection) */
33
+ context: TestContext;
34
+ /** The request used */
35
+ request: Request;
36
+ /** Execution time in milliseconds */
37
+ duration: number;
38
+ /** Whether the action returned a redirect */
39
+ isRedirect: boolean;
40
+ /** Redirect location if applicable */
41
+ redirectTo: string | null;
42
+ }
43
+ /**
44
+ * Test an action function directly.
45
+ *
46
+ * @example
47
+ * import { testAction } from '@ereo/testing';
48
+ * import { action } from './routes/blog/[slug]';
49
+ *
50
+ * test('creates a comment', async () => {
51
+ * const result = await testAction(action, {
52
+ * params: { slug: 'my-post' },
53
+ * formData: { content: 'Great post!' },
54
+ * });
55
+ *
56
+ * expect(result.data.success).toBe(true);
57
+ * });
58
+ */
59
+ export declare function testAction<T = unknown, P = RouteParams>(action: ActionFunction<T | Response, P>, options?: ActionTestOptions<P>): Promise<ActionTestResult<T>>;
60
+ /**
61
+ * Create a reusable action tester with preset options.
62
+ *
63
+ * @example
64
+ * const testCommentAction = createActionTester(action, {
65
+ * context: { store: { user: testUser } },
66
+ * });
67
+ *
68
+ * test('creates comment', async () => {
69
+ * const result = await testCommentAction({
70
+ * params: { slug: 'test' },
71
+ * formData: { content: 'Hello!' },
72
+ * });
73
+ * expect(result.data.success).toBe(true);
74
+ * });
75
+ */
76
+ export declare function createActionTester<T = unknown, P = RouteParams>(action: ActionFunction<T | Response, P>, baseOptions?: ActionTestOptions<P>): (overrides?: Partial<ActionTestOptions<P>>) => Promise<ActionTestResult<T>>;
77
+ /**
78
+ * Test action with multiple form submissions.
79
+ *
80
+ * @example
81
+ * const results = await testActionMatrix(action, {
82
+ * params: { slug: 'post-1' },
83
+ * submissions: [
84
+ * { formData: { content: 'Comment 1' } },
85
+ * { formData: { content: 'Comment 2' } },
86
+ * { formData: { content: '' } }, // Invalid
87
+ * ],
88
+ * });
89
+ *
90
+ * expect(results[0].data.success).toBe(true);
91
+ * expect(results[2].data.error).toBeDefined();
92
+ */
93
+ export declare function testActionMatrix<T = unknown, P = RouteParams>(action: ActionFunction<T | Response, P>, options: {
94
+ params?: P;
95
+ submissions: Array<{
96
+ formData?: Record<string, string | Blob>;
97
+ body?: Record<string, unknown>;
98
+ }>;
99
+ context?: TestContextOptions;
100
+ }): Promise<ActionTestResult<T>[]>;
101
+ /**
102
+ * Test action error handling.
103
+ *
104
+ * @example
105
+ * test('handles validation error', async () => {
106
+ * const result = await testActionError(action, {
107
+ * formData: { content: '' },
108
+ * });
109
+ *
110
+ * expect(result.error).toBeInstanceOf(ValidationError);
111
+ * });
112
+ */
113
+ export declare function testActionError<P = RouteParams>(action: ActionFunction<unknown, P>, options?: ActionTestOptions<P>): Promise<{
114
+ error: Error | null;
115
+ context: TestContext;
116
+ request: Request;
117
+ }>;
118
+ /**
119
+ * Test action with file upload.
120
+ *
121
+ * @example
122
+ * test('uploads file', async () => {
123
+ * const result = await testActionWithFile(action, {
124
+ * params: { id: '1' },
125
+ * file: {
126
+ * field: 'avatar',
127
+ * name: 'avatar.png',
128
+ * content: imageBlob,
129
+ * type: 'image/png',
130
+ * },
131
+ * });
132
+ *
133
+ * expect(result.data.url).toContain('avatar.png');
134
+ * });
135
+ */
136
+ export declare function testActionWithFile<T = unknown, P = RouteParams>(action: ActionFunction<T | Response, P>, options: {
137
+ params?: P;
138
+ file: {
139
+ field: string;
140
+ name: string;
141
+ content: string | Blob;
142
+ type?: string;
143
+ };
144
+ extraFields?: Record<string, string>;
145
+ context?: TestContextOptions;
146
+ }): Promise<ActionTestResult<T>>;
147
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @ereo/testing - Assertions
3
+ *
4
+ * Common assertions for testing responses.
5
+ */
6
+ /**
7
+ * Assertion options.
8
+ */
9
+ export interface AssertionOptions {
10
+ /** Custom error message */
11
+ message?: string;
12
+ }
13
+ /**
14
+ * Assert that a response is a redirect.
15
+ *
16
+ * @example
17
+ * const result = await testAction(action, { formData: {} });
18
+ * assertRedirect(result.response, '/login');
19
+ */
20
+ export declare function assertRedirect(response: Response | null, expectedLocation?: string, options?: AssertionOptions & {
21
+ status?: number;
22
+ }): void;
23
+ /**
24
+ * Assert that a response has the expected JSON body.
25
+ *
26
+ * @example
27
+ * const result = await testLoader(loader, { params: { id: '1' } });
28
+ * await assertJson(result.data, { id: 1, name: 'Test' });
29
+ */
30
+ export declare function assertJson<T = unknown>(responseOrData: Response | T, expected: Partial<T>, options?: AssertionOptions): Promise<void>;
31
+ /**
32
+ * Assert that a response has the expected status code.
33
+ *
34
+ * @example
35
+ * const result = await testMiddleware(authMiddleware, {});
36
+ * assertStatus(result.response, 401);
37
+ */
38
+ export declare function assertStatus(response: Response | null, expected: number | number[], options?: AssertionOptions): void;
39
+ /**
40
+ * Assert that a response has the expected headers.
41
+ *
42
+ * @example
43
+ * const result = await testLoader(loader, {});
44
+ * assertHeaders(result.response, {
45
+ * 'Content-Type': 'application/json',
46
+ * 'Cache-Control': /max-age=\d+/,
47
+ * });
48
+ */
49
+ export declare function assertHeaders(response: Response | null, expected: Record<string, string | RegExp>, options?: AssertionOptions): void;
50
+ /**
51
+ * Assert that a response sets the expected cookies.
52
+ *
53
+ * @example
54
+ * const result = await testAction(loginAction, {
55
+ * formData: { email: 'test@example.com', password: 'secret' },
56
+ * });
57
+ * assertCookies(result.response, {
58
+ * session: { exists: true, httpOnly: true },
59
+ * });
60
+ */
61
+ export declare function assertCookies(response: Response | null, expected: Record<string, {
62
+ exists?: boolean;
63
+ value?: string | RegExp;
64
+ httpOnly?: boolean;
65
+ secure?: boolean;
66
+ sameSite?: 'Strict' | 'Lax' | 'None';
67
+ path?: string;
68
+ maxAge?: number;
69
+ expires?: boolean;
70
+ }>, options?: AssertionOptions): void;
71
+ /**
72
+ * Assert that an error was thrown.
73
+ *
74
+ * @example
75
+ * await assertThrows(
76
+ * () => testLoader(loader, { params: { id: 'invalid' } }),
77
+ * { message: /not found/i, status: 404 }
78
+ * );
79
+ */
80
+ export declare function assertThrows(fn: () => Promise<unknown>, expected?: {
81
+ message?: string | RegExp;
82
+ name?: string;
83
+ status?: number;
84
+ }, options?: AssertionOptions): Promise<void>;
85
+ /**
86
+ * Assert that a value matches a schema (basic type checking).
87
+ *
88
+ * @example
89
+ * await assertSchema(result.data, {
90
+ * id: 'number',
91
+ * name: 'string',
92
+ * tags: 'array',
93
+ * meta: 'object',
94
+ * });
95
+ */
96
+ export declare function assertSchema(data: unknown, schema: Record<string, 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'undefined'>, options?: AssertionOptions): void;
97
+ //# sourceMappingURL=assertions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,GAAG,IAAI,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,OAAO,GAAE,gBAAgB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GACnD,IAAI,CAuCN;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,CAAC,GAAG,OAAO,EAC1C,cAAc,EAAE,QAAQ,GAAG,CAAC,EAC5B,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,GAAG,IAAI,EACzB,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CAaN;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,GAAG,IAAI,EACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EACzC,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CA+BN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,GAAG,IAAI,EACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC,EACF,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CAsGN;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC1B,QAAQ,GAAE;IACR,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,EACN,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CA4Cf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,CAAC,EACnG,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CA4BN"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @ereo/testing - Test Context
3
+ *
4
+ * Create mock contexts for testing loaders, actions, and middleware.
5
+ */
6
+ import type { AppContext, CacheOptions } from '@ereo/core';
7
+ /**
8
+ * Options for creating a test context.
9
+ */
10
+ export interface TestContextOptions {
11
+ /** Initial context store values */
12
+ store?: Record<string, unknown>;
13
+ /** Initial environment variables */
14
+ env?: Record<string, string>;
15
+ /** Request URL */
16
+ url?: string | URL;
17
+ /** Initial cache tags */
18
+ cacheTags?: string[];
19
+ /** Initial response headers */
20
+ responseHeaders?: Record<string, string>;
21
+ }
22
+ /**
23
+ * Extended test context with inspection utilities.
24
+ */
25
+ export interface TestContext extends AppContext {
26
+ /** Get all values set in the context store */
27
+ getStore(): Record<string, unknown>;
28
+ /** Get all cache operations performed */
29
+ getCacheOperations(): CacheOperation[];
30
+ /** Reset the context to initial state */
31
+ reset(): void;
32
+ }
33
+ /**
34
+ * Cache operation record for inspection.
35
+ */
36
+ export interface CacheOperation {
37
+ type: 'set' | 'get';
38
+ options?: CacheOptions;
39
+ timestamp: number;
40
+ }
41
+ /**
42
+ * Create a test context for testing loaders, actions, and middleware.
43
+ *
44
+ * @example
45
+ * const ctx = createTestContext({
46
+ * store: { user: { id: 1, name: 'Test' } },
47
+ * env: { DATABASE_URL: 'test://db' },
48
+ * });
49
+ *
50
+ * const result = await loader({ request, params, context: ctx });
51
+ */
52
+ export declare function createTestContext(options?: TestContextOptions): TestContext;
53
+ /**
54
+ * Create a context factory for repeated test setup.
55
+ *
56
+ * @example
57
+ * const contextFactory = createContextFactory({
58
+ * store: { user: testUser },
59
+ * });
60
+ *
61
+ * test('loader test 1', async () => {
62
+ * const ctx = contextFactory();
63
+ * // ...
64
+ * });
65
+ *
66
+ * test('loader test 2', async () => {
67
+ * const ctx = contextFactory({ store: { user: differentUser } });
68
+ * // ...
69
+ * });
70
+ */
71
+ export declare function createContextFactory(baseOptions?: TestContextOptions): (overrides?: Partial<TestContextOptions>) => TestContext;
72
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAgB,YAAY,EAAE,MAAM,YAAY,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,kBAAkB;IAClB,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,+BAA+B;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC7C,8CAA8C;IAC9C,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,yCAAyC;IACzC,kBAAkB,IAAI,cAAc,EAAE,CAAC;IACvC,yCAAyC;IACzC,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;IACpB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAsE/E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,GAAE,kBAAuB,GACnC,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,WAAW,CAgB1D"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @ereo/testing
3
+ *
4
+ * Testing utilities for EreoJS applications.
5
+ * Makes testing loaders, actions, middleware, and components trivial.
6
+ */
7
+ export { createTestContext, createContextFactory, type TestContextOptions, type TestContext, } from './context';
8
+ export { testLoader, createLoaderTester, type LoaderTestOptions, type LoaderTestResult, } from './loader';
9
+ export { testAction, createActionTester, type ActionTestOptions, type ActionTestResult, } from './action';
10
+ export { testMiddleware, createMiddlewareTester, type MiddlewareTestOptions, type MiddlewareTestResult, } from './middleware';
11
+ export { createMockRequest, createFormRequest, createMockFormData, createMockHeaders, parseJsonResponse, parseTextResponse, type MockRequestOptions, } from './request';
12
+ export { renderRoute, createRouteRenderer, type RenderRouteOptions, type RenderResult, } from './render';
13
+ export { assertRedirect, assertJson, assertStatus, assertHeaders, assertCookies, type AssertionOptions, } from './assertions';
14
+ export { createTestServer, type TestServer, type TestServerOptions, } from './server';
15
+ export { snapshotLoader, snapshotAction, type SnapshotOptions, } from './snapshot';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,kBAAkB,GACxB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}