@thunderid/javascript 1.11.0 → 1.12.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/dist/api/auth/executeEmbeddedSelfFlow.d.ts +57 -0
- package/dist/api/auth/executeEmbeddedSelfFlow.d.ts.map +1 -0
- package/dist/cjs/index.cjs +355 -5
- package/dist/constants/AttributeVerificationConstants.d.ts +13 -0
- package/dist/constants/AttributeVerificationConstants.d.ts.map +1 -0
- package/dist/edge/index.js +349 -6
- package/dist/i18n/models/i18n.d.ts +14 -0
- package/dist/i18n/models/i18n.d.ts.map +1 -1
- package/dist/i18n/translations/en-US.d.ts.map +1 -1
- package/dist/i18n/translations/fr-FR.d.ts.map +1 -1
- package/dist/i18n/translations/hi-IN.d.ts.map +1 -1
- package/dist/i18n/translations/ja-JP.d.ts.map +1 -1
- package/dist/i18n/translations/pt-BR.d.ts.map +1 -1
- package/dist/i18n/translations/pt-PT.d.ts.map +1 -1
- package/dist/i18n/translations/si-LK.d.ts.map +1 -1
- package/dist/i18n/translations/ta-IN.d.ts.map +1 -1
- package/dist/i18n/translations/te-IN.d.ts.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +349 -6
- package/dist/models/embedded-flow.d.ts +3 -0
- package/dist/models/embedded-flow.d.ts.map +1 -1
- package/dist/models/embedded-self-flow.d.ts +75 -0
- package/dist/models/embedded-self-flow.d.ts.map +1 -0
- package/dist/models/extensions/components.d.ts +1 -1
- package/dist/models/extensions/components.d.ts.map +1 -1
- package/dist/models/user.d.ts +9 -0
- package/dist/models/user.d.ts.map +1 -1
- package/dist/utils/getFlowStepComponents.d.ts +26 -0
- package/dist/utils/getFlowStepComponents.d.ts.map +1 -0
- package/dist/utils/getVerifiedAttributes.d.ts +14 -0
- package/dist/utils/getVerifiedAttributes.d.ts.map +1 -0
- package/dist/utils/isVerifiableAttribute.d.ts +22 -0
- package/dist/utils/isVerifiableAttribute.d.ts.map +1 -0
- package/dist/utils/parseSelfFlowRequest.d.ts +24 -0
- package/dist/utils/parseSelfFlowRequest.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { EmbeddedFlowComponent, EmbeddedFlowResponseData, EmbeddedFlowResponseType, EmbeddedFlowType, FlowExecutionError } from './embedded-flow';
|
|
2
|
+
/**
|
|
3
|
+
* Status of a `SELF` flow step.
|
|
4
|
+
*
|
|
5
|
+
* @experimental Part of the new ThunderID API
|
|
6
|
+
*/
|
|
7
|
+
export declare enum EmbeddedSelfFlowStatus {
|
|
8
|
+
/**
|
|
9
|
+
* The flow completed, for example a verification was recorded.
|
|
10
|
+
*/
|
|
11
|
+
Complete = "COMPLETE",
|
|
12
|
+
/**
|
|
13
|
+
* The server refused the operation.
|
|
14
|
+
*/
|
|
15
|
+
Error = "ERROR",
|
|
16
|
+
/**
|
|
17
|
+
* The flow needs more input, such as the emailed code.
|
|
18
|
+
*/
|
|
19
|
+
Incomplete = "INCOMPLETE"
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Response of a `SELF` flow.
|
|
23
|
+
*
|
|
24
|
+
* @experimental Part of the new ThunderID API
|
|
25
|
+
*/
|
|
26
|
+
export interface EmbeddedSelfFlowResponse {
|
|
27
|
+
/**
|
|
28
|
+
* Per-step challenge token, sent back on the next request when present.
|
|
29
|
+
*/
|
|
30
|
+
challengeToken?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Step data. In self attribute verification, `additionalData.maskedDestination` names where the code was sent.
|
|
33
|
+
*/
|
|
34
|
+
data?: EmbeddedFlowResponseData & {
|
|
35
|
+
components?: EmbeddedFlowComponent[];
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Structured error details when `flowStatus` is `ERROR`, or when a code was rejected.
|
|
39
|
+
*/
|
|
40
|
+
error?: FlowExecutionError;
|
|
41
|
+
/**
|
|
42
|
+
* Identifier of this flow execution.
|
|
43
|
+
*/
|
|
44
|
+
executionId: string;
|
|
45
|
+
/**
|
|
46
|
+
* Current status of the flow.
|
|
47
|
+
*/
|
|
48
|
+
flowStatus: EmbeddedSelfFlowStatus;
|
|
49
|
+
/**
|
|
50
|
+
* Type of the step.
|
|
51
|
+
*/
|
|
52
|
+
type?: EmbeddedFlowResponseType;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Request that starts or continues a `SELF` flow.
|
|
56
|
+
*
|
|
57
|
+
* @experimental Part of the new ThunderID API
|
|
58
|
+
*/
|
|
59
|
+
export interface EmbeddedSelfFlowRequest {
|
|
60
|
+
action?: string;
|
|
61
|
+
challengeToken?: string;
|
|
62
|
+
executionId?: string;
|
|
63
|
+
flowType?: EmbeddedFlowType.Self;
|
|
64
|
+
/**
|
|
65
|
+
* Handle of the `SELF` flow to start, such as `default-self-attribute-verification-flow`.
|
|
66
|
+
* Required on the request that starts a flow.
|
|
67
|
+
*/
|
|
68
|
+
handle?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Inputs of the step, such as `{attribute: 'email'}` on the request that starts self attribute
|
|
71
|
+
* verification.
|
|
72
|
+
*/
|
|
73
|
+
inputs?: Record<string, string>;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=embedded-self-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedded-self-flow.d.ts","sourceRoot":"","sources":["../../src/models/embedded-self-flow.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAEzB;;;;GAIG;AACH,oBAAY,sBAAsB;IAChC;;OAEG;IACH,QAAQ,aAAa;IAErB;;OAEG;IACH,KAAK,UAAU;IAEf;;OAEG;IACH,UAAU,eAAe;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,IAAI,CAAC,EAAE,wBAAwB,GAAG;QAAC,UAAU,CAAC,EAAE,qBAAqB,EAAE,CAAA;KAAC,CAAC;IAEzE;;OAEG;IACH,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAE3B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,sBAAsB,CAAC;IAEnC;;OAEG;IACH,IAAI,CAAC,EAAE,wBAAwB,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC,IAAI,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC"}
|
|
@@ -6,7 +6,7 @@ import { FlowMetadataResponse } from '../flow-meta';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface ComponentRenderContext {
|
|
8
8
|
additionalData?: Record<string, any>;
|
|
9
|
-
authType: 'signin' | 'signup' | 'recovery';
|
|
9
|
+
authType: 'signin' | 'signup' | 'recovery' | 'verification';
|
|
10
10
|
formErrors: Record<string, string>;
|
|
11
11
|
formValues: Record<string, string>;
|
|
12
12
|
isFormValid: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/models/extensions/components.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/models/extensions/components.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,cAAc,CAAC;IAC5D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,qBAAqB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5G,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC;AAE/G;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC"}
|
package/dist/models/user.d.ts
CHANGED
|
@@ -12,4 +12,13 @@ export interface UserProfile {
|
|
|
12
12
|
flattenedProfile: User;
|
|
13
13
|
profile: User;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Verification record of one of the user's attributes, as returned in `/users/me`.
|
|
17
|
+
*/
|
|
18
|
+
export interface VerifiedAttribute {
|
|
19
|
+
/**
|
|
20
|
+
* When the attribute's current value was verified, as an RFC 3339 timestamp.
|
|
21
|
+
*/
|
|
22
|
+
verifiedAt: string;
|
|
23
|
+
}
|
|
15
24
|
//# sourceMappingURL=user.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/models/user.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,IAAK,SAAQ,SAAS;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,IAAI,CAAC;IACvB,OAAO,EAAE,IAAI,CAAC;CACf"}
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/models/user.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,IAAK,SAAQ,SAAS;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,IAAI,CAAC;IACvB,OAAO,EAAE,IAAI,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EmbeddedFlowComponent } from '../models/embedded-flow';
|
|
2
|
+
/**
|
|
3
|
+
* The components of a flow step that collect a value or submit the step.
|
|
4
|
+
*/
|
|
5
|
+
export interface FlowStepComponents {
|
|
6
|
+
/** Components that submit the step, the resend action included. */
|
|
7
|
+
actions: EmbeddedFlowComponent[];
|
|
8
|
+
/** Components that collect a value. */
|
|
9
|
+
inputs: EmbeddedFlowComponent[];
|
|
10
|
+
/** The step's resend action, if it has one. */
|
|
11
|
+
resend?: EmbeddedFlowComponent;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Collects the inputs and actions of a flow step, nested components included, in document order.
|
|
15
|
+
*
|
|
16
|
+
* @param components - The step's components.
|
|
17
|
+
* @returns The step's inputs, actions and resend action.
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const {actions, inputs} = getFlowStepComponents(response.data.components);
|
|
21
|
+
* const isAwaitingLink = inputs.length === 0 && actions.length === 0;
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
declare const getFlowStepComponents: (components: EmbeddedFlowComponent[], step?: FlowStepComponents) => FlowStepComponents;
|
|
25
|
+
export default getFlowStepComponents;
|
|
26
|
+
//# sourceMappingURL=getFlowStepComponents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getFlowStepComponents.d.ts","sourceRoot":"","sources":["../../src/utils/getFlowStepComponents.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,qBAAqB,EAA4B,MAAM,yBAAyB,CAAC;AAgBzF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,uCAAuC;IACvC,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,+CAA+C;IAC/C,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,QAAA,MAAM,qBAAqB,GACzB,YAAY,qBAAqB,EAAE,EACnC,OAAM,kBAA8C,KACnD,kBAQF,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { User, VerifiedAttribute } from '../models/user';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the verified attributes of a `/users/me` profile, keyed by attribute name.
|
|
4
|
+
*
|
|
5
|
+
* A profile without the field, from a server that does not report verification, leaves every status
|
|
6
|
+
* unknown, so the result is `undefined` rather than an empty record that would read as unverified.
|
|
7
|
+
*
|
|
8
|
+
* @param user - The profile to read.
|
|
9
|
+
* @returns The verified attributes, an empty object when none is verified, or `undefined` when the
|
|
10
|
+
* profile does not report them.
|
|
11
|
+
*/
|
|
12
|
+
declare const getVerifiedAttributes: (user?: User | null) => Record<string, VerifiedAttribute> | undefined;
|
|
13
|
+
export default getVerifiedAttributes;
|
|
14
|
+
//# sourceMappingURL=getVerifiedAttributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getVerifiedAttributes.d.ts","sourceRoot":"","sources":["../../src/utils/getVerifiedAttributes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,IAAI,EAAE,iBAAiB,EAAC,MAAM,gBAAgB,CAAC;AAEvD;;;;;;;;;GASG;AACH,QAAA,MAAM,qBAAqB,GAAI,OAAO,IAAI,GAAG,IAAI,KAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,SAMvF,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AttributeSchema } from '../api/account/getUsersMeMeta';
|
|
2
|
+
/**
|
|
3
|
+
* Whether the signed-in user can verify the given attribute: a top-level, single-valued property of
|
|
4
|
+
* type `email` or `mobile` in the user type schema from `GET /users/me/meta`.
|
|
5
|
+
*
|
|
6
|
+
* Schema keys are top-level properties, and a multi-valued property has type `array`, so both are
|
|
7
|
+
* settled by the property's own type. An absent schema, or one without the attribute, leaves the
|
|
8
|
+
* type unknown and resolves to `false`, so no verification is started on missing information.
|
|
9
|
+
*
|
|
10
|
+
* @param userSchema - The user type schema resolved by the provider, keyed by attribute.
|
|
11
|
+
* @param attribute - The attribute to check (e.g. `email`).
|
|
12
|
+
* @returns `true` only when the schema declares `attribute` with a verifiable type.
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* if (!isVerifiableAttribute(userSchema, 'given_name')) {
|
|
16
|
+
* return null;
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare const isVerifiableAttribute: (userSchema: Record<string, AttributeSchema> | null | undefined, attribute: string) => boolean;
|
|
21
|
+
export default isVerifiableAttribute;
|
|
22
|
+
//# sourceMappingURL=isVerifiableAttribute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isVerifiableAttribute.d.ts","sourceRoot":"","sources":["../../src/utils/isVerifiableAttribute.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAG9D;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,qBAAqB,GACzB,YAAY,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI,GAAG,SAAS,EAC9D,WAAW,MAAM,KAChB,OAUF,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EmbeddedSelfFlowRequest } from '../models/embedded-self-flow';
|
|
2
|
+
/**
|
|
3
|
+
* Result of {@link parseSelfFlowRequest}: the request to send, or the field that made it invalid.
|
|
4
|
+
*/
|
|
5
|
+
export type SelfFlowRequestParseResult = {
|
|
6
|
+
invalid: string;
|
|
7
|
+
} | {
|
|
8
|
+
request: EmbeddedSelfFlowRequest;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Checks a `SELF` flow step that a browser sent to a server-side SDK, which attaches the
|
|
12
|
+
* session's access token before forwarding it. Such an endpoint is public, so its types protect
|
|
13
|
+
* nothing.
|
|
14
|
+
*
|
|
15
|
+
* Only the fields of a step are kept, so a caller cannot add a user or application identifier. A
|
|
16
|
+
* request without an `executionId` starts a flow, and must name a `SELF` flow by its handle,
|
|
17
|
+
* so the endpoint cannot start a flow of another type with the user's token.
|
|
18
|
+
*
|
|
19
|
+
* @param raw - The request body as received.
|
|
20
|
+
* @returns The request to send, or the name of the first invalid field.
|
|
21
|
+
*/
|
|
22
|
+
declare const parseSelfFlowRequest: (raw: unknown) => SelfFlowRequestParseResult;
|
|
23
|
+
export default parseSelfFlowRequest;
|
|
24
|
+
//# sourceMappingURL=parseSelfFlowRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseSelfFlowRequest.d.ts","sourceRoot":"","sources":["../../src/utils/parseSelfFlowRequest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAAG;IAAC,OAAO,EAAE,uBAAuB,CAAA;CAAC,CAAC;AAUhG;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,oBAAoB,GAAI,KAAK,OAAO,KAAG,0BA8B5C,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|