@navios/jwt 1.0.0-alpha.2 → 1.0.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/CHANGELOG.md +25 -0
- package/README.md +6 -8
- package/dist/src/__tests__/jwt.service.spec.d.mts +2 -0
- package/dist/src/__tests__/jwt.service.spec.d.mts.map +1 -0
- package/dist/src/jwt-service.provider.d.mts +1 -1
- package/dist/src/jwt.service.d.mts +6 -14
- package/dist/src/jwt.service.d.mts.map +1 -1
- package/dist/src/options/jwt-service.options.d.mts +2 -7
- package/dist/src/options/jwt-service.options.d.mts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/index.cjs +29 -34
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +9 -22
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +9 -22
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +29 -34
- package/lib/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/jwt.service.spec.mts +453 -0
- package/src/jwt-service.provider.mts +1 -1
- package/src/jwt.service.mts +64 -105
- package/src/options/jwt-service.options.mts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.0] - 2026-01-09
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Stable Release**: First stable release of @navios/jwt
|
|
13
|
+
- Production-ready JWT authentication and authorization for Navios
|
|
14
|
+
- Type-safe JWT token generation and validation
|
|
15
|
+
- Seamless integration with Navios guards and dependency injection
|
|
16
|
+
|
|
17
|
+
## [1.0.0-alpha.3] - 2026-01-08
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Simplified Internal Implementation**: Refactored `JwtService` with extracted helper methods
|
|
22
|
+
- New `prepareSign()` private method for sign option preparation
|
|
23
|
+
- New `prepareVerify()` private method for verify option preparation
|
|
24
|
+
- Reduced code duplication between sync and async methods
|
|
25
|
+
- **Improved JSDoc Documentation**: Updated method documentation for clarity
|
|
26
|
+
- Removed outdated references to async `secretOrKeyProvider` warnings
|
|
27
|
+
- Simplified async method descriptions
|
|
28
|
+
|
|
29
|
+
### Dependencies
|
|
30
|
+
|
|
31
|
+
- Updated to support `@navios/core` ^1.0.0-alpha.3
|
|
32
|
+
|
|
8
33
|
## [1.0.0-alpha.2] - 2026-01-07
|
|
9
34
|
|
|
10
35
|
### Dependencies
|
package/README.md
CHANGED
|
@@ -152,7 +152,7 @@ const token = jwtService.sign(
|
|
|
152
152
|
{ expiresIn: '1h' }
|
|
153
153
|
)
|
|
154
154
|
|
|
155
|
-
// Asynchronous signing
|
|
155
|
+
// Asynchronous signing
|
|
156
156
|
const token = await jwtService.signAsync(
|
|
157
157
|
{ userId: '123', role: 'admin' },
|
|
158
158
|
{ expiresIn: '1h' }
|
|
@@ -174,7 +174,7 @@ try {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
// Asynchronous verification
|
|
177
|
+
// Asynchronous verification
|
|
178
178
|
try {
|
|
179
179
|
const payload = await jwtService.verifyAsync<{ userId: string }>(token)
|
|
180
180
|
console.log(payload.userId)
|
|
@@ -236,7 +236,7 @@ interface JwtServiceOptions {
|
|
|
236
236
|
requestType: RequestType,
|
|
237
237
|
token?: string,
|
|
238
238
|
options?: SignOptions | VerifyOptions,
|
|
239
|
-
) => Secret
|
|
239
|
+
) => Secret
|
|
240
240
|
}
|
|
241
241
|
```
|
|
242
242
|
|
|
@@ -263,23 +263,21 @@ The library exports error classes from the underlying `jsonwebtoken` library:
|
|
|
263
263
|
|
|
264
264
|
1. **Always use `verify()` or `verifyAsync()`** for production code. Never use `decode()` for security-sensitive operations.
|
|
265
265
|
|
|
266
|
-
2. **
|
|
267
|
-
|
|
268
|
-
3. **Specify allowed algorithms** in `verifyOptions` to prevent algorithm confusion attacks:
|
|
266
|
+
2. **Specify allowed algorithms** in `verifyOptions` to prevent algorithm confusion attacks:
|
|
269
267
|
```typescript
|
|
270
268
|
verifyOptions: {
|
|
271
269
|
algorithms: ['HS256', 'RS256'], // Explicitly allow only these algorithms
|
|
272
270
|
}
|
|
273
271
|
```
|
|
274
272
|
|
|
275
|
-
|
|
273
|
+
3. **Set appropriate expiration times** based on your security requirements:
|
|
276
274
|
```typescript
|
|
277
275
|
signOptions: {
|
|
278
276
|
expiresIn: '15m', // Short-lived access tokens
|
|
279
277
|
}
|
|
280
278
|
```
|
|
281
279
|
|
|
282
|
-
|
|
280
|
+
4. **Use asymmetric keys** for distributed systems where public keys can be shared:
|
|
283
281
|
```typescript
|
|
284
282
|
// Sign with private key
|
|
285
283
|
privateKey: fs.readFileSync('private.pem')
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.service.spec.d.mts","sourceRoot":"","sources":["../../../src/__tests__/jwt.service.spec.mts"],"names":[],"mappings":""}
|
|
@@ -10,7 +10,7 @@ import { JwtServiceOptionsSchema } from './options/jwt-service.options.mjs';
|
|
|
10
10
|
* both static configuration and async factory functions for dynamic configuration.
|
|
11
11
|
*
|
|
12
12
|
* @param config - Static JWT service configuration options
|
|
13
|
-
* @returns A bound injection token that can be used with `inject()` or `
|
|
13
|
+
* @returns A bound injection token that can be used with `inject()` or `asyncInject()`
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* ```ts
|
|
@@ -182,17 +182,12 @@ export declare const JwtServiceToken: InjectionToken<unknown, import("zod/v4").Z
|
|
|
182
182
|
subject: import("zod/v4").ZodOptional<import("zod/v4").ZodString>;
|
|
183
183
|
maxAge: import("zod/v4").ZodOptional<import("zod/v4").ZodUnion<readonly [import("zod/v4").ZodString, import("zod/v4").ZodNumber]>>;
|
|
184
184
|
allowInvalidAsymmetricKeyTypes: import("zod/v4").ZodOptional<import("zod/v4").ZodBoolean>;
|
|
185
|
-
}, import("zod/v4/core").$strip>]>>], null>, import("zod/v4").ZodUnion<readonly [import("zod/v4").
|
|
185
|
+
}, import("zod/v4/core").$strip>]>>], null>, import("zod/v4").ZodUnion<readonly [import("zod/v4").ZodString, import("zod/v4").ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, import("zod/v4").ZodObject<{
|
|
186
186
|
type: import("zod/v4").ZodString;
|
|
187
187
|
}, import("zod/v4/core").$loose>, import("zod/v4").ZodObject<{
|
|
188
188
|
key: import("zod/v4").ZodUnion<readonly [import("zod/v4").ZodString, import("zod/v4").ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>]>;
|
|
189
189
|
passphrase: import("zod/v4").ZodString;
|
|
190
|
-
}, import("zod/v4/core").$strip>]
|
|
191
|
-
type: import("zod/v4").ZodString;
|
|
192
|
-
}, import("zod/v4/core").$loose>, import("zod/v4").ZodObject<{
|
|
193
|
-
key: import("zod/v4").ZodUnion<readonly [import("zod/v4").ZodString, import("zod/v4").ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>]>;
|
|
194
|
-
passphrase: import("zod/v4").ZodString;
|
|
195
|
-
}, import("zod/v4/core").$strip>]>>]>>>;
|
|
190
|
+
}, import("zod/v4/core").$strip>]>>>;
|
|
196
191
|
}, import("zod/v4/core").$strip>, true>;
|
|
197
192
|
/**
|
|
198
193
|
* Service for signing, verifying, and decoding JSON Web Tokens (JWTs).
|
|
@@ -240,7 +235,6 @@ export declare class JwtService {
|
|
|
240
235
|
* @param payload - The payload to sign. Can be a string, Buffer, or object.
|
|
241
236
|
* @param options - Signing options. When payload is a string, only `secret` and `privateKey` are allowed.
|
|
242
237
|
* @returns The signed JWT token as a string
|
|
243
|
-
* @throws {Error} If `secretOrKeyProvider` returns a Promise (use `signAsync` instead)
|
|
244
238
|
* @throws {Error} If payload is a string and invalid options are provided
|
|
245
239
|
*
|
|
246
240
|
* @example
|
|
@@ -267,8 +261,7 @@ export declare class JwtService {
|
|
|
267
261
|
/**
|
|
268
262
|
* Signs a JWT payload asynchronously.
|
|
269
263
|
*
|
|
270
|
-
*
|
|
271
|
-
* to handle async key resolution. Supports the same payload types and options as `sign()`.
|
|
264
|
+
* Supports the same payload types and options as `sign()`.
|
|
272
265
|
*
|
|
273
266
|
* @param payload - The payload to sign. Can be a string, Buffer, or object.
|
|
274
267
|
* @param options - Signing options. When payload is a string, only `secret` and `privateKey` are allowed.
|
|
@@ -277,7 +270,6 @@ export declare class JwtService {
|
|
|
277
270
|
*
|
|
278
271
|
* @example
|
|
279
272
|
* ```ts
|
|
280
|
-
* // Sign with async key provider
|
|
281
273
|
* const token = await jwtService.signAsync(
|
|
282
274
|
* { userId: '123' },
|
|
283
275
|
* { expiresIn: '1h' }
|
|
@@ -306,7 +298,6 @@ export declare class JwtService {
|
|
|
306
298
|
* @throws {TokenExpiredError} If the token has expired
|
|
307
299
|
* @throws {NotBeforeError} If the token is not yet valid (nbf claim)
|
|
308
300
|
* @throws {JsonWebTokenError} If the token is invalid or malformed
|
|
309
|
-
* @throws {Error} If `secretOrKeyProvider` returns a Promise (use `verifyAsync` instead)
|
|
310
301
|
*
|
|
311
302
|
* @example
|
|
312
303
|
* ```ts
|
|
@@ -324,8 +315,7 @@ export declare class JwtService {
|
|
|
324
315
|
/**
|
|
325
316
|
* Verifies and decodes a JWT token asynchronously.
|
|
326
317
|
*
|
|
327
|
-
*
|
|
328
|
-
* to handle async key resolution. Provides the same validation as `verify()`.
|
|
318
|
+
* Provides the same validation as `verify()`.
|
|
329
319
|
*
|
|
330
320
|
* @template T - The expected type of the decoded payload
|
|
331
321
|
* @param token - The JWT token string to verify
|
|
@@ -370,6 +360,8 @@ export declare class JwtService {
|
|
|
370
360
|
* ```
|
|
371
361
|
*/
|
|
372
362
|
decode<T = any>(token: string, options?: jwt.DecodeOptions): T;
|
|
363
|
+
private prepareSign;
|
|
364
|
+
private prepareVerify;
|
|
373
365
|
private mergeJwtOptions;
|
|
374
366
|
private getSecretKey;
|
|
375
367
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.service.d.mts","sourceRoot":"","sources":["../../src/jwt.service.mts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,cAAc,EAAU,MAAM,cAAc,CAAA;AAEzE,OAAO,GAAG,MAAM,cAAc,CAAA;AAE9B,OAAO,KAAK,EAEV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,WAAW,EAEZ,MAAM,mCAAmC,CAAA;AAE1C,OAAO,EAEL,WAAW,EACZ,MAAM,mCAAmC,CAAA;AAE1C;;;;GAIG;AACH,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"jwt.service.d.mts","sourceRoot":"","sources":["../../src/jwt.service.mts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,cAAc,EAAU,MAAM,cAAc,CAAA;AAEzE,OAAO,GAAG,MAAM,cAAc,CAAA;AAE9B,OAAO,KAAK,EAEV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,WAAW,EAEZ,MAAM,mCAAmC,CAAA;AAE1C,OAAO,EAEL,WAAW,EACZ,MAAM,mCAAmC,CAAA;AAE1C;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAG3B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAGa,UAAU;IAUT,OAAO,CAAC,QAAQ,CAAC,OAAO;IATpC,MAAM,wCAEJ;IAEF;;;;OAIG;gBAC0B,OAAO,GAAE,iBAAsB;IAE5D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,IAAI,CACF,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,WAAW,CAAC,GAChD,MAAM;IACT;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM;IAShE;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CACP,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,WAAW,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAa9E;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG,EAC3B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAqB,GAC7B,CAAC;IAMJ;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,CAAC,CAAC;IAUb;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,aAAa,GAAG,CAAC;IAI9D,OAAO,CAAC,WAAW;IA8BnB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,YAAY;CAkBrB"}
|
|
@@ -369,17 +369,12 @@ export declare const JwtServiceOptionsSchema: z.ZodObject<{
|
|
|
369
369
|
subject: z.ZodOptional<z.ZodString>;
|
|
370
370
|
maxAge: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
371
371
|
allowInvalidAsymmetricKeyTypes: z.ZodOptional<z.ZodBoolean>;
|
|
372
|
-
}, z.core.$strip>]>>], null>, z.ZodUnion<readonly [z.
|
|
372
|
+
}, z.core.$strip>]>>], null>, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, z.ZodObject<{
|
|
373
373
|
type: z.ZodString;
|
|
374
374
|
}, z.core.$loose>, z.ZodObject<{
|
|
375
375
|
key: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>]>;
|
|
376
376
|
passphrase: z.ZodString;
|
|
377
|
-
}, z.core.$strip>]
|
|
378
|
-
type: z.ZodString;
|
|
379
|
-
}, z.core.$loose>, z.ZodObject<{
|
|
380
|
-
key: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>]>;
|
|
381
|
-
passphrase: z.ZodString;
|
|
382
|
-
}, z.core.$strip>]>>]>>>;
|
|
377
|
+
}, z.core.$strip>]>>>;
|
|
383
378
|
}, z.core.$strip>;
|
|
384
379
|
/**
|
|
385
380
|
* Configuration options for the JWT service.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-service.options.d.mts","sourceRoot":"","sources":["../../../src/options/jwt-service.options.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B;;;;;GAKG;AACH,oBAAY,WAAW;IACrB,qCAAqC;IACrC,IAAI,SAAS;IACb,uCAAuC;IACvC,MAAM,WAAW;CAClB;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;EAcxB,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;iBAW1B,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqB5B,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoB9B,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;mBAYvB,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEjD,eAAO,MAAM,uBAAuB
|
|
1
|
+
{"version":3,"file":"jwt-service.options.d.mts","sourceRoot":"","sources":["../../../src/options/jwt-service.options.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B;;;;;GAKG;AACH,oBAAY,WAAW;IACrB,qCAAqC;IACrC,IAAI,SAAS;IACb,uCAAuC;IACvC,MAAM,WAAW;CAClB;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;EAcxB,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;iBAW1B,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqB5B,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoB9B,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;mBAYvB,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEjD,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgBlC,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEvE;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA"}
|