@tiledev/sdk-shopify 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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +269 -0
  3. package/dist/blogs.d.ts +3 -0
  4. package/dist/blogs.d.ts.map +1 -0
  5. package/dist/blogs.js +72 -0
  6. package/dist/blogs.js.map +1 -0
  7. package/dist/cart.d.ts +3 -0
  8. package/dist/cart.d.ts.map +1 -0
  9. package/dist/cart.js +96 -0
  10. package/dist/cart.js.map +1 -0
  11. package/dist/cartPolicy.d.ts +15 -0
  12. package/dist/cartPolicy.d.ts.map +1 -0
  13. package/dist/cartPolicy.js +74 -0
  14. package/dist/cartPolicy.js.map +1 -0
  15. package/dist/client.d.ts +15 -0
  16. package/dist/client.d.ts.map +1 -0
  17. package/dist/client.js +130 -0
  18. package/dist/client.js.map +1 -0
  19. package/dist/collections.d.ts +3 -0
  20. package/dist/collections.d.ts.map +1 -0
  21. package/dist/collections.js +44 -0
  22. package/dist/collections.js.map +1 -0
  23. package/dist/customer.d.ts +3 -0
  24. package/dist/customer.d.ts.map +1 -0
  25. package/dist/customer.js +124 -0
  26. package/dist/customer.js.map +1 -0
  27. package/dist/errors.d.ts +19 -0
  28. package/dist/errors.d.ts.map +1 -0
  29. package/dist/errors.js +63 -0
  30. package/dist/errors.js.map +1 -0
  31. package/dist/index.d.ts +11 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +56 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/messages.d.ts +24 -0
  36. package/dist/messages.d.ts.map +1 -0
  37. package/dist/messages.js +81 -0
  38. package/dist/messages.js.map +1 -0
  39. package/dist/money.d.ts +18 -0
  40. package/dist/money.d.ts.map +1 -0
  41. package/dist/money.js +93 -0
  42. package/dist/money.js.map +1 -0
  43. package/dist/products.d.ts +6 -0
  44. package/dist/products.d.ts.map +1 -0
  45. package/dist/products.js +193 -0
  46. package/dist/products.js.map +1 -0
  47. package/dist/queries.d.ts +55 -0
  48. package/dist/queries.d.ts.map +1 -0
  49. package/dist/queries.js +582 -0
  50. package/dist/queries.js.map +1 -0
  51. package/dist/react/ShopifyProvider.d.ts +181 -0
  52. package/dist/react/ShopifyProvider.d.ts.map +1 -0
  53. package/dist/react/ShopifyProvider.js +785 -0
  54. package/dist/react/ShopifyProvider.js.map +1 -0
  55. package/dist/react/index.d.ts +3 -0
  56. package/dist/react/index.d.ts.map +1 -0
  57. package/dist/react/index.js +14 -0
  58. package/dist/react/index.js.map +1 -0
  59. package/dist/react/useTileCredit.d.ts +34 -0
  60. package/dist/react/useTileCredit.d.ts.map +1 -0
  61. package/dist/react/useTileCredit.js +96 -0
  62. package/dist/react/useTileCredit.js.map +1 -0
  63. package/dist/shopify.d.ts +3 -0
  64. package/dist/shopify.d.ts.map +1 -0
  65. package/dist/shopify.js +54 -0
  66. package/dist/shopify.js.map +1 -0
  67. package/dist/tileCredit.d.ts +64 -0
  68. package/dist/tileCredit.d.ts.map +1 -0
  69. package/dist/tileCredit.js +274 -0
  70. package/dist/tileCredit.js.map +1 -0
  71. package/dist/types.d.ts +785 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +25 -0
  74. package/dist/types.js.map +1 -0
  75. package/dist/variants.d.ts +3 -0
  76. package/dist/variants.d.ts.map +1 -0
  77. package/dist/variants.js +67 -0
  78. package/dist/variants.js.map +1 -0
  79. package/dist/wishlist.d.ts +4 -0
  80. package/dist/wishlist.d.ts.map +1 -0
  81. package/dist/wishlist.js +232 -0
  82. package/dist/wishlist.js.map +1 -0
  83. package/package.json +63 -0
  84. package/react/package.json +6 -0
@@ -0,0 +1,181 @@
1
+ import { ReactNode } from "react";
2
+ import type { AlertMessageKey, AlertMessages, Cart, CartLineAttribute, CartLineGuard, CartLineInput, CartPolicy, CartWriteResult, Customer, MessageResolver, Product, ShopifyConfig, WishlistItem, WishlistStorageAdapter } from "../types";
3
+ interface CartState {
4
+ cart: Cart | null;
5
+ loading: boolean;
6
+ itemCount: number;
7
+ /** Distinct lines, which is what `maxLineItems` limits — not `itemCount`. */
8
+ lineCount: number;
9
+ /** The configured `maxLineItems`, or `null` when unlimited. */
10
+ maxLineItems: number | null;
11
+ /**
12
+ * `ok: false` means nothing was written: a `cartGuard` veto (`reason: 'guard'`) or the
13
+ * line limit (`reason: 'limit'`, with the configured message). Shopify refusing the
14
+ * line still throws — an unsellable one emits `cart:outOfStock` on the way out.
15
+ */
16
+ addLine: (input: CartLineInput) => Promise<CartWriteResult>;
17
+ /**
18
+ * Returns the resulting cart, `null` when nothing landed. One unsellable line fails the whole
19
+ * `cartLinesAdd`, so a rejected batch is retried line by line and the successes are kept.
20
+ */
21
+ addLines: (inputs: CartLineInput[]) => Promise<Cart | null>;
22
+ /**
23
+ * `false` when a `cartGuard` cancelled the increase. `attributes` REPLACE the line's set —
24
+ * Shopify does not merge them — so omit the argument to leave them untouched.
25
+ */
26
+ updateLine: (lineId: string, quantity: number, attributes?: CartLineAttribute[]) => Promise<boolean>;
27
+ removeLine: (lineId: string) => Promise<void>;
28
+ applyDiscountCodes: (codes: string[]) => Promise<void>;
29
+ /**
30
+ * Attributes the order to a buyer and opens checkout signed in. `false` when there is no cart
31
+ * yet. New customer accounts pass their Customer Account API token straight through.
32
+ */
33
+ setBuyerIdentity: (identity: {
34
+ email?: string;
35
+ countryCode?: string;
36
+ customerAccessToken?: string;
37
+ }) => Promise<boolean>;
38
+ /** Re-reads the cart and returns it, so a caller need not wait for the re-render. */
39
+ refresh: () => Promise<Cart | null>;
40
+ /**
41
+ * Switches to a cart handed over from elsewhere — another device, a support agent, the web store.
42
+ * A read and a swap, not a mutation: nothing is written to either cart. Null when that id no
43
+ * longer resolves, in which case the current cart is left alone.
44
+ */
45
+ adopt: (cartId: string) => Promise<Cart | null>;
46
+ reset: () => Promise<void>;
47
+ }
48
+ interface WishlistState {
49
+ items: WishlistItem[];
50
+ count: number;
51
+ has: (productId: string) => boolean;
52
+ /** Alias for `has`. */
53
+ isWishlisted: (productId: string) => boolean;
54
+ add: (product: Product | string) => Promise<void>;
55
+ remove: (productId: string) => Promise<void>;
56
+ toggle: (product: Product | string) => Promise<boolean>;
57
+ clear: () => Promise<void>;
58
+ refresh: () => Promise<void>;
59
+ }
60
+ /**
61
+ * The customer session, so the four Login alerts have somewhere to originate.
62
+ * `shopify.customer.*` stays available for everything else; this owns only what
63
+ * a session needs — the token, who it belongs to, and the events.
64
+ */
65
+ interface CustomerState {
66
+ customer: Customer | null;
67
+ /** True once a stored token has been exchanged for a profile. */
68
+ loggedIn: boolean;
69
+ /** The stored access token, for callers that need it (Tile Credit, checkout). */
70
+ accessToken: string | null;
71
+ loading: boolean;
72
+ /** Restoring a stored token on mount — distinct from "logged out". */
73
+ restoring: boolean;
74
+ /** `false` on bad credentials, which emits `auth:loginFailed`. Everything else throws. */
75
+ login: (email: string, password: string) => Promise<boolean>;
76
+ signup: (input: {
77
+ email: string;
78
+ password: string;
79
+ firstName?: string;
80
+ lastName?: string;
81
+ acceptsMarketing?: boolean;
82
+ }) => Promise<boolean>;
83
+ /** Always resolves — Shopify refusing the token delete still ends the local session. */
84
+ logout: () => Promise<void>;
85
+ /** Emits `auth:recoverSent`. Shopify does not reveal whether the email exists. */
86
+ recoverPassword: (email: string) => Promise<void>;
87
+ /** Re-reads the profile for the stored token. Null if the token no longer resolves. */
88
+ refresh: () => Promise<Customer | null>;
89
+ }
90
+ /**
91
+ * Checkout is Shopify-hosted, so the SDK cannot see the outcome itself. The host
92
+ * webview reports it here and gets the configured copy on the event, rather than
93
+ * every app hard-coding "Your order has been placed".
94
+ *
95
+ * A `checkout.observe(url)` helper that classifies the return URL is the next
96
+ * piece of work; this is the seam it will emit through.
97
+ */
98
+ interface CheckoutState {
99
+ /** Emits `checkout:orderPlaced`, then resets the cart so the next visit starts clean. */
100
+ reportOrderPlaced: (details?: {
101
+ orderId?: string;
102
+ orderNumber?: string | number;
103
+ }) => Promise<void>;
104
+ /** Emits `checkout:paymentFailed`. Leaves the cart alone so the shopper can retry. */
105
+ reportPaymentFailed: (error?: unknown) => void;
106
+ }
107
+ interface ShopifyContextType {
108
+ ready: boolean;
109
+ error: string | null;
110
+ cart: CartState;
111
+ wishlist: WishlistState;
112
+ customer: CustomerState;
113
+ checkout: CheckoutState;
114
+ /** Resolved alert copy, for labelling UI that isn't a toast — e.g. the
115
+ * empty-wishlist placeholder (`wishlist.empty`), which has no event. */
116
+ message: (key: AlertMessageKey) => string;
117
+ }
118
+ /**
119
+ * Everything the host may want to tell the shopper about. One event per alert the
120
+ * editor's Settings panel configures, plus the writes that carry no copy of their own.
121
+ *
122
+ * Failures are events too — a "Payment failed" or "Out of stock" toast needs a
123
+ * signal as much as a success does, and wrapping every call in try/catch to find
124
+ * out is what this replaces. Errors still throw for callers that want them.
125
+ */
126
+ export type ShopifyEventType = "cart:add" | "cart:update" | "cart:remove" | "cart:limitExceeded" | "cart:outOfStock" | "cart:buyerIdentity" | "wishlist:add" | "wishlist:remove" | "auth:loginSuccess" | "auth:loginFailed" | "auth:signup" | "auth:logout" | "auth:recoverSent" | "checkout:orderPlaced" | "checkout:paymentFailed";
127
+ export interface ShopifyEvent {
128
+ type: ShopifyEventType;
129
+ /** How to present it — a toast tone, not a log level. */
130
+ severity: "success" | "error" | "info";
131
+ /**
132
+ * Resolved copy for this event, already through the Settings panel → i18n →
133
+ * default chain. Absent for the events that have no configurable message
134
+ * (`cart:update`, `cart:buyerIdentity`), which are state signals, not alerts.
135
+ */
136
+ message?: string;
137
+ /** Which panel field `message` came from, for hosts that key off it. */
138
+ messageKey?: AlertMessageKey;
139
+ /** Present on failures. `ShopifyError.errors` carries the Shopify codes. */
140
+ error?: unknown;
141
+ }
142
+ export interface ShopifyProviderProps {
143
+ children: ReactNode;
144
+ config: ShopifyConfig;
145
+ /**
146
+ * Backs the cart id, the customer session and the wishlist. Defaults to
147
+ * `window.localStorage`; React Native and Node consumers pass an
148
+ * AsyncStorage-compatible adapter.
149
+ */
150
+ storage?: WishlistStorageAdapter;
151
+ onEvent?: (event: ShopifyEvent) => void;
152
+ /** Vets cart writes — see `CartLineGuard`. On the provider so no screen can bypass it. */
153
+ cartGuard?: CartLineGuard;
154
+ /** See `WishlistInitOptions.keepDeleted`. Recommended for a shopper-facing wishlist. */
155
+ wishlistKeepDeleted?: boolean;
156
+ /**
157
+ * Alert copy, outside `config` so a Live Layer publish can change it without
158
+ * re-running `init` (which would re-load the shop and re-create the cart).
159
+ * Merged over `config.messages`; re-applied whenever this object changes.
160
+ */
161
+ messages?: AlertMessages;
162
+ /** i18n resolver for keys `messages` does not set. Same reason as above. */
163
+ translate?: MessageResolver;
164
+ /** Cart rules. Live-updatable for the same reason. */
165
+ cartPolicy?: CartPolicy;
166
+ }
167
+ export declare function ShopifyProvider({ children, config, storage, onEvent, cartGuard, wishlistKeepDeleted, messages, translate, cartPolicy, }: ShopifyProviderProps): import("react").JSX.Element;
168
+ export declare function useShopify(): ShopifyContextType;
169
+ export declare function useCart(): CartState;
170
+ export declare function useWishlist(): WishlistState;
171
+ /** Customer session — the source of the four Login alerts. */
172
+ export declare function useCustomer(): CustomerState;
173
+ /** Reports a hosted-checkout outcome so the two Checkout alerts can fire. */
174
+ export declare function useCheckout(): CheckoutState;
175
+ /**
176
+ * Resolved alert copy, for UI that isn't a toast — the empty-wishlist
177
+ * placeholder (`wishlist.empty`) is configurable but has no event.
178
+ */
179
+ export declare function useShopifyMessage(): (key: AlertMessageKey) => string;
180
+ export type { CartState, WishlistState, CustomerState, CheckoutState };
181
+ //# sourceMappingURL=ShopifyProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShopifyProvider.d.ts","sourceRoot":"","sources":["../../src/react/ShopifyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EAOV,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,IAAI,EAEJ,iBAAiB,EACjB,aAAa,EACb,aAAa,EAEb,UAAU,EACV,eAAe,EACf,QAAQ,EAER,eAAe,EACf,OAAO,EACP,aAAa,EACb,YAAY,EACZ,sBAAsB,EACvB,MAAM,UAAU,CAAC;AA4BlB,UAAU,SAAS;IACjB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;OAIG;IACH,OAAO,EAAa,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACvE;;;OAGG;IACH,QAAQ,EAAY,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACtE;;;OAGG;IACH,UAAU,EAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7G,UAAU,EAAU,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;OAGG;IACH,gBAAgB,EAAE,CAAC,QAAQ,EAAE;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,qFAAqF;IACrF,OAAO,EAAa,MAAM,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC/C;;;;OAIG;IACH,KAAK,EAAe,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC7D,KAAK,EAAe,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAED,UAAU,aAAa;IACrB,KAAK,EAAS,YAAY,EAAE,CAAC;IAC7B,KAAK,EAAS,MAAM,CAAC;IACrB,GAAG,EAAW,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,uBAAuB;IACvB,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,GAAG,EAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,EAAQ,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,EAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,KAAK,EAAS,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO,EAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,UAAU,aAAa;IACrB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,EAAE,OAAO,CAAC;IAClB,iFAAiF;IACjF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB,0FAA0F;IAC1F,KAAK,EAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,EAAE,CAAC,KAAK,EAAE;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,wFAAwF;IACxF,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,kFAAkF;IAClF,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,uFAAuF;IACvF,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,UAAU,aAAa;IACrB,yFAAyF;IACzF,iBAAiB,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpG,sFAAsF;IACtF,mBAAmB,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAK,OAAO,CAAC;IAClB,KAAK,EAAK,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAM,SAAS,CAAC;IACpB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB;6EACyE;IACzE,OAAO,EAAG,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAAC;CAC5C;AAOD;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,aAAa,GACb,aAAa,GACb,oBAAoB,GACpB,iBAAiB,GACjB,oBAAoB,GACpB,cAAc,GACd,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,GAClB,aAAa,GACb,aAAa,GACb,kBAAkB,GAClB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,yDAAyD;IACzD,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACvC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAyBD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,0FAA0F;IAC1F,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,sDAAsD;IACtD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AASD,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,SAAS,EACT,UAAU,GACX,EAAE,oBAAoB,+BAwsBtB;AAED,wBAAgB,UAAU,IAAI,kBAAkB,CAI/C;AAED,wBAAgB,OAAO,IAAI,SAAS,CAEnC;AAED,wBAAgB,WAAW,IAAI,aAAa,CAE3C;AAED,8DAA8D;AAC9D,wBAAgB,WAAW,IAAI,aAAa,CAE3C;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,IAAI,aAAa,CAE3C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAEpE;AAED,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}