@burdenoff/microfe-devportal 2026.914.1 → 2026.914.3

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 (36) hide show
  1. package/dist/devportal/DevportalRoutes.d.ts.map +1 -1
  2. package/dist/devportal/DevportalRoutes.js +130 -110
  3. package/dist/devportal/DevportalRoutes.js.map +1 -1
  4. package/dist/devportal/components/SectionNav.d.ts +10 -1
  5. package/dist/devportal/components/SectionNav.d.ts.map +1 -1
  6. package/dist/devportal/components/SectionNav.js +60 -42
  7. package/dist/devportal/components/SectionNav.js.map +1 -1
  8. package/dist/devportal/hooks/useIsSellerSection.d.ts +13 -0
  9. package/dist/devportal/hooks/useIsSellerSection.d.ts.map +1 -0
  10. package/dist/devportal/hooks/useIsSellerSection.js +15 -0
  11. package/dist/devportal/hooks/useIsSellerSection.js.map +1 -0
  12. package/dist/devportal/pages/CreateOrganizationPage.d.ts.map +1 -1
  13. package/dist/devportal/pages/CreateOrganizationPage.js +107 -106
  14. package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
  15. package/dist/devportal/pages/OrganizationDetailPage.d.ts.map +1 -1
  16. package/dist/devportal/pages/OrganizationDetailPage.js +349 -336
  17. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  18. package/dist/devportal/pages/OrganizationMembersPage.d.ts.map +1 -1
  19. package/dist/devportal/pages/OrganizationMembersPage.js +291 -290
  20. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  21. package/dist/devportal/pages/OrganizationsPage.d.ts.map +1 -1
  22. package/dist/devportal/pages/OrganizationsPage.js +102 -101
  23. package/dist/devportal/pages/OrganizationsPage.js.map +1 -1
  24. package/dist/devportal/pages/RevenueDashboardPage.d.ts.map +1 -1
  25. package/dist/devportal/pages/RevenueDashboardPage.js +210 -209
  26. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  27. package/dist/devportal/pages/SellerDashboardPage.d.ts.map +1 -1
  28. package/dist/devportal/pages/SellerDashboardPage.js +14 -22
  29. package/dist/devportal/pages/SellerDashboardPage.js.map +1 -1
  30. package/dist/generated/global-operations.d.ts +102 -12
  31. package/dist/generated/global-operations.d.ts.map +1 -1
  32. package/dist/generated/global-operations.js +107 -92
  33. package/dist/generated/global-operations.js.map +1 -1
  34. package/dist/generated/global-types.d.ts +2963 -242
  35. package/dist/generated/global-types.d.ts.map +1 -1
  36. package/package.json +1 -1
@@ -1,125 +1,126 @@
1
1
  import { useDevportal as e } from "../providers/DevportalProvider.js";
2
2
  import { useTr as t } from "../utils/i18n.js";
3
3
  import { EmptyState as n } from "../components/EmptyState.js";
4
- import { useGetMyOrganizationsQuery as r } from "../../generated/global-operations.js";
5
- import { getErrorMessage as i } from "../hooks/useGraphQL.js";
6
- import { PageLayout as a } from "../components/PageLayout.js";
7
- import { StatusBadge as o, VerifiedBadge as s } from "../components/StatusBadge.js";
8
- import { PermissionGuard as c } from "../components/PermissionGuard.js";
4
+ import { orgSectionPath as r, useIsSellerSection as i } from "../hooks/useIsSellerSection.js";
5
+ import { useGetMyOrganizationsQuery as a } from "../../generated/global-operations.js";
6
+ import { getErrorMessage as o } from "../hooks/useGraphQL.js";
7
+ import { PageLayout as s } from "../components/PageLayout.js";
8
+ import { StatusBadge as c, VerifiedBadge as l } from "../components/StatusBadge.js";
9
+ import { PermissionGuard as u } from "../components/PermissionGuard.js";
9
10
  import "../components/index.js";
10
11
  import "../hooks/index.js";
11
- import { AlertCircle as l, AppWindow as u, Building2 as d, CheckCircle as f, DollarSign as p, Loader2 as m, Plus as h, Users as g } from "lucide-react";
12
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
13
- import { EmphasisPanel as y, GlassCard as b } from "@burdenoff/fe-libs/ui";
12
+ import { AlertCircle as d, AppWindow as f, Building2 as p, CheckCircle as m, DollarSign as h, Loader2 as g, Plus as _, Users as v } from "lucide-react";
13
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
14
+ import { EmphasisPanel as x, GlassCard as S } from "@burdenoff/fe-libs/ui";
14
15
  //#region src/devportal/pages/OrganizationsPage.tsx
15
- var x = () => {
16
- let { navigate: o, basePath: s } = e(), u = t(), { data: d, loading: f, error: p, refetch: g } = r({ fetchPolicy: "cache-and-network" }), x = d?.myDeveloperOrganizations ?? [], C = (e) => {
17
- o?.(`${s}${e}`);
18
- };
19
- return f && !d ? /* @__PURE__ */ _(a, {
20
- title: u("devportal.developerOrganizations", "Developer Organizations"),
21
- description: u("devportal.manageYourDevTeams", "Manage your development teams"),
22
- children: /* @__PURE__ */ v("div", {
16
+ var C = () => {
17
+ let { navigate: c, basePath: l } = e(), f = t(), p = i(), { data: m, loading: h, error: v, refetch: C } = a({ fetchPolicy: "cache-and-network" }), T = (m?.myDeveloperOrganizations ?? []).filter((e) => p ? e.kind === "PHYSICAL" : e.kind !== "PHYSICAL"), E = (e) => {
18
+ c?.(`${l}${e}`);
19
+ }, D = r(p, "new"), O = (e) => r(p, e), k = p ? f("devportal.sellerOrganizations", "Seller Organizations") : f("devportal.developerOrganizations", "Developer Organizations"), A = p ? f("devportal.manageYourSellerOrgs", "Manage the organizations you sell physical goods under") : f("devportal.manageYourDevTeams", "Manage your development teams");
20
+ return h && !m ? /* @__PURE__ */ y(s, {
21
+ title: k,
22
+ description: A,
23
+ children: /* @__PURE__ */ b("div", {
23
24
  className: "flex items-center justify-center py-12",
24
- children: [/* @__PURE__ */ _(m, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ _("span", {
25
+ children: [/* @__PURE__ */ y(g, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ y("span", {
25
26
  className: "ml-2 text-text-secondary",
26
- children: u("devportal.loadingOrganizations", "Loading organizations...")
27
+ children: f("devportal.loadingOrganizations", "Loading organizations...")
27
28
  })]
28
29
  })
29
- }) : p ? /* @__PURE__ */ _(a, {
30
- title: u("devportal.developerOrganizations", "Developer Organizations"),
31
- description: u("devportal.manageYourDevTeams", "Manage your development teams"),
32
- children: /* @__PURE__ */ v("div", {
30
+ }) : v ? /* @__PURE__ */ y(s, {
31
+ title: k,
32
+ description: A,
33
+ children: /* @__PURE__ */ b("div", {
33
34
  className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center",
34
35
  children: [
35
- /* @__PURE__ */ _(l, { className: "mx-auto h-8 w-8 text-status-error-text" }),
36
- /* @__PURE__ */ _("h3", {
36
+ /* @__PURE__ */ y(d, { className: "mx-auto h-8 w-8 text-status-error-text" }),
37
+ /* @__PURE__ */ y("h3", {
37
38
  className: "mt-2 font-medium text-status-error-text",
38
- children: u("devportal.failedToLoadOrganizations", "Failed to load organizations")
39
+ children: f("devportal.failedToLoadOrganizations", "Failed to load organizations")
39
40
  }),
40
- /* @__PURE__ */ _("p", {
41
+ /* @__PURE__ */ y("p", {
41
42
  className: "mt-1 text-sm text-text-secondary",
42
- children: i(p)
43
+ children: o(v)
43
44
  }),
44
- /* @__PURE__ */ _("button", {
45
- onClick: () => g(),
45
+ /* @__PURE__ */ y("button", {
46
+ onClick: () => C(),
46
47
  className: "mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
47
- children: u("devportal.tryAgain", "Try Again")
48
+ children: f("devportal.tryAgain", "Try Again")
48
49
  })
49
50
  ]
50
51
  })
51
- }) : /* @__PURE__ */ _(c, {
52
+ }) : /* @__PURE__ */ y(u, {
52
53
  authOnly: !0,
53
- children: /* @__PURE__ */ v(a, {
54
- title: u("devportal.developerOrganizations", "Developer Organizations"),
55
- description: u("devportal.manageYourDevTeams", "Manage your development teams"),
56
- purpose: u("devportal.organizationsPurpose", "An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation."),
57
- actions: /* @__PURE__ */ v("button", {
58
- onClick: () => C("/organizations/new"),
54
+ children: /* @__PURE__ */ b(s, {
55
+ title: k,
56
+ description: A,
57
+ purpose: p ? f("devportal.sellerOrganizationsPurpose", "A seller organization owns your physical listings, orders, and revenue. It's created automatically the first time you list an item, or you can create one here.") : f("devportal.organizationsPurpose", "An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation."),
58
+ actions: /* @__PURE__ */ b("button", {
59
+ onClick: () => E(D),
59
60
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
60
- children: [/* @__PURE__ */ _(h, { size: 16 }), u("devportal.createOrganization", "Create Organization")]
61
+ children: [/* @__PURE__ */ y(_, { size: 16 }), f("devportal.createOrganization", "Create Organization")]
61
62
  }),
62
- children: [x.length > 0 && /* @__PURE__ */ _(y, {
63
+ children: [T.length > 0 && /* @__PURE__ */ y(x, {
63
64
  className: "mb-6",
64
- children: /* @__PURE__ */ v("div", {
65
+ children: /* @__PURE__ */ b("div", {
65
66
  className: "grid grid-cols-2 gap-4 sm:grid-cols-3",
66
67
  children: [
67
- /* @__PURE__ */ v(b, {
68
+ /* @__PURE__ */ b(S, {
68
69
  treatment: "metric",
69
70
  className: "p-4",
70
- children: [/* @__PURE__ */ _("p", {
71
+ children: [/* @__PURE__ */ y("p", {
71
72
  className: "text-sm text-text-secondary",
72
- children: u("devportal.organizations", "Organizations")
73
- }), /* @__PURE__ */ _("p", {
73
+ children: f("devportal.organizations", "Organizations")
74
+ }), /* @__PURE__ */ y("p", {
74
75
  className: "mt-1 text-2xl font-semibold tabular-nums",
75
- children: x.length
76
+ children: T.length
76
77
  })]
77
78
  }),
78
- /* @__PURE__ */ v(b, {
79
+ /* @__PURE__ */ b(S, {
79
80
  treatment: "metric",
80
81
  className: "p-4",
81
- children: [/* @__PURE__ */ _("p", {
82
+ children: [/* @__PURE__ */ y("p", {
82
83
  className: "text-sm text-text-secondary",
83
- children: u("devportal.totalApps", "Total Apps")
84
- }), /* @__PURE__ */ _("p", {
84
+ children: f("devportal.totalApps", "Total Apps")
85
+ }), /* @__PURE__ */ y("p", {
85
86
  className: "mt-1 text-2xl font-semibold tabular-nums",
86
- children: x.reduce((e, t) => e + (t.totalApps ?? 0), 0)
87
+ children: T.reduce((e, t) => e + (t.totalApps ?? 0), 0)
87
88
  })]
88
89
  }),
89
- /* @__PURE__ */ v(b, {
90
+ /* @__PURE__ */ b(S, {
90
91
  treatment: "metric",
91
92
  className: "p-4",
92
- children: [/* @__PURE__ */ _("p", {
93
+ children: [/* @__PURE__ */ y("p", {
93
94
  className: "text-sm text-text-secondary",
94
- children: u("devportal.activeInstalls", "Active Installs")
95
- }), /* @__PURE__ */ _("p", {
95
+ children: f("devportal.activeInstalls", "Active Installs")
96
+ }), /* @__PURE__ */ y("p", {
96
97
  className: "mt-1 text-2xl font-semibold tabular-nums",
97
- children: x.reduce((e, t) => e + (t.activeInstalls ?? 0), 0).toLocaleString()
98
+ children: T.reduce((e, t) => e + (t.activeInstalls ?? 0), 0).toLocaleString()
98
99
  })]
99
100
  })
100
101
  ]
101
102
  })
102
- }), x.length > 0 ? /* @__PURE__ */ _("div", {
103
+ }), T.length > 0 ? /* @__PURE__ */ y("div", {
103
104
  className: "grid gap-6",
104
- children: x.map((e) => /* @__PURE__ */ _(S, {
105
+ children: T.map((e) => /* @__PURE__ */ y(w, {
105
106
  org: e,
106
- onClick: () => C(`/organizations/${e.id}`)
107
+ onClick: () => E(O(e.id))
107
108
  }, e.id))
108
- }) : /* @__PURE__ */ _(n, {
109
+ }) : /* @__PURE__ */ y(n, {
109
110
  illustration: "empty-people",
110
- title: u("devportal.noOrganizationsYet", "No organizations yet"),
111
- description: u("devportal.createOrgToCollaborate", "Create an organization to collaborate with your team and manage apps together"),
112
- action: /* @__PURE__ */ v("button", {
113
- onClick: () => C("/organizations/new"),
111
+ title: p ? f("devportal.noSellerOrganizationsYet", "No seller organizations yet") : f("devportal.noOrganizationsYet", "No organizations yet"),
112
+ description: p ? f("devportal.createSellerOrgToSell", "Create a seller organization to start selling physical products, or list your first item and one will be set up for you") : f("devportal.createOrgToCollaborate", "Create an organization to collaborate with your team and manage apps together"),
113
+ action: /* @__PURE__ */ b("button", {
114
+ onClick: () => E(D),
114
115
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
115
- children: [/* @__PURE__ */ _(h, { size: 16 }), u("devportal.createOrganization", "Create Organization")]
116
+ children: [/* @__PURE__ */ y(_, { size: 16 }), f("devportal.createOrganization", "Create Organization")]
116
117
  })
117
118
  })]
118
119
  })
119
120
  });
120
- }, S = ({ org: e, onClick: n }) => {
121
+ }, w = ({ org: e, onClick: n }) => {
121
122
  let r = t();
122
- return /* @__PURE__ */ v("div", {
123
+ return /* @__PURE__ */ b("div", {
123
124
  role: "button",
124
125
  tabIndex: 0,
125
126
  onClick: n,
@@ -127,71 +128,71 @@ var x = () => {
127
128
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), n());
128
129
  },
129
130
  className: "cursor-pointer rounded-card border border-border-seam bg-bg-surface p-6 shadow-[var(--shadow-pop)] transition-[box-shadow,border-color] hover:shadow-[var(--shadow-pop-hover)] hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
130
- children: [/* @__PURE__ */ v("div", {
131
+ children: [/* @__PURE__ */ b("div", {
131
132
  className: "flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
132
- children: [/* @__PURE__ */ v("div", {
133
+ children: [/* @__PURE__ */ b("div", {
133
134
  className: "flex items-start gap-4",
134
- children: [e.logoUrl ? /* @__PURE__ */ _("img", {
135
+ children: [e.logoUrl ? /* @__PURE__ */ y("img", {
135
136
  src: e.logoUrl,
136
137
  alt: e.name,
137
138
  className: "h-16 w-16 rounded-lg object-cover"
138
- }) : /* @__PURE__ */ _("div", {
139
+ }) : /* @__PURE__ */ y("div", {
139
140
  className: "flex h-16 w-16 items-center justify-center rounded-lg bg-action-primary-bg/10 text-primary",
140
- children: /* @__PURE__ */ _(d, { size: 32 })
141
- }), /* @__PURE__ */ v("div", { children: [
142
- /* @__PURE__ */ v("div", {
141
+ children: /* @__PURE__ */ y(p, { size: 32 })
142
+ }), /* @__PURE__ */ b("div", { children: [
143
+ /* @__PURE__ */ b("div", {
143
144
  className: "flex items-center gap-2 flex-wrap",
144
145
  children: [
145
- /* @__PURE__ */ _("h3", {
146
+ /* @__PURE__ */ y("h3", {
146
147
  className: "text-lg font-semibold",
147
148
  children: e.name
148
149
  }),
149
- e.isVerified && /* @__PURE__ */ _(s, { verified: !0 }),
150
- e.isCertified && /* @__PURE__ */ v("span", {
150
+ e.isVerified && /* @__PURE__ */ y(l, { verified: !0 }),
151
+ e.isCertified && /* @__PURE__ */ b("span", {
151
152
  className: "inline-flex items-center gap-1 rounded-full bg-status-info-bg-subtle px-2 py-0.5 text-xs font-medium text-status-info-text",
152
153
  children: [
153
- /* @__PURE__ */ _(f, { size: 12 }),
154
+ /* @__PURE__ */ y(m, { size: 12 }),
154
155
  " ",
155
156
  r("devportal.certified", "Certified")
156
157
  ]
157
158
  })
158
159
  ]
159
160
  }),
160
- e.description && /* @__PURE__ */ _("p", {
161
+ e.description && /* @__PURE__ */ y("p", {
161
162
  className: "mt-1 text-sm text-text-secondary",
162
163
  children: e.description
163
164
  }),
164
- /* @__PURE__ */ v("div", {
165
+ /* @__PURE__ */ b("div", {
165
166
  className: "mt-2 flex flex-wrap items-center gap-2",
166
- children: [/* @__PURE__ */ _(o, {
167
+ children: [/* @__PURE__ */ y(c, {
167
168
  status: e.tier,
168
169
  type: "tier"
169
- }), e.partnerTier && /* @__PURE__ */ _(o, {
170
+ }), e.partnerTier && /* @__PURE__ */ y(c, {
170
171
  status: e.partnerTier,
171
172
  type: "partner"
172
173
  })]
173
174
  })
174
175
  ] })]
175
- }), /* @__PURE__ */ v("div", {
176
+ }), /* @__PURE__ */ b("div", {
176
177
  className: "flex flex-wrap gap-6 text-sm",
177
178
  children: [
178
- /* @__PURE__ */ v("div", {
179
+ /* @__PURE__ */ b("div", {
179
180
  className: "flex items-center gap-2",
180
- children: [/* @__PURE__ */ _(g, {
181
+ children: [/* @__PURE__ */ y(v, {
181
182
  size: 16,
182
183
  className: "text-text-secondary"
183
- }), /* @__PURE__ */ v("span", { children: [
184
+ }), /* @__PURE__ */ b("span", { children: [
184
185
  e.members?.length || 0,
185
186
  " ",
186
187
  r("devportal.membersLower", "members")
187
188
  ] })]
188
189
  }),
189
- /* @__PURE__ */ v("div", {
190
+ /* @__PURE__ */ b("div", {
190
191
  className: "flex items-center gap-2",
191
- children: [/* @__PURE__ */ _(u, {
192
+ children: [/* @__PURE__ */ y(f, {
192
193
  size: 16,
193
194
  className: "text-text-secondary"
194
- }), /* @__PURE__ */ v("span", { children: [
195
+ }), /* @__PURE__ */ b("span", { children: [
195
196
  e.publishedApps,
196
197
  " / ",
197
198
  e.totalApps,
@@ -199,43 +200,43 @@ var x = () => {
199
200
  r("devportal.appsLower", "apps")
200
201
  ] })]
201
202
  }),
202
- /* @__PURE__ */ v("div", {
203
+ /* @__PURE__ */ b("div", {
203
204
  className: "flex items-center gap-2",
204
- children: [/* @__PURE__ */ _(p, {
205
+ children: [/* @__PURE__ */ y(h, {
205
206
  size: 16,
206
207
  className: "text-text-secondary"
207
- }), /* @__PURE__ */ v("span", { children: ["$", (e.totalRevenue || 0).toLocaleString()] })]
208
+ }), /* @__PURE__ */ b("span", { children: ["$", (e.totalRevenue || 0).toLocaleString()] })]
208
209
  })
209
210
  ]
210
211
  })]
211
- }), /* @__PURE__ */ v("div", {
212
+ }), /* @__PURE__ */ b("div", {
212
213
  className: "mt-4 grid grid-cols-2 gap-4 rounded-lg bg-bg-sunken/50 p-4 sm:grid-cols-4",
213
214
  children: [
214
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
215
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
215
216
  className: "text-xs text-text-secondary",
216
217
  children: r("devportal.totalInstalls", "Total Installs")
217
- }), /* @__PURE__ */ _("p", {
218
+ }), /* @__PURE__ */ y("p", {
218
219
  className: "text-lg font-semibold",
219
220
  children: (e.totalInstalls || 0).toLocaleString()
220
221
  })] }),
221
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
222
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
222
223
  className: "text-xs text-text-secondary",
223
224
  children: r("devportal.activeInstalls", "Active Installs")
224
- }), /* @__PURE__ */ _("p", {
225
+ }), /* @__PURE__ */ y("p", {
225
226
  className: "text-lg font-semibold",
226
227
  children: (e.activeInstalls || 0).toLocaleString()
227
228
  })] }),
228
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
229
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
229
230
  className: "text-xs text-text-secondary",
230
231
  children: r("devportal.apiCalls", "API Calls")
231
- }), /* @__PURE__ */ _("p", {
232
+ }), /* @__PURE__ */ y("p", {
232
233
  className: "text-lg font-semibold",
233
234
  children: e.totalApiCalls ? `${(parseInt(e.totalApiCalls) / 1e6).toFixed(1)}M` : "0"
234
235
  })] }),
235
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
236
+ /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
236
237
  className: "text-xs text-text-secondary",
237
238
  children: r("devportal.avgRating", "Avg Rating")
238
- }), /* @__PURE__ */ _("p", {
239
+ }), /* @__PURE__ */ y("p", {
239
240
  className: "text-lg font-semibold",
240
241
  children: e.averageRating ? `${e.averageRating.toFixed(1)} ★` : r("devportal.notAvailable", "N/A")
241
242
  })] })
@@ -244,6 +245,6 @@ var x = () => {
244
245
  });
245
246
  };
246
247
  //#endregion
247
- export { x as OrganizationsPage };
248
+ export { C as OrganizationsPage };
248
249
 
249
250
  //# sourceMappingURL=OrganizationsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationsPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport {\n Plus,\n Building2,\n Users,\n AppWindow,\n DollarSign,\n CheckCircle,\n AlertCircle,\n Loader2,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { StatusBadge, VerifiedBadge } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { useTr } from \"../utils/i18n\";\nimport type { DeveloperOrganization } from \"../types\";\nimport {\n useGetMyOrganizationsQuery,\n getErrorMessage,\n type OrganizationFieldsFragment,\n} from \"../hooks\";\n\n/**\n * Organizations listing page\n *\n * Displays all developer organizations the current user is a member of.\n * Uses GraphQL to fetch real data from the DevPortal backend.\n */\nexport const OrganizationsPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const tr = useTr();\n\n // Fetch organizations from GraphQL API\n const { data, loading, error, refetch } = useGetMyOrganizationsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const organizations = data?.myDeveloperOrganizations ?? [];\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingOrganizations\", \"Loading organizations...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\n \"devportal.failedToLoadOrganizations\",\n \"Failed to load organizations\",\n )}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n purpose={tr(\n \"devportal.organizationsPurpose\",\n \"An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n >\n {organizations.length > 0 && (\n <EmphasisPanel className=\"mb-6\">\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.organizations\", \"Organizations\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.totalApps ?? 0),\n 0,\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.activeInstalls\", \"Active Installs\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations\n .reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.activeInstalls ?? 0),\n 0,\n )\n .toLocaleString()}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n )}\n {organizations.length > 0 ? (\n <div className=\"grid gap-6\">\n {organizations.map((org: OrganizationFieldsFragment) => (\n <OrganizationCard\n key={org.id}\n org={org as DeveloperOrganization}\n onClick={() => handleNavigate(`/organizations/${org.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={tr(\"devportal.noOrganizationsYet\", \"No organizations yet\")}\n description={tr(\n \"devportal.createOrgToCollaborate\",\n \"Create an organization to collaborate with your team and manage apps together\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// Organization card component\nconst OrganizationCard: FC<{\n org: DeveloperOrganization;\n onClick: () => void;\n}> = ({ org, onClick }) => {\n const tr = useTr();\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onClick();\n }\n }}\n className=\"cursor-pointer rounded-card border border-border-seam bg-bg-surface p-6 shadow-[var(--shadow-pop)] transition-[box-shadow,border-color] hover:shadow-[var(--shadow-pop-hover)] hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n {/* Left side - Info */}\n <div className=\"flex items-start gap-4\">\n {org.logoUrl ? (\n <img\n src={org.logoUrl}\n alt={org.name}\n className=\"h-16 w-16 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-lg bg-action-primary-bg/10 text-primary\">\n <Building2 size={32} />\n </div>\n )}\n <div>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h3 className=\"text-lg font-semibold\">{org.name}</h3>\n {org.isVerified && <VerifiedBadge verified />}\n {org.isCertified && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-info-bg-subtle px-2 py-0.5 text-xs font-medium text-status-info-text\">\n <CheckCircle size={12} />{\" \"}\n {tr(\"devportal.certified\", \"Certified\")}\n </span>\n )}\n </div>\n {org.description && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {org.description}\n </p>\n )}\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n <StatusBadge status={org.tier} type=\"tier\" />\n {org.partnerTier && (\n <StatusBadge status={org.partnerTier} type=\"partner\" />\n )}\n </div>\n </div>\n </div>\n\n {/* Right side - Stats */}\n <div className=\"flex flex-wrap gap-6 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Users size={16} className=\"text-text-secondary\" />\n <span>\n {org.members?.length || 0}{\" \"}\n {tr(\"devportal.membersLower\", \"members\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <AppWindow size={16} className=\"text-text-secondary\" />\n <span>\n {org.publishedApps} / {org.totalApps}{\" \"}\n {tr(\"devportal.appsLower\", \"apps\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <DollarSign size={16} className=\"text-text-secondary\" />\n <span>${(org.totalRevenue || 0).toLocaleString()}</span>\n </div>\n </div>\n </div>\n\n {/* Stats bar */}\n <div className=\"mt-4 grid grid-cols-2 gap-4 rounded-lg bg-bg-sunken/50 p-4 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.totalInstalls\", \"Total Installs\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {(org.totalInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.activeInstalls\", \"Active Installs\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {(org.activeInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.apiCalls\", \"API Calls\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {org.totalApiCalls\n ? `${(parseInt(org.totalApiCalls) / 1000000).toFixed(1)}M`\n : \"0\"}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.avgRating\", \"Avg Rating\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {org.averageRating\n ? `${org.averageRating.toFixed(1)} ★`\n : tr(\"devportal.notAvailable\", \"N/A\")}\n </p>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OrganizationsPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport {\n Plus,\n Building2,\n Users,\n AppWindow,\n DollarSign,\n CheckCircle,\n AlertCircle,\n Loader2,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { StatusBadge, VerifiedBadge } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { useTr } from \"../utils/i18n\";\nimport {\n useIsSellerSection,\n orgSectionPath,\n} from \"../hooks/useIsSellerSection\";\nimport type { DeveloperOrganization } from \"../types\";\nimport {\n useGetMyOrganizationsQuery,\n getErrorMessage,\n type OrganizationFieldsFragment,\n} from \"../hooks\";\n\n/**\n * Organizations listing page\n *\n * Displays all developer organizations the current user is a member of.\n * Uses GraphQL to fetch real data from the DevPortal backend.\n */\nexport const OrganizationsPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const tr = useTr();\n const isSeller = useIsSellerSection();\n\n // Fetch organizations from GraphQL API\n const { data, loading, error, refetch } = useGetMyOrganizationsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n // Shared page for both DIGITAL orgs (regular devportal) and PHYSICAL orgs\n // (seller portal) — filtered by which section it's reached from. See\n // DeveloperOrgKind (BOFF-7285).\n const organizations = (data?.myDeveloperOrganizations ?? []).filter(\n (org: OrganizationFieldsFragment) =>\n isSeller ? org.kind === \"PHYSICAL\" : org.kind !== \"PHYSICAL\",\n );\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const createPath = orgSectionPath(isSeller, \"new\");\n const detailPath = (orgId: string) => orgSectionPath(isSeller, orgId);\n\n const pageTitle = isSeller\n ? tr(\"devportal.sellerOrganizations\", \"Seller Organizations\")\n : tr(\"devportal.developerOrganizations\", \"Developer Organizations\");\n const pageDescription = isSeller\n ? tr(\n \"devportal.manageYourSellerOrgs\",\n \"Manage the organizations you sell physical goods under\",\n )\n : tr(\"devportal.manageYourDevTeams\", \"Manage your development teams\");\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout title={pageTitle} description={pageDescription}>\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingOrganizations\", \"Loading organizations...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout title={pageTitle} description={pageDescription}>\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\n \"devportal.failedToLoadOrganizations\",\n \"Failed to load organizations\",\n )}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={pageTitle}\n description={pageDescription}\n purpose={\n isSeller\n ? tr(\n \"devportal.sellerOrganizationsPurpose\",\n \"A seller organization owns your physical listings, orders, and revenue. It's created automatically the first time you list an item, or you can create one here.\",\n )\n : tr(\n \"devportal.organizationsPurpose\",\n \"An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation.\",\n )\n }\n actions={\n <button\n onClick={() => handleNavigate(createPath)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n >\n {organizations.length > 0 && (\n <EmphasisPanel className=\"mb-6\">\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.organizations\", \"Organizations\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.totalApps ?? 0),\n 0,\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.activeInstalls\", \"Active Installs\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations\n .reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.activeInstalls ?? 0),\n 0,\n )\n .toLocaleString()}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n )}\n {organizations.length > 0 ? (\n <div className=\"grid gap-6\">\n {organizations.map((org: OrganizationFieldsFragment) => (\n <OrganizationCard\n key={org.id}\n org={org as DeveloperOrganization}\n onClick={() => handleNavigate(detailPath(org.id))}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={\n isSeller\n ? tr(\n \"devportal.noSellerOrganizationsYet\",\n \"No seller organizations yet\",\n )\n : tr(\"devportal.noOrganizationsYet\", \"No organizations yet\")\n }\n description={\n isSeller\n ? tr(\n \"devportal.createSellerOrgToSell\",\n \"Create a seller organization to start selling physical products, or list your first item and one will be set up for you\",\n )\n : tr(\n \"devportal.createOrgToCollaborate\",\n \"Create an organization to collaborate with your team and manage apps together\",\n )\n }\n action={\n <button\n onClick={() => handleNavigate(createPath)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// Organization card component\nconst OrganizationCard: FC<{\n org: DeveloperOrganization;\n onClick: () => void;\n}> = ({ org, onClick }) => {\n const tr = useTr();\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onClick();\n }\n }}\n className=\"cursor-pointer rounded-card border border-border-seam bg-bg-surface p-6 shadow-[var(--shadow-pop)] transition-[box-shadow,border-color] hover:shadow-[var(--shadow-pop-hover)] hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n {/* Left side - Info */}\n <div className=\"flex items-start gap-4\">\n {org.logoUrl ? (\n <img\n src={org.logoUrl}\n alt={org.name}\n className=\"h-16 w-16 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-lg bg-action-primary-bg/10 text-primary\">\n <Building2 size={32} />\n </div>\n )}\n <div>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h3 className=\"text-lg font-semibold\">{org.name}</h3>\n {org.isVerified && <VerifiedBadge verified />}\n {org.isCertified && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-info-bg-subtle px-2 py-0.5 text-xs font-medium text-status-info-text\">\n <CheckCircle size={12} />{\" \"}\n {tr(\"devportal.certified\", \"Certified\")}\n </span>\n )}\n </div>\n {org.description && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {org.description}\n </p>\n )}\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n <StatusBadge status={org.tier} type=\"tier\" />\n {org.partnerTier && (\n <StatusBadge status={org.partnerTier} type=\"partner\" />\n )}\n </div>\n </div>\n </div>\n\n {/* Right side - Stats */}\n <div className=\"flex flex-wrap gap-6 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Users size={16} className=\"text-text-secondary\" />\n <span>\n {org.members?.length || 0}{\" \"}\n {tr(\"devportal.membersLower\", \"members\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <AppWindow size={16} className=\"text-text-secondary\" />\n <span>\n {org.publishedApps} / {org.totalApps}{\" \"}\n {tr(\"devportal.appsLower\", \"apps\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <DollarSign size={16} className=\"text-text-secondary\" />\n <span>${(org.totalRevenue || 0).toLocaleString()}</span>\n </div>\n </div>\n </div>\n\n {/* Stats bar */}\n <div className=\"mt-4 grid grid-cols-2 gap-4 rounded-lg bg-bg-sunken/50 p-4 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.totalInstalls\", \"Total Installs\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {(org.totalInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.activeInstalls\", \"Active Installs\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {(org.activeInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.apiCalls\", \"API Calls\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {org.totalApiCalls\n ? `${(parseInt(org.totalApiCalls) / 1000000).toFixed(1)}M`\n : \"0\"}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.avgRating\", \"Avg Rating\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {org.averageRating\n ? `${org.averageRating.toFixed(1)} ★`\n : tr(\"devportal.notAvailable\", \"N/A\")}\n </p>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RevenueDashboardPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/RevenueDashboardPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAgEhC,eAAO,MAAM,oBAAoB,EAAE,EAmxBlC,CAAC"}
1
+ {"version":3,"file":"RevenueDashboardPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/RevenueDashboardPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAiEhC,eAAO,MAAM,oBAAoB,EAAE,EA6xBlC,CAAC"}