@lokalise/api-contracts 6.3.0 → 6.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.
- package/README.md +63 -0
- package/dist/contractBuilder.d.ts +84 -0
- package/dist/contractBuilder.js +17 -0
- package/dist/contractBuilder.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/rest/restContractBuilder.d.ts +6 -0
- package/dist/rest/restContractBuilder.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,69 @@ This reduces amount of assumptions FE needs to make about the behaviour of BE, r
|
|
|
8
8
|
written on FE, and makes the code more type-safe (as path parameter setting is handled by logic exposed by BE, in a
|
|
9
9
|
type-safe way).
|
|
10
10
|
|
|
11
|
+
## Universal Contract Builder
|
|
12
|
+
|
|
13
|
+
Use `buildContract` as a single entry point for creating any type of API contract. It automatically delegates to the appropriate specialized builder based on the configuration:
|
|
14
|
+
|
|
15
|
+
| `sseEvents` | Contract Type |
|
|
16
|
+
|-------------|---------------|
|
|
17
|
+
| ❌ | REST contract (GET, POST, PUT, PATCH, DELETE) |
|
|
18
|
+
| ✅ | SSE or Dual-mode contract |
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { buildContract } from '@lokalise/api-contracts'
|
|
22
|
+
import { z } from 'zod'
|
|
23
|
+
|
|
24
|
+
// REST GET route
|
|
25
|
+
const getUsers = buildContract({
|
|
26
|
+
successResponseBodySchema: z.array(userSchema),
|
|
27
|
+
pathResolver: () => '/api/users',
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// REST POST route
|
|
31
|
+
const createUser = buildContract({
|
|
32
|
+
method: 'post',
|
|
33
|
+
requestBodySchema: createUserSchema,
|
|
34
|
+
successResponseBodySchema: userSchema,
|
|
35
|
+
pathResolver: () => '/api/users',
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// REST DELETE route
|
|
39
|
+
const deleteUser = buildContract({
|
|
40
|
+
method: 'delete',
|
|
41
|
+
requestPathParamsSchema: z.object({ userId: z.string() }),
|
|
42
|
+
pathResolver: (params) => `/api/users/${params.userId}`,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
// SSE-only streaming endpoint
|
|
46
|
+
const notifications = buildContract({
|
|
47
|
+
pathResolver: () => '/api/notifications/stream',
|
|
48
|
+
params: z.object({}),
|
|
49
|
+
query: z.object({}),
|
|
50
|
+
requestHeaders: z.object({}),
|
|
51
|
+
sseEvents: {
|
|
52
|
+
notification: z.object({ id: z.string(), message: z.string() }),
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
// Dual-mode endpoint (supports both JSON and SSE)
|
|
57
|
+
const chatCompletion = buildContract({
|
|
58
|
+
method: 'post',
|
|
59
|
+
pathResolver: () => '/api/chat/completions',
|
|
60
|
+
params: z.object({}),
|
|
61
|
+
query: z.object({}),
|
|
62
|
+
requestHeaders: z.object({}),
|
|
63
|
+
requestBody: z.object({ message: z.string() }),
|
|
64
|
+
syncResponseBody: z.object({ reply: z.string() }),
|
|
65
|
+
sseEvents: {
|
|
66
|
+
chunk: z.object({ delta: z.string() }),
|
|
67
|
+
done: z.object({ usage: z.object({ tokens: z.number() }) }),
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
You can also use the specialized builders directly (`buildRestContract`, `buildSseContract`) if you prefer explicit control over contract types.
|
|
73
|
+
|
|
11
74
|
## REST Contracts
|
|
12
75
|
|
|
13
76
|
Use `buildRestContract` to create REST API contracts. The contract type is automatically determined based on the configuration:
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { z } from 'zod/v4';
|
|
2
|
+
import type { DeleteRouteDefinition, GetRouteDefinition, PayloadRouteDefinition } from './apiContracts.ts';
|
|
3
|
+
import type { HttpStatusCode } from './HttpStatusCodes.ts';
|
|
4
|
+
import { type DeleteContractConfig, type GetContractConfig, type PayloadContractConfig } from './rest/restContractBuilder.ts';
|
|
5
|
+
import type { DualModeContractDefinition } from './sse/dualModeContracts.ts';
|
|
6
|
+
import { type DualModeGetContractConfig, type DualModePayloadContractConfig, type SSEGetContractConfig, type SSEPayloadContractConfig } from './sse/sseContractBuilders.ts';
|
|
7
|
+
import type { SSEContractDefinition } from './sse/sseContracts.ts';
|
|
8
|
+
import type { SSEEventSchemas } from './sse/sseTypes.ts';
|
|
9
|
+
/**
|
|
10
|
+
* Universal contract builder that creates either REST or SSE contracts based on configuration.
|
|
11
|
+
*
|
|
12
|
+
* This is a unified entry point that delegates to:
|
|
13
|
+
* - `buildRestContract` when no `sseEvents` is provided
|
|
14
|
+
* - `buildSseContract` when `sseEvents` is provided
|
|
15
|
+
*
|
|
16
|
+
* ## Contract Type Detection
|
|
17
|
+
*
|
|
18
|
+
* | `sseEvents` | `syncResponseBody` | `requestBody`/`requestBodySchema` | Result |
|
|
19
|
+
* |-------------|-------------------|-----------------------------------|--------|
|
|
20
|
+
* | ❌ | - | ❌ | REST GET |
|
|
21
|
+
* | ❌ | - | ✅ (method: post/put/patch) | REST Payload |
|
|
22
|
+
* | ❌ | - | ❌ (method: delete) | REST DELETE |
|
|
23
|
+
* | ✅ | ❌ | ❌ | SSE-only GET |
|
|
24
|
+
* | ✅ | ❌ | ✅ | SSE-only POST/PUT/PATCH |
|
|
25
|
+
* | ✅ | ✅ | ❌ | Dual-mode GET |
|
|
26
|
+
* | ✅ | ✅ | ✅ | Dual-mode POST/PUT/PATCH |
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // REST GET route
|
|
31
|
+
* const getUsers = buildContract({
|
|
32
|
+
* successResponseBodySchema: z.array(userSchema),
|
|
33
|
+
* pathResolver: () => '/api/users',
|
|
34
|
+
* })
|
|
35
|
+
*
|
|
36
|
+
* // REST POST route
|
|
37
|
+
* const createUser = buildContract({
|
|
38
|
+
* method: 'post',
|
|
39
|
+
* requestBodySchema: createUserSchema,
|
|
40
|
+
* successResponseBodySchema: userSchema,
|
|
41
|
+
* pathResolver: () => '/api/users',
|
|
42
|
+
* })
|
|
43
|
+
*
|
|
44
|
+
* // REST DELETE route
|
|
45
|
+
* const deleteUser = buildContract({
|
|
46
|
+
* method: 'delete',
|
|
47
|
+
* pathResolver: (params) => `/api/users/${params.userId}`,
|
|
48
|
+
* requestPathParamsSchema: z.object({ userId: z.string() }),
|
|
49
|
+
* })
|
|
50
|
+
*
|
|
51
|
+
* // SSE-only streaming endpoint
|
|
52
|
+
* const notifications = buildContract({
|
|
53
|
+
* pathResolver: () => '/api/notifications/stream',
|
|
54
|
+
* params: z.object({}),
|
|
55
|
+
* query: z.object({}),
|
|
56
|
+
* requestHeaders: z.object({}),
|
|
57
|
+
* sseEvents: {
|
|
58
|
+
* notification: z.object({ id: z.string(), message: z.string() }),
|
|
59
|
+
* },
|
|
60
|
+
* })
|
|
61
|
+
*
|
|
62
|
+
* // Dual-mode endpoint (supports both JSON and SSE)
|
|
63
|
+
* const chatCompletion = buildContract({
|
|
64
|
+
* method: 'post',
|
|
65
|
+
* pathResolver: () => '/api/chat/completions',
|
|
66
|
+
* params: z.object({}),
|
|
67
|
+
* query: z.object({}),
|
|
68
|
+
* requestHeaders: z.object({}),
|
|
69
|
+
* requestBody: z.object({ message: z.string() }),
|
|
70
|
+
* syncResponseBody: z.object({ reply: z.string() }),
|
|
71
|
+
* sseEvents: {
|
|
72
|
+
* chunk: z.object({ delta: z.string() }),
|
|
73
|
+
* done: z.object({ usage: z.object({ tokens: z.number() }) }),
|
|
74
|
+
* },
|
|
75
|
+
* })
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function buildContract<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: GetContractConfig<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): GetRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
|
|
79
|
+
export declare function buildContract<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = true, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: DeleteContractConfig<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): DeleteRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
|
|
80
|
+
export declare function buildContract<RequestBodySchema extends z.Schema | undefined = undefined, SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: PayloadContractConfig<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): PayloadRouteDefinition<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
|
|
81
|
+
export declare function buildContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: DualModeGetContractConfig<Params, Query, RequestHeaders, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>): DualModeContractDefinition<'get', Params, Query, RequestHeaders, undefined, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>;
|
|
82
|
+
export declare function buildContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: SSEGetContractConfig<Params, Query, RequestHeaders, Events, ResponseSchemasByStatusCode>): SSEContractDefinition<'get', Params, Query, RequestHeaders, undefined, Events, ResponseSchemasByStatusCode>;
|
|
83
|
+
export declare function buildContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, JsonResponse extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseHeaders extends z.ZodTypeAny | undefined = undefined, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: DualModePayloadContractConfig<Params, Query, RequestHeaders, Body, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>): DualModeContractDefinition<'post' | 'put' | 'patch', Params, Query, RequestHeaders, Body, JsonResponse, Events, ResponseHeaders, ResponseSchemasByStatusCode>;
|
|
84
|
+
export declare function buildContract<Params extends z.ZodTypeAny, Query extends z.ZodTypeAny, RequestHeaders extends z.ZodTypeAny, Body extends z.ZodTypeAny, Events extends SSEEventSchemas, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.ZodTypeAny>> | undefined = undefined>(config: SSEPayloadContractConfig<Params, Query, RequestHeaders, Body, Events, ResponseSchemasByStatusCode>): SSEContractDefinition<'post' | 'put' | 'patch', Params, Query, RequestHeaders, Body, Events, ResponseSchemasByStatusCode>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { buildRestContract, } from "./rest/restContractBuilder.js";
|
|
2
|
+
import { buildSseContract, } from "./sse/sseContractBuilders.js";
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Implementation
|
|
5
|
+
// ============================================================================
|
|
6
|
+
export function buildContract(
|
|
7
|
+
// biome-ignore lint/suspicious/noExplicitAny: Union of all config types
|
|
8
|
+
config) {
|
|
9
|
+
const hasSseEvents = 'sseEvents' in config && config.sseEvents !== undefined;
|
|
10
|
+
if (hasSseEvents) {
|
|
11
|
+
// Delegate to SSE contract builder
|
|
12
|
+
return buildSseContract(config);
|
|
13
|
+
}
|
|
14
|
+
// Delegate to REST contract builder
|
|
15
|
+
return buildRestContract(config);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=contractBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contractBuilder.js","sourceRoot":"","sources":["../src/contractBuilder.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,iBAAiB,GAIlB,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EACL,gBAAgB,GAKjB,MAAM,8BAA8B,CAAA;AAqTrC,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,UAAU,aAAa;AAC3B,wEAAwE;AACxE,MAAW;IAGX,MAAM,YAAY,GAAG,WAAW,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,CAAA;IAE5E,IAAI,YAAY,EAAE,CAAC;QACjB,mCAAmC;QACnC,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAA;IACjC,CAAC;IAED,oCAAoC;IACpC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAA;AAClC,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,+BAA+B;AAC/B,cAAc,4BAA4B,CAAA;AAC1C,oBAAoB;AACpB,cAAc,8BAA8B,CAAA;AAC5C,gBAAgB;AAChB,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,6BAA6B;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,+BAA+B;AAC/B,cAAc,4BAA4B,CAAA;AAC1C,oBAAoB;AACpB,cAAc,8BAA8B,CAAA;AAC5C,gBAAgB;AAChB,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA"}
|
|
@@ -8,6 +8,8 @@ import type { HttpStatusCode } from '../HttpStatusCodes.ts';
|
|
|
8
8
|
export type GetContractConfig<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = Omit<CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'> & {
|
|
9
9
|
method?: never;
|
|
10
10
|
requestBodySchema?: never;
|
|
11
|
+
/** Discriminator to distinguish from SSE contracts in buildContract */
|
|
12
|
+
sseEvents?: never;
|
|
11
13
|
};
|
|
12
14
|
/**
|
|
13
15
|
* Configuration for building a DELETE route.
|
|
@@ -16,6 +18,8 @@ export type GetContractConfig<SuccessResponseBodySchema extends z.Schema | undef
|
|
|
16
18
|
export type DeleteContractConfig<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = true, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = Omit<CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'> & {
|
|
17
19
|
method: 'delete';
|
|
18
20
|
requestBodySchema?: never;
|
|
21
|
+
/** Discriminator to distinguish from SSE contracts in buildContract */
|
|
22
|
+
sseEvents?: never;
|
|
19
23
|
};
|
|
20
24
|
/**
|
|
21
25
|
* Configuration for building a payload route (POST, PUT, PATCH).
|
|
@@ -24,6 +28,8 @@ export type DeleteContractConfig<SuccessResponseBodySchema extends z.Schema | un
|
|
|
24
28
|
export type PayloadContractConfig<RequestBodySchema extends z.Schema | undefined = undefined, SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode> & {
|
|
25
29
|
method: 'post' | 'put' | 'patch';
|
|
26
30
|
requestBodySchema: RequestBodySchema;
|
|
31
|
+
/** Discriminator to distinguish from SSE contracts in buildContract */
|
|
32
|
+
sseEvents?: never;
|
|
27
33
|
};
|
|
28
34
|
/**
|
|
29
35
|
* Builds REST API contracts with automatic type inference.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restContractBuilder.js","sourceRoot":"","sources":["../../src/rest/restContractBuilder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"restContractBuilder.js","sourceRoot":"","sources":["../../src/rest/restContractBuilder.ts"],"names":[],"mappings":"AA+RA,iBAAiB;AACjB,MAAM,UAAU,iBAAiB,CAC/B,MAKsE;IAGtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC5B,MAAM,OAAO,GAAG,mBAAmB,IAAI,MAAM,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS,CAAA;IAEvF,oEAAoE;IACpE,MAAM,aAAa,GAAG,MAAM,KAAK,QAAQ,CAAA;IACzC,MAAM,8BAA8B,GAAG,aAAa,CAAA;IAEpD,MAAM,UAAU,GAAG;QACjB,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,IAAI,8BAA8B;QACzF,yBAAyB,EAAE,MAAM,CAAC,yBAAyB,IAAI,KAAK;QACpE,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;QACvD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,yBAAyB,EAAE,MAAM,CAAC,yBAAyB;QAC3D,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,2BAA2B,EAAE,MAAM,CAAC,2BAA2B;QAC/D,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAA;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,iCAAiC;QACjC,OAAO;YACL,GAAG,UAAU;YACb,MAAM,EAAE,MAAkC;YAC1C,qFAAqF;YACrF,iBAAiB,EAAG,MAAqC,CAAC,iBAAiB;SAC5E,CAAA;IACH,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,eAAe;QACf,OAAO;YACL,GAAG,UAAU;YACb,MAAM,EAAE,QAAiB;SAC1B,CAAA;IACH,CAAC;IAED,sBAAsB;IACtB,OAAO;QACL,GAAG,UAAU;QACb,MAAM,EAAE,KAAc;KACvB,CAAA;AACH,CAAC"}
|