@burdenoff/microfe-coolandlovely 2026.629.1 → 2026.706.2

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 (66) hide show
  1. package/dist/coolandlovely/CoolAndLovelyRoutes.js +14 -6
  2. package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
  3. package/dist/coolandlovely/components/ActorName.js +29 -0
  4. package/dist/coolandlovely/components/ActorName.js.map +1 -0
  5. package/dist/coolandlovely/components/AddToLookbookButton.js +81 -0
  6. package/dist/coolandlovely/components/AddToLookbookButton.js.map +1 -0
  7. package/dist/coolandlovely/components/Comments.js +109 -0
  8. package/dist/coolandlovely/components/Comments.js.map +1 -0
  9. package/dist/coolandlovely/components/Field.js +22 -2
  10. package/dist/coolandlovely/components/Field.js.map +1 -1
  11. package/dist/coolandlovely/components/FileImage.js +17 -0
  12. package/dist/coolandlovely/components/FileImage.js.map +1 -0
  13. package/dist/coolandlovely/components/FollowButton.js +24 -0
  14. package/dist/coolandlovely/components/FollowButton.js.map +1 -0
  15. package/dist/coolandlovely/components/ImageUploadField.js +71 -0
  16. package/dist/coolandlovely/components/ImageUploadField.js.map +1 -0
  17. package/dist/coolandlovely/components/Thumbnail.js +20 -13
  18. package/dist/coolandlovely/components/Thumbnail.js.map +1 -1
  19. package/dist/coolandlovely/hooks/index.js +2 -0
  20. package/dist/coolandlovely/hooks/useComments.js +68 -0
  21. package/dist/coolandlovely/hooks/useComments.js.map +1 -0
  22. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +219 -148
  23. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
  24. package/dist/coolandlovely/hooks/useFiles.js +94 -0
  25. package/dist/coolandlovely/hooks/useFiles.js.map +1 -0
  26. package/dist/coolandlovely/pages/HomePage.js +105 -87
  27. package/dist/coolandlovely/pages/HomePage.js.map +1 -1
  28. package/dist/coolandlovely/pages/brands/BrandDetailPage.js +144 -122
  29. package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
  30. package/dist/coolandlovely/pages/brands/BrandFormPage.js +129 -91
  31. package/dist/coolandlovely/pages/brands/BrandFormPage.js.map +1 -1
  32. package/dist/coolandlovely/pages/brands/BrandsListPage.js +2 -0
  33. package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
  34. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js +5 -1
  35. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
  36. package/dist/coolandlovely/pages/collections/CollectionFormPage.js +117 -102
  37. package/dist/coolandlovely/pages/collections/CollectionFormPage.js.map +1 -1
  38. package/dist/coolandlovely/pages/collections/CollectionsListPage.js +2 -0
  39. package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
  40. package/dist/coolandlovely/pages/discover/DiscoverPage.js +223 -0
  41. package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -0
  42. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +99 -95
  43. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
  44. package/dist/coolandlovely/pages/items/StyleItemFormPage.js +144 -130
  45. package/dist/coolandlovely/pages/items/StyleItemFormPage.js.map +1 -1
  46. package/dist/coolandlovely/pages/items/StyleItemsListPage.js +2 -0
  47. package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
  48. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +190 -99
  49. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
  50. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js +81 -68
  51. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
  52. package/dist/coolandlovely/pages/looks/LookDetailPage.js +195 -155
  53. package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
  54. package/dist/coolandlovely/pages/looks/LookFormPage.js +127 -88
  55. package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
  56. package/dist/coolandlovely/pages/looks/LooksListPage.js +2 -0
  57. package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
  58. package/dist/coolandlovely/pages/profile/StyleProfilePage.js +169 -101
  59. package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
  60. package/dist/coolandlovely/pages/trends/TrendsPage.js +249 -0
  61. package/dist/coolandlovely/pages/trends/TrendsPage.js.map +1 -0
  62. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js +88 -76
  63. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js.map +1 -1
  64. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +2 -0
  65. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
  66. package/package.json +1 -1
@@ -1,29 +1,36 @@
1
1
  import { cn as e } from "../utils/cn.js";
2
- import { jsx as t } from "react/jsx-runtime";
2
+ import { FileImage as t } from "./FileImage.js";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
3
4
  //#region src/coolandlovely/components/Thumbnail.tsx
4
- var n = [
5
+ var i = [
5
6
  "from-accent-purple-subtle to-bg-sunken",
6
7
  "from-accent-blue-subtle to-bg-sunken",
7
8
  "from-status-success-bg-subtle to-bg-sunken",
8
9
  "from-status-warning-bg-subtle to-bg-sunken",
9
10
  "from-[var(--color-accent-soft)] to-bg-sunken"
10
11
  ];
11
- function r(e) {
12
- if (!e) return n[0];
12
+ function a(e) {
13
+ if (!e) return i[0];
13
14
  let t = 0;
14
15
  for (let n = 0; n < e.length; n += 1) t = (t * 31 + e.charCodeAt(n)) % 997;
15
- return n[t % n.length];
16
+ return i[t % i.length];
16
17
  }
17
- var i = ({ icon: n, seed: i, className: a, label: o }) => /* @__PURE__ */ t("div", {
18
- className: e("relative flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br", r(i), a),
19
- "aria-hidden": o ? void 0 : !0,
20
- "aria-label": o,
21
- children: /* @__PURE__ */ t("span", {
18
+ var o = ({ icon: i, seed: o, className: s, label: c, fileId: l, alt: u }) => /* @__PURE__ */ r("div", {
19
+ className: e("relative flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br", a(o), s),
20
+ "aria-hidden": c ? void 0 : !0,
21
+ "aria-label": c,
22
+ children: [/* @__PURE__ */ n("span", {
22
23
  className: "text-text-secondary opacity-80",
23
- children: n
24
- })
24
+ children: i
25
+ }), l ? /* @__PURE__ */ n("span", {
26
+ className: "absolute inset-0",
27
+ children: /* @__PURE__ */ n(t, {
28
+ fileId: l,
29
+ alt: u ?? c ?? ""
30
+ })
31
+ }) : null]
25
32
  });
26
33
  //#endregion
27
- export { i as Thumbnail };
34
+ export { o as Thumbnail };
28
35
 
29
36
  //# sourceMappingURL=Thumbnail.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Thumbnail.js","names":[],"sources":["../../../src/coolandlovely/components/Thumbnail.tsx"],"sourcesContent":["/**\n * Thumbnail Component\n * @module coolandlovely/components\n *\n * Renders a calm, on-token visual placeholder for a fashion entity. Imagery in\n * CoolAndLovely is referenced from wspace-files-svc via federation (we only\n * have the File id here, not a resolvable URL), so the catalogue/wardrobe/look\n * surfaces render a branded glyph tile keyed by an icon rather than a broken\n * <img>. The seed (entity id) gives each tile a stable accent tint.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface ThumbnailProps {\n icon: ReactNode;\n /** Stable seed (e.g. entity id) used to pick a deterministic accent tint. */\n seed?: string;\n className?: string;\n /** Whether a File reference exists (shows a subtle \"image attached\" hint). */\n hasImage?: boolean;\n label?: string;\n}\n\nconst tints = [\n 'from-accent-purple-subtle to-bg-sunken',\n 'from-accent-blue-subtle to-bg-sunken',\n 'from-status-success-bg-subtle to-bg-sunken',\n 'from-status-warning-bg-subtle to-bg-sunken',\n 'from-[var(--color-accent-soft)] to-bg-sunken',\n];\n\nfunction tintFor(seed: string | undefined): string {\n if (!seed) return tints[0];\n let hash = 0;\n for (let i = 0; i < seed.length; i += 1) {\n hash = (hash * 31 + seed.charCodeAt(i)) % 997;\n }\n return tints[hash % tints.length];\n}\n\nexport const Thumbnail: FC<ThumbnailProps> = ({ icon, seed, className, label }) => {\n return (\n <div\n className={cn(\n 'relative flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br',\n tintFor(seed),\n className\n )}\n aria-hidden={label ? undefined : true}\n aria-label={label}\n >\n <span className=\"text-text-secondary opacity-80\">{icon}</span>\n </div>\n );\n};\n"],"mappings":";;;AAwBA,IAAM,IAAQ;CACZ;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,EAAQ,GAAkC;AACjD,KAAI,CAAC,EAAM,QAAO,EAAM;CACxB,IAAI,IAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,EACpC,MAAQ,IAAO,KAAK,EAAK,WAAW,EAAE,IAAI;AAE5C,QAAO,EAAM,IAAO,EAAM;;AAG5B,IAAa,KAAiC,EAAE,SAAM,SAAM,cAAW,eAEnE,kBAAC,OAAD;CACE,WAAW,EACT,0FACA,EAAQ,EAAK,EACb,EACD;CACD,eAAa,IAAQ,KAAA,IAAY;CACjC,cAAY;WAEZ,kBAAC,QAAD;EAAM,WAAU;YAAkC;EAAY,CAAA;CAC1D,CAAA"}
1
+ {"version":3,"file":"Thumbnail.js","names":[],"sources":["../../../src/coolandlovely/components/Thumbnail.tsx"],"sourcesContent":["/**\n * Thumbnail Component\n * @module coolandlovely/components\n *\n * Renders a calm, on-token visual placeholder for a fashion entity. Imagery in\n * CoolAndLovely is referenced from wspace-files-svc via federation (we only\n * have the File id here, not a resolvable URL), so the catalogue/wardrobe/look\n * surfaces render a branded glyph tile keyed by an icon rather than a broken\n * <img>. The seed (entity id) gives each tile a stable accent tint.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\nimport { FileImage } from './FileImage';\n\ninterface ThumbnailProps {\n icon: ReactNode;\n /** Stable seed (e.g. entity id) used to pick a deterministic accent tint. */\n seed?: string;\n className?: string;\n /** Whether a File reference exists (shows a subtle \"image attached\" hint). */\n hasImage?: boolean;\n label?: string;\n /** wspace-files File id — when it resolves, its image overlays the glyph. */\n fileId?: string | null;\n /** Alt text when a real image is shown. */\n alt?: string;\n}\n\nconst tints = [\n 'from-accent-purple-subtle to-bg-sunken',\n 'from-accent-blue-subtle to-bg-sunken',\n 'from-status-success-bg-subtle to-bg-sunken',\n 'from-status-warning-bg-subtle to-bg-sunken',\n 'from-[var(--color-accent-soft)] to-bg-sunken',\n];\n\nfunction tintFor(seed: string | undefined): string {\n if (!seed) return tints[0];\n let hash = 0;\n for (let i = 0; i < seed.length; i += 1) {\n hash = (hash * 31 + seed.charCodeAt(i)) % 997;\n }\n return tints[hash % tints.length];\n}\n\nexport const Thumbnail: FC<ThumbnailProps> = ({ icon, seed, className, label, fileId, alt }) => {\n return (\n <div\n className={cn(\n 'relative flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br',\n tintFor(seed),\n className\n )}\n aria-hidden={label ? undefined : true}\n aria-label={label}\n >\n <span className=\"text-text-secondary opacity-80\">{icon}</span>\n {fileId ? (\n <span className=\"absolute inset-0\">\n <FileImage fileId={fileId} alt={alt ?? label ?? ''} />\n </span>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;AA6BA,IAAM,IAAQ;CACZ;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,EAAQ,GAAkC;AACjD,KAAI,CAAC,EAAM,QAAO,EAAM;CACxB,IAAI,IAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,EACpC,MAAQ,IAAO,KAAK,EAAK,WAAW,EAAE,IAAI;AAE5C,QAAO,EAAM,IAAO,EAAM;;AAG5B,IAAa,KAAiC,EAAE,SAAM,SAAM,cAAW,UAAO,WAAQ,aAElF,kBAAC,OAAD;CACE,WAAW,EACT,0FACA,EAAQ,EAAK,EACb,EACD;CACD,eAAa,IAAQ,KAAA,IAAY;CACjC,cAAY;WAPd,CASE,kBAAC,QAAD;EAAM,WAAU;YAAkC;EAAY,CAAA,EAC7D,IACC,kBAAC,QAAD;EAAM,WAAU;YACd,kBAAC,GAAD;GAAmB;GAAQ,KAAK,KAAO,KAAS;GAAM,CAAA;EACjD,CAAA,GACL,KACA"}
@@ -1 +1,3 @@
1
+ import "./useFiles.js";
1
2
  import "./useCoolAndLovelyApi.js";
3
+ import "./useComments.js";
@@ -0,0 +1,68 @@
1
+ import { useCoolAndLovely as e } from "../context/CoolAndLovelyContext.js";
2
+ import "../context/index.js";
3
+ import { useMutation as t, useQuery as n, useQueryClient as r } from "@tanstack/react-query";
4
+ import { graphqlFetch as i } from "@burdenoff/fe-libs/shared/graphql";
5
+ import { clearGraphqlFetchResponseCache as a } from "@burdenoff/fe-libs/shared/graphql/fetch";
6
+ //#region src/coolandlovely/hooks/useComments.ts
7
+ var o = "coolandlovely-comments", s = async (e, t, n) => {
8
+ let r = await i({
9
+ gateway: "workspace",
10
+ baseUrl: n,
11
+ query: e,
12
+ variables: t,
13
+ workspaceToken: !0
14
+ });
15
+ if (r.errors?.length) throw Error(r.errors[0]?.message ?? "Comments request failed");
16
+ if (!r.data) throw Error("Comments response did not include data");
17
+ return /^\s*mutation\b/.test(e) && a(), r.data;
18
+ }, c = "\n query CooGetEntityComments($input: GetCommentsInput!) {\n getEntityComments(input: $input) {\n total\n items {\n id\n authorId\n authorType\n edited\n createdAt\n content { text }\n }\n }\n }\n", l = "\n mutation CooCreateEntityComment($input: CreateEntityCommentInput!) {\n createEntityComment(input: $input) {\n id\n }\n }\n", u = (t, r) => {
19
+ let { apiGatewayUrl: i } = e();
20
+ return n({
21
+ queryKey: [
22
+ o,
23
+ t,
24
+ r
25
+ ],
26
+ enabled: !!r,
27
+ queryFn: async () => {
28
+ let e = (await s(c, { input: {
29
+ entityType: t,
30
+ entityId: r,
31
+ take: 100,
32
+ sortBy: "createdAt",
33
+ sortOrder: "desc"
34
+ } }, i)).getEntityComments;
35
+ return {
36
+ total: e.total,
37
+ comments: e.items.map((e) => ({
38
+ id: e.id,
39
+ authorId: e.authorId,
40
+ authorType: (e.authorType ?? "user").toLowerCase(),
41
+ text: e.content?.text ?? "",
42
+ createdAt: e.createdAt,
43
+ edited: e.edited
44
+ }))
45
+ };
46
+ }
47
+ });
48
+ }, d = () => {
49
+ let n = r(), { apiGatewayUrl: i } = e();
50
+ return t({
51
+ mutationFn: async ({ entityType: e, entityId: t, text: n }) => (await s(l, { input: {
52
+ entityType: e,
53
+ entityId: t,
54
+ content: { text: n }
55
+ } }, i)).createEntityComment,
56
+ onSuccess: (e, t) => {
57
+ n.invalidateQueries({ queryKey: [
58
+ o,
59
+ t.entityType,
60
+ t.entityId
61
+ ] });
62
+ }
63
+ });
64
+ };
65
+ //#endregion
66
+ export { d as useAddComment, u as useEntityComments };
67
+
68
+ //# sourceMappingURL=useComments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useComments.js","names":[],"sources":["../../../src/coolandlovely/hooks/useComments.ts"],"sourcesContent":["/**\n * Comments hooks — reviews / feedback via wspace-conversations-svc (NO new table).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely does NOT own a comment/review table. Reviews & feedback on a\n * look or brand are polymorphic `EntityComment` records owned by\n * wspace-conversations-svc, keyed by (entityType, entityId). Same graphqlFetch\n * transport (workspace gateway + workspace token) as every other coo* call.\n *\n * Commenter display names must be resolved via fe-libs useActorProfiles\n * (GLOBAL gateway) — the federated wspace `User` here exposes only ids, so\n * NEVER select firstName/name on the comment author.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useCoolAndLovely } from '../context';\n\nconst QK = 'coolandlovely-comments';\n\n/** A single review/comment as surfaced in the MFE (scalar-only projection). */\nexport interface EntityCommentView {\n id: string;\n authorId: string;\n authorType: string;\n text: string;\n createdAt: string;\n edited: boolean;\n}\n\ninterface RawEntityComment {\n id: string;\n authorId: string;\n authorType: string;\n edited: boolean;\n createdAt: string;\n content: { text?: string | null } | null;\n}\n\nconst commentFetch = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Comments request failed');\n }\n if (!response.data) {\n throw new Error('Comments response did not include data');\n }\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n};\n\nconst GET_COMMENTS = `\n query CooGetEntityComments($input: GetCommentsInput!) {\n getEntityComments(input: $input) {\n total\n items {\n id\n authorId\n authorType\n edited\n createdAt\n content { text }\n }\n }\n }\n`;\n\nconst CREATE_COMMENT = `\n mutation CooCreateEntityComment($input: CreateEntityCommentInput!) {\n createEntityComment(input: $input) {\n id\n }\n }\n`;\n\nexport interface EntityCommentsResult {\n total: number;\n comments: EntityCommentView[];\n}\n\n/** List reviews/comments for a (entityType, entityId), newest first. */\nexport const useEntityComments = (entityType: string, entityId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, entityType, entityId],\n enabled: Boolean(entityId),\n queryFn: async (): Promise<EntityCommentsResult> => {\n const data = await commentFetch<{\n getEntityComments: { total: number; items: RawEntityComment[] };\n }>(\n GET_COMMENTS,\n {\n input: {\n entityType,\n entityId,\n take: 100,\n sortBy: 'createdAt',\n sortOrder: 'desc',\n },\n },\n apiGatewayUrl\n );\n const conn = data.getEntityComments;\n return {\n total: conn.total,\n comments: conn.items.map((c) => ({\n id: c.id,\n authorId: c.authorId,\n authorType: (c.authorType ?? 'user').toLowerCase(),\n text: c.content?.text ?? '',\n createdAt: c.createdAt,\n edited: c.edited,\n })),\n };\n },\n });\n};\n\n/** Post a review/comment on a (entityType, entityId). */\nexport const useAddComment = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({\n entityType,\n entityId,\n text,\n }: {\n entityType: string;\n entityId: string;\n text: string;\n }) => {\n const data = await commentFetch<{ createEntityComment: { id: string } }>(\n CREATE_COMMENT,\n {\n input: {\n entityType,\n entityId,\n content: { text },\n },\n },\n apiGatewayUrl\n );\n return data.createEntityComment;\n },\n onSuccess: (_result, variables) => {\n void queryClient.invalidateQueries({\n queryKey: [QK, variables.entityType, variables.entityId],\n });\n },\n });\n};\n"],"mappings":";;;;;;AAoBA,IAAM,IAAK,0BAqBL,IAAe,OACnB,GACA,GACA,MACmB;CACnB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA;EACA,gBAAgB;EACjB,CAAC;AACF,KAAI,EAAS,QAAQ,OACnB,OAAU,MAAM,EAAS,OAAO,IAAI,WAAW,0BAA0B;AAE3E,KAAI,CAAC,EAAS,KACZ,OAAU,MAAM,yCAAyC;AAK3D,QAHI,iBAAiB,KAAK,EAAM,IAC9B,GAAgC,EAE3B,EAAS;GAGZ,IAAe,yQAgBf,IAAiB,8IAcV,KAAqB,GAAoB,MAAiC;CACrF,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAY;GAAS;EACpC,SAAS,EAAQ;EACjB,SAAS,YAA2C;GAgBlD,IAAM,KAfO,MAAM,EAGjB,GACA,EACE,OAAO;IACL;IACA;IACA,MAAM;IACN,QAAQ;IACR,WAAW;IACZ,EACF,EACD,EACD,EACiB;AAClB,UAAO;IACL,OAAO,EAAK;IACZ,UAAU,EAAK,MAAM,KAAK,OAAO;KAC/B,IAAI,EAAE;KACN,UAAU,EAAE;KACZ,aAAa,EAAE,cAAc,QAAQ,aAAa;KAClD,MAAM,EAAE,SAAS,QAAQ;KACzB,WAAW,EAAE;KACb,QAAQ,EAAE;KACX,EAAE;IACJ;;EAEJ,CAAC;GAIS,UAAsB;CACjC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EACjB,eACA,aACA,eAMa,MAAM,EACjB,GACA,EACE,OAAO;GACL;GACA;GACA,SAAS,EAAE,SAAM;GAClB,EACF,EACD,EACD,EACW;EAEd,YAAY,GAAS,MAAc;AAC5B,KAAY,kBAAkB,EACjC,UAAU;IAAC;IAAI,EAAU;IAAY,EAAU;IAAS,EACzD,CAAC;;EAEL,CAAC"}