@shellui/core 0.0.11 → 0.0.13

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 (172) hide show
  1. package/README.md +0 -11
  2. package/dist/ContentView-CZG-ro_B.js +146 -0
  3. package/dist/ContentView-CZG-ro_B.js.map +1 -0
  4. package/dist/CookiePreferencesView-Bb3hFqw1.js +213 -0
  5. package/dist/CookiePreferencesView-Bb3hFqw1.js.map +1 -0
  6. package/dist/DefaultLayout-D3IpgS4j.js +406 -0
  7. package/dist/DefaultLayout-D3IpgS4j.js.map +1 -0
  8. package/dist/FullscreenLayout-Do9vAfl8.js +30 -0
  9. package/dist/FullscreenLayout-Do9vAfl8.js.map +1 -0
  10. package/dist/HomeView-DwckTuxz.js +21 -0
  11. package/dist/HomeView-DwckTuxz.js.map +1 -0
  12. package/dist/NotFoundView-DD7azhz-.js +52 -0
  13. package/dist/NotFoundView-DD7azhz-.js.map +1 -0
  14. package/dist/OverlayShell-kDY56DaN.js +642 -0
  15. package/dist/OverlayShell-kDY56DaN.js.map +1 -0
  16. package/dist/SettingsView-Bt4I-KDT.js +2207 -0
  17. package/dist/SettingsView-Bt4I-KDT.js.map +1 -0
  18. package/dist/ViewRoute-ChSPabOy.js +32 -0
  19. package/dist/ViewRoute-ChSPabOy.js.map +1 -0
  20. package/dist/WindowsLayout-CEqkRKyk.js +633 -0
  21. package/dist/WindowsLayout-CEqkRKyk.js.map +1 -0
  22. package/dist/app.d.ts +3 -0
  23. package/dist/app.d.ts.map +1 -0
  24. package/dist/components/ContentView.d.ts +10 -0
  25. package/dist/components/ContentView.d.ts.map +1 -0
  26. package/dist/components/HomeView.d.ts +2 -0
  27. package/dist/components/HomeView.d.ts.map +1 -0
  28. package/dist/components/LoadingOverlay.d.ts +2 -0
  29. package/dist/components/LoadingOverlay.d.ts.map +1 -0
  30. package/dist/components/NotFoundView.d.ts +2 -0
  31. package/dist/components/NotFoundView.d.ts.map +1 -0
  32. package/dist/components/RouteErrorBoundary.d.ts +2 -0
  33. package/dist/components/RouteErrorBoundary.d.ts.map +1 -0
  34. package/dist/components/ViewRoute.d.ts +7 -0
  35. package/dist/components/ViewRoute.d.ts.map +1 -0
  36. package/dist/components/ui/alert-dialog.d.ts +32 -0
  37. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  38. package/dist/components/ui/breadcrumb.d.ts +20 -0
  39. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  40. package/dist/components/ui/button-group.d.ts +7 -0
  41. package/dist/components/ui/button-group.d.ts.map +1 -0
  42. package/dist/components/ui/button.d.ts +12 -0
  43. package/dist/components/ui/button.d.ts.map +1 -0
  44. package/dist/components/ui/dialog.d.ts +24 -0
  45. package/dist/components/ui/dialog.d.ts.map +1 -0
  46. package/dist/components/ui/drawer.d.ts +38 -0
  47. package/dist/components/ui/drawer.d.ts.map +1 -0
  48. package/dist/components/ui/select.d.ts +5 -0
  49. package/dist/components/ui/select.d.ts.map +1 -0
  50. package/dist/components/ui/sidebar.d.ts +46 -0
  51. package/dist/components/ui/sidebar.d.ts.map +1 -0
  52. package/dist/components/ui/sonner.d.ts +6 -0
  53. package/dist/components/ui/sonner.d.ts.map +1 -0
  54. package/dist/components/ui/switch.d.ts +8 -0
  55. package/dist/components/ui/switch.d.ts.map +1 -0
  56. package/dist/constants/urls.d.ts +6 -0
  57. package/dist/constants/urls.d.ts.map +1 -0
  58. package/dist/constants/urls.js +8 -0
  59. package/dist/constants/urls.js.map +1 -0
  60. package/dist/features/alertDialog/DialogContext.d.ts +12 -0
  61. package/dist/features/alertDialog/DialogContext.d.ts.map +1 -0
  62. package/dist/features/config/ConfigProvider.d.ts +15 -0
  63. package/dist/features/config/ConfigProvider.d.ts.map +1 -0
  64. package/dist/features/config/types.d.ts +177 -0
  65. package/dist/features/config/types.d.ts.map +1 -0
  66. package/dist/features/config/useConfig.d.ts +8 -0
  67. package/dist/features/config/useConfig.d.ts.map +1 -0
  68. package/dist/features/cookieConsent/CookieConsentModal.d.ts +6 -0
  69. package/dist/features/cookieConsent/CookieConsentModal.d.ts.map +1 -0
  70. package/dist/features/cookieConsent/CookiePreferencesView.d.ts +2 -0
  71. package/dist/features/cookieConsent/CookiePreferencesView.d.ts.map +1 -0
  72. package/dist/features/cookieConsent/cookieConsent.d.ts +22 -0
  73. package/dist/features/cookieConsent/cookieConsent.d.ts.map +1 -0
  74. package/dist/features/cookieConsent/useCookieConsent.d.ts +15 -0
  75. package/dist/features/cookieConsent/useCookieConsent.d.ts.map +1 -0
  76. package/dist/features/drawer/DrawerContext.d.ts +24 -0
  77. package/dist/features/drawer/DrawerContext.d.ts.map +1 -0
  78. package/dist/features/layouts/AppLayout.d.ts +12 -0
  79. package/dist/features/layouts/AppLayout.d.ts.map +1 -0
  80. package/dist/features/layouts/DefaultLayout.d.ts +10 -0
  81. package/dist/features/layouts/DefaultLayout.d.ts.map +1 -0
  82. package/dist/features/layouts/FullscreenLayout.d.ts +9 -0
  83. package/dist/features/layouts/FullscreenLayout.d.ts.map +1 -0
  84. package/dist/features/layouts/LayoutProviders.d.ts +9 -0
  85. package/dist/features/layouts/LayoutProviders.d.ts.map +1 -0
  86. package/dist/features/layouts/OverlayShell.d.ts +10 -0
  87. package/dist/features/layouts/OverlayShell.d.ts.map +1 -0
  88. package/dist/features/layouts/WindowsLayout.d.ts +24 -0
  89. package/dist/features/layouts/WindowsLayout.d.ts.map +1 -0
  90. package/dist/features/layouts/utils.d.ts +16 -0
  91. package/dist/features/layouts/utils.d.ts.map +1 -0
  92. package/dist/features/modal/ModalContext.d.ts +20 -0
  93. package/dist/features/modal/ModalContext.d.ts.map +1 -0
  94. package/dist/features/sentry/initSentry.d.ts +14 -0
  95. package/dist/features/sentry/initSentry.d.ts.map +1 -0
  96. package/dist/features/settings/SettingsContext.d.ts +10 -0
  97. package/dist/features/settings/SettingsContext.d.ts.map +1 -0
  98. package/dist/features/settings/SettingsIcons.d.ts +22 -0
  99. package/dist/features/settings/SettingsIcons.d.ts.map +1 -0
  100. package/dist/features/settings/SettingsProvider.d.ts +5 -0
  101. package/dist/features/settings/SettingsProvider.d.ts.map +1 -0
  102. package/dist/features/settings/SettingsRoutes.d.ts +7 -0
  103. package/dist/features/settings/SettingsRoutes.d.ts.map +1 -0
  104. package/dist/features/settings/SettingsView.d.ts +2 -0
  105. package/dist/features/settings/SettingsView.d.ts.map +1 -0
  106. package/dist/features/settings/components/Advanced.d.ts +2 -0
  107. package/dist/features/settings/components/Advanced.d.ts.map +1 -0
  108. package/dist/features/settings/components/Appearance.d.ts +2 -0
  109. package/dist/features/settings/components/Appearance.d.ts.map +1 -0
  110. package/dist/features/settings/components/DataPrivacy.d.ts +2 -0
  111. package/dist/features/settings/components/DataPrivacy.d.ts.map +1 -0
  112. package/dist/features/settings/components/Develop.d.ts +2 -0
  113. package/dist/features/settings/components/Develop.d.ts.map +1 -0
  114. package/dist/features/settings/components/LanguageAndRegion.d.ts +2 -0
  115. package/dist/features/settings/components/LanguageAndRegion.d.ts.map +1 -0
  116. package/dist/features/settings/components/ServiceWorker.d.ts +2 -0
  117. package/dist/features/settings/components/ServiceWorker.d.ts.map +1 -0
  118. package/dist/features/settings/components/UpdateApp.d.ts +2 -0
  119. package/dist/features/settings/components/UpdateApp.d.ts.map +1 -0
  120. package/dist/features/settings/components/develop/DialogTestButtons.d.ts +2 -0
  121. package/dist/features/settings/components/develop/DialogTestButtons.d.ts.map +1 -0
  122. package/dist/features/settings/components/develop/DrawerTestButtons.d.ts +2 -0
  123. package/dist/features/settings/components/develop/DrawerTestButtons.d.ts.map +1 -0
  124. package/dist/features/settings/components/develop/ModalTestButtons.d.ts +2 -0
  125. package/dist/features/settings/components/develop/ModalTestButtons.d.ts.map +1 -0
  126. package/dist/features/settings/components/develop/ToastTestButtons.d.ts +2 -0
  127. package/dist/features/settings/components/develop/ToastTestButtons.d.ts.map +1 -0
  128. package/dist/features/settings/hooks/useSettings.d.ts +2 -0
  129. package/dist/features/settings/hooks/useSettings.d.ts.map +1 -0
  130. package/dist/features/sonner/SonnerContext.d.ts +29 -0
  131. package/dist/features/sonner/SonnerContext.d.ts.map +1 -0
  132. package/dist/features/theme/ThemeProvider.d.ts +11 -0
  133. package/dist/features/theme/ThemeProvider.d.ts.map +1 -0
  134. package/dist/features/theme/themes.d.ts +114 -0
  135. package/dist/features/theme/themes.d.ts.map +1 -0
  136. package/dist/features/theme/useTheme.d.ts +10 -0
  137. package/dist/features/theme/useTheme.d.ts.map +1 -0
  138. package/dist/i18n/I18nProvider.d.ts +9 -0
  139. package/dist/i18n/I18nProvider.d.ts.map +1 -0
  140. package/dist/i18n/config.d.ts +23 -0
  141. package/dist/i18n/config.d.ts.map +1 -0
  142. package/dist/i18n/translations/en/common.json.d.ts +19 -0
  143. package/dist/i18n/translations/en/cookieConsent.json.d.ts +53 -0
  144. package/dist/i18n/translations/en/settings.json.d.ts +358 -0
  145. package/dist/i18n/translations/fr/common.json.d.ts +19 -0
  146. package/dist/i18n/translations/fr/cookieConsent.json.d.ts +53 -0
  147. package/dist/i18n/translations/fr/settings.json.d.ts +358 -0
  148. package/dist/index-CfvdAI_Y.js +2168 -0
  149. package/dist/index-CfvdAI_Y.js.map +1 -0
  150. package/dist/index.d.ts +7 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +12 -0
  153. package/dist/index.js.map +1 -0
  154. package/dist/lib/utils.d.ts +3 -0
  155. package/dist/lib/utils.d.ts.map +1 -0
  156. package/dist/lib/z-index.d.ts +29 -0
  157. package/dist/lib/z-index.d.ts.map +1 -0
  158. package/dist/router/router.d.ts +3 -0
  159. package/dist/router/router.d.ts.map +1 -0
  160. package/dist/router/routes.d.ts +4 -0
  161. package/dist/router/routes.d.ts.map +1 -0
  162. package/dist/sidebar-Dt-gibIZ.js +336 -0
  163. package/dist/sidebar-Dt-gibIZ.js.map +1 -0
  164. package/dist/style.css +1 -0
  165. package/dist/switch-CuKXfl3x.js +44 -0
  166. package/dist/switch-CuKXfl3x.js.map +1 -0
  167. package/dist/types.js +2 -0
  168. package/dist/types.js.map +1 -0
  169. package/package.json +16 -14
  170. package/src/features/config/ConfigProvider.ts +20 -5
  171. package/src/features/config/useConfig.ts +14 -1
  172. package/src/index.ts +2 -2
@@ -0,0 +1,406 @@
1
+ import { jsx as e, jsxs as h, Fragment as O } from "react/jsx-runtime";
2
+ import { useLocation as M, Outlet as F, Link as I } from "react-router";
3
+ import { useMemo as j, useEffect as P, useState as C, useRef as G, useLayoutEffect as H } from "react";
4
+ import { useTranslation as R } from "react-i18next";
5
+ import { shellui as L } from "@shellui/sdk";
6
+ import { S as V, a as U, b as X, c as Z, d as q, e as J, f as K, g as Q, h as T, i as B, j as Y } from "./sidebar-Dt-gibIZ.js";
7
+ import { f as z, s as ee, b as $, d as ne, c as u, Z as te, r as re } from "./index-CfvdAI_Y.js";
8
+ import { L as oe, O as se } from "./OverlayShell-kDY56DaN.js";
9
+ const W = (n) => {
10
+ try {
11
+ const o = new URL(n).hostname;
12
+ return o ? `https://icons.duckduckgo.com/ip3/${o}.ico` : null;
13
+ } catch {
14
+ return null;
15
+ }
16
+ }, E = ({
17
+ navigation: n
18
+ }) => {
19
+ const a = M(), { i18n: o } = R(), s = o.language || "en", b = (t, l) => typeof t == "string" ? t : t[l] || t.en || t.fr || Object.values(t)[0] || "", f = j(() => n.some((t) => "title" in t && "items" in t ? t.items.some((l) => !!l.icon) : !!t.icon), [n]), c = (t) => "title" in t && "items" in t, d = (t) => {
20
+ const l = `/${t.path}`, m = t.openIn === "modal" || t.openIn === "drawer", p = t.openIn === "external", r = !m && !p && (a.pathname === l || a.pathname.startsWith(`${l}/`)), i = b(t.label, s), g = p && !t.icon ? W(t.url) : null, x = t.icon ?? g ?? null, v = x ? /* @__PURE__ */ e(
21
+ "img",
22
+ {
23
+ src: x,
24
+ alt: "",
25
+ className: u("h-4 w-4", "shrink-0")
26
+ }
27
+ ) : f ? /* @__PURE__ */ e("span", { className: "h-4 w-4 shrink-0" }) : null, w = /* @__PURE__ */ h(O, { children: [
28
+ v,
29
+ /* @__PURE__ */ e("span", { className: "truncate", children: i }),
30
+ p ? /* @__PURE__ */ e(pe, { className: "ml-auto h-4 w-4 shrink-0 opacity-70" }) : null
31
+ ] }), N = t.openIn === "modal" ? /* @__PURE__ */ e(
32
+ "button",
33
+ {
34
+ type: "button",
35
+ onClick: () => L.openModal(t.url),
36
+ className: "flex items-center gap-2 w-full cursor-pointer text-left",
37
+ children: w
38
+ }
39
+ ) : t.openIn === "drawer" ? /* @__PURE__ */ e(
40
+ "button",
41
+ {
42
+ type: "button",
43
+ onClick: () => L.openDrawer({ url: t.url, position: t.drawerPosition }),
44
+ className: "flex items-center gap-2 w-full cursor-pointer text-left",
45
+ children: w
46
+ }
47
+ ) : t.openIn === "external" ? /* @__PURE__ */ e(
48
+ "a",
49
+ {
50
+ href: t.url,
51
+ target: "_blank",
52
+ rel: "noopener noreferrer",
53
+ className: "flex items-center gap-2 w-full",
54
+ children: w
55
+ }
56
+ ) : /* @__PURE__ */ e(
57
+ I,
58
+ {
59
+ to: `/${t.path}`,
60
+ className: "flex items-center gap-2 w-full",
61
+ children: w
62
+ }
63
+ );
64
+ return /* @__PURE__ */ e(
65
+ Y,
66
+ {
67
+ asChild: !0,
68
+ isActive: r,
69
+ className: u("w-full", r && "bg-sidebar-accent text-sidebar-accent-foreground"),
70
+ children: N
71
+ }
72
+ );
73
+ };
74
+ return /* @__PURE__ */ e(O, { children: n.map((t) => {
75
+ if (c(t)) {
76
+ const l = b(t.title, s);
77
+ return /* @__PURE__ */ h(
78
+ J,
79
+ {
80
+ className: "mt-0",
81
+ children: [
82
+ /* @__PURE__ */ e(K, { className: "mb-1", children: l }),
83
+ /* @__PURE__ */ e(Q, { children: /* @__PURE__ */ e(T, { className: "gap-0.5", children: t.items.map((m) => /* @__PURE__ */ e(B, { children: d(m) }, m.path)) }) })
84
+ ]
85
+ },
86
+ l
87
+ );
88
+ } else
89
+ return /* @__PURE__ */ e(
90
+ T,
91
+ {
92
+ className: "gap-0.5",
93
+ children: /* @__PURE__ */ e(B, { children: d(t) })
94
+ },
95
+ t.path
96
+ );
97
+ }) });
98
+ }, ae = ({
99
+ title: n,
100
+ logo: a,
101
+ startNav: o,
102
+ endItems: s
103
+ }) => /* @__PURE__ */ h(O, { children: [
104
+ /* @__PURE__ */ e(X, { className: "border-b border-sidebar-border pb-4", children: (n || a) && /* @__PURE__ */ e(
105
+ I,
106
+ {
107
+ to: "/",
108
+ className: "flex items-center pl-1 pr-3 py-2 text-lg font-semibold text-sidebar-foreground hover:text-sidebar-foreground/80 transition-colors",
109
+ children: a && a.trim() ? /* @__PURE__ */ e(
110
+ "img",
111
+ {
112
+ src: a,
113
+ alt: n || "Logo",
114
+ className: "h-5 w-auto shrink-0 object-contain sidebar-logo"
115
+ }
116
+ ) : n ? /* @__PURE__ */ e("span", { className: "leading-none", children: n }) : null
117
+ }
118
+ ) }),
119
+ /* @__PURE__ */ e(Z, { className: "gap-1", children: /* @__PURE__ */ e(E, { navigation: o }) }),
120
+ s.length > 0 && /* @__PURE__ */ e(q, { children: /* @__PURE__ */ e(E, { navigation: s }) })
121
+ ] });
122
+ function ie(n, a) {
123
+ return typeof n == "string" ? n : n[a] || n.en || n.fr || Object.values(n)[0] || "";
124
+ }
125
+ const le = 64, A = 4, ce = 12, de = 6, he = (n) => n.startsWith("/icons/"), ue = ({
126
+ item: n,
127
+ label: a,
128
+ isActive: o,
129
+ iconSrc: s,
130
+ applyIconTheme: b
131
+ }) => {
132
+ const f = `/${n.path}`, c = /* @__PURE__ */ h("span", { className: "flex flex-col items-center justify-center gap-1 w-full min-w-0 max-w-full overflow-hidden", children: [
133
+ s ? /* @__PURE__ */ e(
134
+ "img",
135
+ {
136
+ src: s,
137
+ alt: "",
138
+ className: u(
139
+ "size-4 shrink-0 rounded-sm object-cover",
140
+ b && "opacity-90 dark:opacity-100 dark:invert"
141
+ )
142
+ }
143
+ ) : /* @__PURE__ */ e("span", { className: "size-4 shrink-0 rounded-sm bg-muted" }),
144
+ /* @__PURE__ */ e("span", { className: "text-[11px] leading-tight truncate w-full min-w-0 text-center block", children: a })
145
+ ] }), d = u(
146
+ "flex flex-col items-center justify-center rounded-md py-1.5 px-2 min-w-0 max-w-full transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
147
+ o ? "bg-accent text-accent-foreground [&_span]:text-accent-foreground" : "text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground [&_span]:inherit"
148
+ );
149
+ return n.openIn === "modal" ? /* @__PURE__ */ e(
150
+ "button",
151
+ {
152
+ type: "button",
153
+ onClick: () => L.openModal(n.url),
154
+ className: d,
155
+ children: c
156
+ }
157
+ ) : n.openIn === "drawer" ? /* @__PURE__ */ e(
158
+ "button",
159
+ {
160
+ type: "button",
161
+ onClick: () => L.openDrawer({ url: n.url, position: n.drawerPosition }),
162
+ className: d,
163
+ children: c
164
+ }
165
+ ) : n.openIn === "external" ? /* @__PURE__ */ e(
166
+ "a",
167
+ {
168
+ href: n.url,
169
+ target: "_blank",
170
+ rel: "noopener noreferrer",
171
+ className: d,
172
+ children: c
173
+ }
174
+ ) : /* @__PURE__ */ e(
175
+ I,
176
+ {
177
+ to: f,
178
+ className: d,
179
+ children: c
180
+ }
181
+ );
182
+ }, pe = ({ className: n }) => /* @__PURE__ */ h(
183
+ "svg",
184
+ {
185
+ xmlns: "http://www.w3.org/2000/svg",
186
+ width: "24",
187
+ height: "24",
188
+ viewBox: "0 0 24 24",
189
+ fill: "none",
190
+ stroke: "currentColor",
191
+ strokeWidth: "2",
192
+ strokeLinecap: "round",
193
+ strokeLinejoin: "round",
194
+ className: u("shrink-0", n),
195
+ "aria-hidden": !0,
196
+ children: [
197
+ /* @__PURE__ */ e("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
198
+ /* @__PURE__ */ e("polyline", { points: "15 3 21 3 21 9" }),
199
+ /* @__PURE__ */ e("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
200
+ ]
201
+ }
202
+ ), fe = ({ className: n }) => /* @__PURE__ */ e(
203
+ "svg",
204
+ {
205
+ xmlns: "http://www.w3.org/2000/svg",
206
+ width: "24",
207
+ height: "24",
208
+ viewBox: "0 0 24 24",
209
+ fill: "none",
210
+ stroke: "currentColor",
211
+ strokeWidth: "2",
212
+ strokeLinecap: "round",
213
+ strokeLinejoin: "round",
214
+ className: u("shrink-0", n),
215
+ "aria-hidden": !0,
216
+ children: /* @__PURE__ */ e("path", { d: "m18 15-6-6-6 6" })
217
+ }
218
+ ), me = ({ className: n }) => /* @__PURE__ */ e(
219
+ "svg",
220
+ {
221
+ xmlns: "http://www.w3.org/2000/svg",
222
+ width: "24",
223
+ height: "24",
224
+ viewBox: "0 0 24 24",
225
+ fill: "none",
226
+ stroke: "currentColor",
227
+ strokeWidth: "2",
228
+ strokeLinecap: "round",
229
+ strokeLinejoin: "round",
230
+ className: u("shrink-0", n),
231
+ "aria-hidden": !0,
232
+ children: /* @__PURE__ */ e("path", { d: "m6 9 6 6 6-6" })
233
+ }
234
+ ), ge = ({ className: n }) => /* @__PURE__ */ h(
235
+ "svg",
236
+ {
237
+ xmlns: "http://www.w3.org/2000/svg",
238
+ width: "24",
239
+ height: "24",
240
+ viewBox: "0 0 24 24",
241
+ fill: "none",
242
+ stroke: "currentColor",
243
+ strokeWidth: "2",
244
+ strokeLinecap: "round",
245
+ strokeLinejoin: "round",
246
+ className: u("shrink-0", n),
247
+ "aria-hidden": !0,
248
+ children: [
249
+ /* @__PURE__ */ e("path", { d: "m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
250
+ /* @__PURE__ */ e("polyline", { points: "9 22 9 12 15 12 15 22" })
251
+ ]
252
+ }
253
+ ), be = ({
254
+ items: n,
255
+ currentLanguage: a
256
+ }) => {
257
+ const o = M(), [s, b] = C(!1), f = G(null), [c, d] = C(0);
258
+ H(() => {
259
+ const r = f.current;
260
+ if (!r) return;
261
+ const i = new ResizeObserver((g) => {
262
+ const x = g[0]?.contentRect.width ?? 0;
263
+ d(x);
264
+ });
265
+ return i.observe(r), d(r.getBoundingClientRect().width), () => i.disconnect();
266
+ }, []);
267
+ const { rowItems: t, overflowItems: l, hasMore: m } = j(() => {
268
+ const r = n.slice(), i = Math.max(0, c - ce * 2), g = le + A, x = c > 0 ? Math.floor((i + A) / g) : 5, v = Math.min(Math.max(0, x), de), k = v - 1, N = r.length <= k ? r.length : Math.max(0, v - 2), y = r.slice(0, N), D = new Set(y.map((S) => S.path)), _ = r.filter((S) => !D.has(S.path));
269
+ return {
270
+ rowItems: y,
271
+ overflowItems: _,
272
+ hasMore: _.length > 0
273
+ };
274
+ }, [n, c]);
275
+ P(() => {
276
+ b(!1);
277
+ }, [o.pathname]);
278
+ const p = (r, i) => {
279
+ const g = `/${r.path}`, v = !(r.openIn === "modal" || r.openIn === "drawer" || r.openIn === "external") && (o.pathname === g || o.pathname.startsWith(`${g}/`)), k = re(r.label, a), w = r.openIn === "external" && !r.icon ? W(r.url) : null, N = r.icon ?? w ?? null, y = N ? he(N) : !1;
280
+ return /* @__PURE__ */ e(
281
+ ue,
282
+ {
283
+ item: r,
284
+ label: k,
285
+ isActive: v,
286
+ iconSrc: N,
287
+ applyIconTheme: y
288
+ },
289
+ `${r.path}-${r.url}-${i}`
290
+ );
291
+ };
292
+ return /* @__PURE__ */ h(
293
+ "nav",
294
+ {
295
+ ref: f,
296
+ className: "fixed bottom-0 left-0 right-0 z-[9999] md:hidden border-t border-sidebar-border bg-sidebar-background overflow-hidden pt-2",
297
+ style: {
298
+ zIndex: te.SIDEBAR_TRIGGER,
299
+ paddingBottom: "calc(0.5rem + env(safe-area-inset-bottom, 0px))"
300
+ },
301
+ children: [
302
+ /* @__PURE__ */ h("div", { className: "flex flex-row flex-nowrap items-center justify-center gap-1 px-3 overflow-x-hidden", children: [
303
+ /* @__PURE__ */ h(
304
+ I,
305
+ {
306
+ to: "/",
307
+ className: u(
308
+ "flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
309
+ o.pathname === "/" || o.pathname === "" ? "bg-sidebar-accent text-sidebar-accent-foreground [&_span]:text-sidebar-accent-foreground" : "text-sidebar-foreground/80 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground [&_span]:inherit"
310
+ ),
311
+ "aria-label": "Home",
312
+ children: [
313
+ /* @__PURE__ */ e("span", { className: "size-4 shrink-0 flex items-center justify-center [&_svg]:text-current", children: /* @__PURE__ */ e(ge, { className: "size-4" }) }),
314
+ /* @__PURE__ */ e("span", { className: "text-[11px] leading-tight", children: "Home" })
315
+ ]
316
+ }
317
+ ),
318
+ t.map((r, i) => p(r, i)),
319
+ m && /* @__PURE__ */ h(
320
+ "button",
321
+ {
322
+ type: "button",
323
+ onClick: () => b((r) => !r),
324
+ className: u(
325
+ "flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer",
326
+ "text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
327
+ ),
328
+ "aria-expanded": s,
329
+ "aria-label": s ? "Show less" : "Show more",
330
+ children: [
331
+ /* @__PURE__ */ e("span", { className: "size-4 shrink-0 flex items-center justify-center", children: s ? /* @__PURE__ */ e(me, { className: "size-4" }) : /* @__PURE__ */ e(fe, { className: "size-4" }) }),
332
+ /* @__PURE__ */ e("span", { className: "text-[11px] leading-tight", children: s ? "Less" : "More" })
333
+ ]
334
+ }
335
+ )
336
+ ] }),
337
+ /* @__PURE__ */ e(
338
+ "div",
339
+ {
340
+ className: u(
341
+ "grid transition-[grid-template-rows] duration-300 ease-out",
342
+ s ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
343
+ ),
344
+ children: /* @__PURE__ */ e("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ e("div", { className: "px-4 pt-3 pb-2 border-t border-sidebar-border/50 mt-1", children: /* @__PURE__ */ e("div", { className: "grid grid-cols-5 gap-2 justify-items-center max-w-xs mx-auto", children: s ? l.map((r, i) => p(r, i)) : null }) }) })
345
+ }
346
+ )
347
+ ]
348
+ }
349
+ );
350
+ }, xe = ({ title: n, logo: a, navigation: o }) => {
351
+ const s = M(), { i18n: b } = R(), f = b.language || "en", { startNav: c, endItems: d, navigationItems: t, mobileNavItems: l } = j(() => {
352
+ const m = z(o, "desktop"), p = z(o, "mobile"), { start: r, end: i } = ee(m), g = $(m), x = $(p);
353
+ return {
354
+ startNav: ne(r),
355
+ endItems: i,
356
+ navigationItems: g,
357
+ mobileNavItems: x
358
+ };
359
+ }, [o]);
360
+ return P(() => {
361
+ if (!n) return;
362
+ const p = (s.pathname.replace(/^\/+|\/+$/g, "") || "").split("/")[0];
363
+ if (!p) {
364
+ document.title = n;
365
+ return;
366
+ }
367
+ const r = t.find((i) => i.path === p);
368
+ if (r) {
369
+ const i = ie(r.label, f);
370
+ document.title = `${i} | ${n}`;
371
+ } else
372
+ document.title = n;
373
+ }, [s.pathname, n, t, f]), /* @__PURE__ */ e(oe, { children: /* @__PURE__ */ e(V, { children: /* @__PURE__ */ h(se, { navigationItems: t, children: [
374
+ /* @__PURE__ */ h("div", { className: "flex h-screen overflow-hidden", children: [
375
+ /* @__PURE__ */ e(U, { className: u("hidden md:flex shrink-0"), children: /* @__PURE__ */ e(
376
+ ae,
377
+ {
378
+ title: n,
379
+ logo: a,
380
+ startNav: c,
381
+ endItems: d
382
+ }
383
+ ) }),
384
+ /* @__PURE__ */ e("main", { className: "flex-1 flex flex-col overflow-hidden bg-background relative min-w-0", children: /* @__PURE__ */ e("div", { className: "flex-1 flex flex-col overflow-auto pb-16 md:pb-0", children: /* @__PURE__ */ e(F, {}) }) })
385
+ ] }),
386
+ /* @__PURE__ */ e(
387
+ be,
388
+ {
389
+ items: l,
390
+ currentLanguage: f
391
+ }
392
+ )
393
+ ] }) }) });
394
+ }, Oe = ({ title: n, appIcon: a, logo: o, navigation: s }) => /* @__PURE__ */ e(
395
+ xe,
396
+ {
397
+ title: n,
398
+ appIcon: a,
399
+ logo: o,
400
+ navigation: s
401
+ }
402
+ );
403
+ export {
404
+ Oe as DefaultLayout
405
+ };
406
+ //# sourceMappingURL=DefaultLayout-D3IpgS4j.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultLayout-D3IpgS4j.js","sources":["../src/features/layouts/DefaultLayout.tsx"],"sourcesContent":["import { Link, useLocation, Outlet } from 'react-router';\nimport { useMemo, useEffect, useState, useRef, useLayoutEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport {\n Sidebar,\n SidebarProvider,\n SidebarHeader,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuItem,\n SidebarMenuButton,\n} from '@/components/ui/sidebar';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\nimport {\n filterNavigationByViewport,\n filterNavigationForSidebar,\n flattenNavigationItems,\n resolveLocalizedString as resolveNavLabel,\n splitNavigationByPosition,\n} from './utils';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\n\ninterface DefaultLayoutProps {\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\n// DuckDuckGo favicon URL for a given page URL (used when openIn === 'external' and no icon is set)\nconst getExternalFaviconUrl = (url: string): string | null => {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n if (!hostname) return null;\n return `https://icons.duckduckgo.com/ip3/${hostname}.ico`;\n } catch {\n return null;\n }\n};\n\nconst NavigationContent = ({\n navigation,\n}: {\n navigation: (NavigationItem | NavigationGroup)[];\n}) => {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n // Helper function to resolve localized strings\n const resolveLocalizedString = (\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n ): string => {\n if (typeof value === 'string') {\n return value;\n }\n // Try current language first, then English as fallback\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n };\n\n // Check if at least one navigation item has an icon\n const hasAnyIcons = useMemo(() => {\n return navigation.some((item) => {\n if ('title' in item && 'items' in item) {\n // It's a group\n return (item as NavigationGroup).items.some((navItem) => !!navItem.icon);\n }\n // It's a standalone item\n return !!(item as NavigationItem).icon;\n });\n }, [navigation]);\n\n // Helper to check if an item is a group\n const isGroup = (item: NavigationItem | NavigationGroup): item is NavigationGroup => {\n return 'title' in item && 'items' in item;\n };\n\n // Render a single nav item link or modal/drawer trigger\n const renderNavItem = (navItem: NavigationItem) => {\n const pathPrefix = `/${navItem.path}`;\n const isOverlay = navItem.openIn === 'modal' || navItem.openIn === 'drawer';\n const isExternal = navItem.openIn === 'external';\n const isActive =\n !isOverlay &&\n !isExternal &&\n (location.pathname === pathPrefix || location.pathname.startsWith(`${pathPrefix}/`));\n const itemLabel = resolveLocalizedString(navItem.label, currentLanguage);\n const faviconUrl = isExternal && !navItem.icon ? getExternalFaviconUrl(navItem.url) : null;\n const iconSrc = navItem.icon ?? faviconUrl ?? null;\n const iconEl = iconSrc ? (\n <img\n src={iconSrc}\n alt=\"\"\n className={cn('h-4 w-4', 'shrink-0')}\n />\n ) : hasAnyIcons ? (\n <span className=\"h-4 w-4 shrink-0\" />\n ) : null;\n const externalIcon = isExternal ? (\n <ExternalLinkIcon className=\"ml-auto h-4 w-4 shrink-0 opacity-70\" />\n ) : null;\n const content = (\n <>\n {iconEl}\n <span className=\"truncate\">{itemLabel}</span>\n {externalIcon}\n </>\n );\n const linkOrTrigger =\n navItem.openIn === 'modal' ? (\n <button\n type=\"button\"\n onClick={() => shellui.openModal(navItem.url)}\n className=\"flex items-center gap-2 w-full cursor-pointer text-left\"\n >\n {content}\n </button>\n ) : navItem.openIn === 'drawer' ? (\n <button\n type=\"button\"\n onClick={() => shellui.openDrawer({ url: navItem.url, position: navItem.drawerPosition })}\n className=\"flex items-center gap-2 w-full cursor-pointer text-left\"\n >\n {content}\n </button>\n ) : navItem.openIn === 'external' ? (\n <a\n href={navItem.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 w-full\"\n >\n {content}\n </a>\n ) : (\n <Link\n to={`/${navItem.path}`}\n className=\"flex items-center gap-2 w-full\"\n >\n {content}\n </Link>\n );\n return (\n <SidebarMenuButton\n asChild\n isActive={isActive}\n className={cn('w-full', isActive && 'bg-sidebar-accent text-sidebar-accent-foreground')}\n >\n {linkOrTrigger}\n </SidebarMenuButton>\n );\n };\n\n // Render navigation items - handle both groups and standalone items\n return (\n <>\n {navigation.map((item) => {\n if (isGroup(item)) {\n // Render as a group\n const groupTitle = resolveLocalizedString(item.title, currentLanguage);\n return (\n <SidebarGroup\n key={groupTitle}\n className=\"mt-0\"\n >\n <SidebarGroupLabel className=\"mb-1\">{groupTitle}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu className=\"gap-0.5\">\n {item.items.map((navItem) => (\n <SidebarMenuItem key={navItem.path}>{renderNavItem(navItem)}</SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n );\n } else {\n // Render as a standalone item\n return (\n <SidebarMenu\n key={item.path}\n className=\"gap-0.5\"\n >\n <SidebarMenuItem>{renderNavItem(item)}</SidebarMenuItem>\n </SidebarMenu>\n );\n }\n })}\n </>\n );\n};\n\n/** Reusable sidebar inner: header, main nav, footer. Used in desktop Sidebar and mobile Drawer. */\nconst SidebarInner = ({\n title,\n logo,\n startNav,\n endItems,\n}: {\n title?: string;\n logo?: string;\n startNav: (NavigationItem | NavigationGroup)[];\n endItems: (NavigationItem | NavigationGroup)[];\n}) => (\n <>\n <SidebarHeader className=\"border-b border-sidebar-border pb-4\">\n {(title || logo) && (\n <Link\n to=\"/\"\n className=\"flex items-center pl-1 pr-3 py-2 text-lg font-semibold text-sidebar-foreground hover:text-sidebar-foreground/80 transition-colors\"\n >\n {logo && logo.trim() ? (\n <img\n src={logo}\n alt={title || 'Logo'}\n className=\"h-5 w-auto shrink-0 object-contain sidebar-logo\"\n />\n ) : title ? (\n <span className=\"leading-none\">{title}</span>\n ) : null}\n </Link>\n )}\n </SidebarHeader>\n <SidebarContent className=\"gap-1\">\n <NavigationContent navigation={startNav} />\n </SidebarContent>\n {endItems.length > 0 && (\n <SidebarFooter>\n <NavigationContent navigation={endItems} />\n </SidebarFooter>\n )}\n </>\n);\n\nfunction resolveLocalizedLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Approximate width per slot (icon + label + padding) and gap for dynamic slot count. */\nconst BOTTOM_NAV_SLOT_WIDTH = 64;\nconst BOTTOM_NAV_GAP = 4;\nconst BOTTOM_NAV_PX = 12;\n/** Max slots in the row (Home + nav + optional More) to avoid overflow/duplicated wrap. */\nconst BOTTOM_NAV_MAX_SLOTS = 6;\n\n/** True when the icon is a local app icon (/icons/); external images (avatars, favicons) are shown as-is. */\nconst isAppIcon = (src: string) => src.startsWith('/icons/');\n\n/** Single nav item for bottom bar: icon + label, link or action. */\nconst BottomNavItem = ({\n item,\n label,\n isActive,\n iconSrc,\n applyIconTheme,\n}: {\n item: NavigationItem;\n label: string;\n isActive: boolean;\n iconSrc: string | null;\n applyIconTheme: boolean;\n}) => {\n const pathPrefix = `/${item.path}`;\n const content = (\n <span className=\"flex flex-col items-center justify-center gap-1 w-full min-w-0 max-w-full overflow-hidden\">\n {iconSrc ? (\n <img\n src={iconSrc}\n alt=\"\"\n className={cn(\n 'size-4 shrink-0 rounded-sm object-cover',\n applyIconTheme && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"size-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-[11px] leading-tight truncate w-full min-w-0 text-center block\">\n {label}\n </span>\n </span>\n );\n const baseClass = cn(\n 'flex flex-col items-center justify-center rounded-md py-1.5 px-2 min-w-0 max-w-full transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n isActive\n ? 'bg-accent text-accent-foreground [&_span]:text-accent-foreground'\n : 'text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground [&_span]:inherit',\n );\n if (item.openIn === 'modal') {\n return (\n <button\n type=\"button\"\n onClick={() => shellui.openModal(item.url)}\n className={baseClass}\n >\n {content}\n </button>\n );\n }\n if (item.openIn === 'drawer') {\n return (\n <button\n type=\"button\"\n onClick={() => shellui.openDrawer({ url: item.url, position: item.drawerPosition })}\n className={baseClass}\n >\n {content}\n </button>\n );\n }\n if (item.openIn === 'external') {\n return (\n <a\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={baseClass}\n >\n {content}\n </a>\n );\n }\n return (\n <Link\n to={pathPrefix}\n className={baseClass}\n >\n {content}\n </Link>\n );\n};\n\n/** Inline SVG: external-link icon. Bundled so consumers don't need to serve static SVGs. */\nconst ExternalLinkIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n);\n\n/** Caret up: expand (show second line). */\nconst CaretUpIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\n/** Caret down: collapse (hide second line). */\nconst CaretDownIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\n/** Home icon for mobile bottom bar (same as sidebar logo action). */\nconst HomeIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" />\n <polyline points=\"9 22 9 12 15 12 15 22\" />\n </svg>\n);\n\n/** Mobile bottom nav: Home + nav items; More only when not all fit. Dynamic from width. */\nconst MobileBottomNav = ({\n items,\n currentLanguage,\n}: {\n items: NavigationItem[];\n currentLanguage: string;\n}) => {\n const location = useLocation();\n const [expanded, setExpanded] = useState(false);\n const navRef = useRef<HTMLElement>(null);\n const [rowWidth, setRowWidth] = useState(0);\n\n useLayoutEffect(() => {\n const el = navRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n const w = entries[0]?.contentRect.width ?? 0;\n setRowWidth(w);\n });\n ro.observe(el);\n setRowWidth(el.getBoundingClientRect().width);\n return () => ro.disconnect();\n }, []);\n\n const { rowItems, overflowItems, hasMore } = useMemo(() => {\n const list = items.slice();\n const contentWidth = Math.max(0, rowWidth - BOTTOM_NAV_PX * 2);\n const slotTotal = BOTTOM_NAV_SLOT_WIDTH + BOTTOM_NAV_GAP;\n const computedSlots =\n rowWidth > 0 ? Math.floor((contentWidth + BOTTOM_NAV_GAP) / slotTotal) : 5;\n const totalSlots = Math.min(Math.max(0, computedSlots), BOTTOM_NAV_MAX_SLOTS);\n const slotsForNav = totalSlots - 1;\n const allFit = list.length <= slotsForNav;\n const maxInRow = allFit ? list.length : Math.max(0, totalSlots - 2);\n const row = list.slice(0, maxInRow);\n const rowPaths = new Set(row.map((i) => i.path));\n const overflow = list.filter((item) => !rowPaths.has(item.path));\n return {\n rowItems: row,\n overflowItems: overflow,\n hasMore: overflow.length > 0,\n };\n }, [items, rowWidth]);\n\n useEffect(() => {\n setExpanded(false);\n }, [location.pathname]);\n\n const renderItem = (item: NavigationItem, index: number) => {\n const pathPrefix = `/${item.path}`;\n const isOverlayOrExternal =\n item.openIn === 'modal' || item.openIn === 'drawer' || item.openIn === 'external';\n const isActive =\n !isOverlayOrExternal &&\n (location.pathname === pathPrefix || location.pathname.startsWith(`${pathPrefix}/`));\n const label = resolveNavLabel(item.label, currentLanguage);\n const faviconUrl =\n item.openIn === 'external' && !item.icon ? getExternalFaviconUrl(item.url) : null;\n const iconSrc = item.icon ?? faviconUrl ?? null;\n const applyIconTheme = iconSrc ? isAppIcon(iconSrc) : false;\n return (\n <BottomNavItem\n key={`${item.path}-${item.url}-${index}`}\n item={item}\n label={label}\n isActive={isActive}\n iconSrc={iconSrc}\n applyIconTheme={applyIconTheme}\n />\n );\n };\n\n return (\n <nav\n ref={navRef}\n className=\"fixed bottom-0 left-0 right-0 z-[9999] md:hidden border-t border-sidebar-border bg-sidebar-background overflow-hidden pt-2\"\n style={{\n zIndex: Z_INDEX.SIDEBAR_TRIGGER,\n paddingBottom: 'calc(0.5rem + env(safe-area-inset-bottom, 0px))',\n }}\n >\n {/* Top row: Home + nav items + More/Less — single row, no wrap */}\n <div className=\"flex flex-row flex-nowrap items-center justify-center gap-1 px-3 overflow-x-hidden\">\n <Link\n to=\"/\"\n className={cn(\n 'flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n location.pathname === '/' || location.pathname === ''\n ? 'bg-sidebar-accent text-sidebar-accent-foreground [&_span]:text-sidebar-accent-foreground'\n : 'text-sidebar-foreground/80 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground [&_span]:inherit',\n )}\n aria-label=\"Home\"\n >\n <span className=\"size-4 shrink-0 flex items-center justify-center [&_svg]:text-current\">\n <HomeIcon className=\"size-4\" />\n </span>\n <span className=\"text-[11px] leading-tight\">Home</span>\n </Link>\n {rowItems.map((item, i) => renderItem(item, i))}\n {hasMore && (\n <button\n type=\"button\"\n onClick={() => setExpanded((e) => !e)}\n className={cn(\n 'flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer',\n 'text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n )}\n aria-expanded={expanded}\n aria-label={expanded ? 'Show less' : 'Show more'}\n >\n <span className=\"size-4 shrink-0 flex items-center justify-center\">\n {expanded ? <CaretDownIcon className=\"size-4\" /> : <CaretUpIcon className=\"size-4\" />}\n </span>\n <span className=\"text-[11px] leading-tight\">{expanded ? 'Less' : 'More'}</span>\n </button>\n )}\n </div>\n\n {/* Expanded: only overflow items — render list only when expanded so it clears when collapsed */}\n <div\n className={cn(\n 'grid transition-[grid-template-rows] duration-300 ease-out',\n expanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',\n )}\n >\n <div className=\"min-h-0 overflow-hidden\">\n <div className=\"px-4 pt-3 pb-2 border-t border-sidebar-border/50 mt-1\">\n <div className=\"grid grid-cols-5 gap-2 justify-items-center max-w-xs mx-auto\">\n {expanded ? overflowItems.map((item, i) => renderItem(item, i)) : null}\n </div>\n </div>\n </div>\n </div>\n </nav>\n );\n};\n\nconst DefaultLayoutContent = ({ title, logo, navigation }: DefaultLayoutProps) => {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n const { startNav, endItems, navigationItems, mobileNavItems } = useMemo(() => {\n const desktopNav = filterNavigationByViewport(navigation, 'desktop');\n const mobileNav = filterNavigationByViewport(navigation, 'mobile');\n const { start, end } = splitNavigationByPosition(desktopNav);\n const flat = flattenNavigationItems(desktopNav);\n const mobileFlat = flattenNavigationItems(mobileNav);\n return {\n startNav: filterNavigationForSidebar(start),\n endItems: end,\n navigationItems: flat,\n mobileNavItems: mobileFlat,\n };\n }, [navigation]);\n\n useEffect(() => {\n if (!title) return;\n const pathname = location.pathname.replace(/^\\/+|\\/+$/g, '') || '';\n const segment = pathname.split('/')[0];\n if (!segment) {\n document.title = title;\n return;\n }\n const navItem = navigationItems.find((item) => item.path === segment);\n if (navItem) {\n const label = resolveLocalizedLabel(navItem.label, currentLanguage);\n document.title = `${label} | ${title}`;\n } else {\n document.title = title;\n }\n }, [location.pathname, title, navigationItems, currentLanguage]);\n\n return (\n <LayoutProviders>\n <SidebarProvider>\n <OverlayShell navigationItems={navigationItems}>\n <div className=\"flex h-screen overflow-hidden\">\n {/* Desktop sidebar: visible from md up */}\n <Sidebar className={cn('hidden md:flex shrink-0')}>\n <SidebarInner\n title={title}\n logo={logo}\n startNav={startNav}\n endItems={endItems}\n />\n </Sidebar>\n\n <main className=\"flex-1 flex flex-col overflow-hidden bg-background relative min-w-0\">\n <div className=\"flex-1 flex flex-col overflow-auto pb-16 md:pb-0\">\n <Outlet />\n </div>\n </main>\n </div>\n\n {/* Mobile bottom nav: visible only below md */}\n <MobileBottomNav\n items={mobileNavItems}\n currentLanguage={currentLanguage}\n />\n </OverlayShell>\n </SidebarProvider>\n </LayoutProviders>\n );\n};\n\nexport const DefaultLayout = ({ title, appIcon, logo, navigation }: DefaultLayoutProps) => {\n return (\n <DefaultLayoutContent\n title={title}\n appIcon={appIcon}\n logo={logo}\n navigation={navigation}\n />\n );\n};\n"],"names":["getExternalFaviconUrl","url","hostname","NavigationContent","navigation","location","useLocation","i18n","useTranslation","currentLanguage","resolveLocalizedString","value","lang","hasAnyIcons","useMemo","item","navItem","isGroup","renderNavItem","pathPrefix","isOverlay","isExternal","isActive","itemLabel","faviconUrl","iconSrc","iconEl","jsx","cn","content","jsxs","Fragment","ExternalLinkIcon","linkOrTrigger","shellui","Link","SidebarMenuButton","groupTitle","SidebarGroup","SidebarGroupLabel","SidebarGroupContent","SidebarMenu","SidebarMenuItem","SidebarInner","title","logo","startNav","endItems","SidebarHeader","SidebarContent","SidebarFooter","resolveLocalizedLabel","BOTTOM_NAV_SLOT_WIDTH","BOTTOM_NAV_GAP","BOTTOM_NAV_PX","BOTTOM_NAV_MAX_SLOTS","isAppIcon","src","BottomNavItem","label","applyIconTheme","baseClass","className","CaretUpIcon","CaretDownIcon","HomeIcon","MobileBottomNav","items","expanded","setExpanded","useState","navRef","useRef","rowWidth","setRowWidth","useLayoutEffect","el","ro","entries","w","rowItems","overflowItems","hasMore","list","contentWidth","slotTotal","computedSlots","totalSlots","slotsForNav","maxInRow","row","rowPaths","i","overflow","useEffect","renderItem","index","resolveNavLabel","Z_INDEX","e","DefaultLayoutContent","navigationItems","mobileNavItems","desktopNav","filterNavigationByViewport","mobileNav","start","end","splitNavigationByPosition","flat","flattenNavigationItems","mobileFlat","filterNavigationForSidebar","segment","LayoutProviders","SidebarProvider","OverlayShell","Sidebar","Outlet","DefaultLayout","appIcon"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { useMemo as l, useEffect as f } from "react";
3
+ import { useLocation as u, Outlet as p } from "react-router";
4
+ import { useTranslation as d } from "react-i18next";
5
+ import { b as h } from "./index-CfvdAI_Y.js";
6
+ import { L as g, O as b } from "./OverlayShell-kDY56DaN.js";
7
+ function L(e, n) {
8
+ return typeof e == "string" ? e : e[n] || e.en || e.fr || Object.values(e)[0] || "";
9
+ }
10
+ function w({ title: e, navigation: n }) {
11
+ const a = u(), { i18n: m } = d(), s = m.language || "en", o = l(() => h(n), [n]);
12
+ return f(() => {
13
+ if (!e) return;
14
+ const c = (a.pathname.replace(/^\/+|\/+$/g, "") || "").split("/")[0];
15
+ if (!c) {
16
+ document.title = e;
17
+ return;
18
+ }
19
+ const i = o.find((r) => r.path === c);
20
+ if (i) {
21
+ const r = L(i.label, s);
22
+ document.title = `${r} | ${e}`;
23
+ } else
24
+ document.title = e;
25
+ }, [a.pathname, e, o, s]), /* @__PURE__ */ t(g, { children: /* @__PURE__ */ t(b, { navigationItems: o, children: /* @__PURE__ */ t("main", { className: "flex flex-col w-full h-screen overflow-hidden bg-background", children: /* @__PURE__ */ t(p, {}) }) }) });
26
+ }
27
+ export {
28
+ w as FullscreenLayout
29
+ };
30
+ //# sourceMappingURL=FullscreenLayout-Do9vAfl8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FullscreenLayout-Do9vAfl8.js","sources":["../src/features/layouts/FullscreenLayout.tsx"],"sourcesContent":["import { useMemo, useEffect } from 'react';\nimport { Outlet, useLocation } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport { flattenNavigationItems } from './utils';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\n\ninterface FullscreenLayoutProps {\n title?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nfunction resolveLocalizedLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Full-width layout with no sidebar or navigation; only content area. Modal, drawer and providers are still active. */\nexport function FullscreenLayout({ title, navigation }: FullscreenLayoutProps) {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n const navigationItems = useMemo(() => flattenNavigationItems(navigation), [navigation]);\n\n useEffect(() => {\n if (!title) return;\n const pathname = location.pathname.replace(/^\\/+|\\/+$/g, '') || '';\n const segment = pathname.split('/')[0];\n if (!segment) {\n document.title = title;\n return;\n }\n const navItem = navigationItems.find((item) => item.path === segment);\n if (navItem) {\n const label = resolveLocalizedLabel(navItem.label, currentLanguage);\n document.title = `${label} | ${title}`;\n } else {\n document.title = title;\n }\n }, [location.pathname, title, navigationItems, currentLanguage]);\n\n return (\n <LayoutProviders>\n <OverlayShell navigationItems={navigationItems}>\n <main className=\"flex flex-col w-full h-screen overflow-hidden bg-background\">\n <Outlet />\n </main>\n </OverlayShell>\n </LayoutProviders>\n );\n}\n"],"names":["resolveLocalizedLabel","value","lang","FullscreenLayout","title","navigation","location","useLocation","i18n","useTranslation","currentLanguage","navigationItems","useMemo","flattenNavigationItems","useEffect","segment","navItem","item","label","jsx","LayoutProviders","OverlayShell","Outlet"],"mappings":";;;;;;AAaA,SAASA,EACPC,GACAC,GACQ;AACR,SAAI,OAAOD,KAAU,WAAiBA,IAC/BA,EAAMC,CAAI,KAAKD,EAAM,MAAMA,EAAM,MAAM,OAAO,OAAOA,CAAK,EAAE,CAAC,KAAK;AAC3E;AAGO,SAASE,EAAiB,EAAE,OAAAC,GAAO,YAAAC,KAAqC;AAC7E,QAAMC,IAAWC,EAAA,GACX,EAAE,MAAAC,EAAA,IAASC,EAAA,GACXC,IAAkBF,EAAK,YAAY,MACnCG,IAAkBC,EAAQ,MAAMC,EAAuBR,CAAU,GAAG,CAACA,CAAU,CAAC;AAEtF,SAAAS,EAAU,MAAM;AACd,QAAI,CAACV,EAAO;AAEZ,UAAMW,KADWT,EAAS,SAAS,QAAQ,cAAc,EAAE,KAAK,IACvC,MAAM,GAAG,EAAE,CAAC;AACrC,QAAI,CAACS,GAAS;AACZ,eAAS,QAAQX;AACjB;AAAA,IACF;AACA,UAAMY,IAAUL,EAAgB,KAAK,CAACM,MAASA,EAAK,SAASF,CAAO;AACpE,QAAIC,GAAS;AACX,YAAME,IAAQlB,EAAsBgB,EAAQ,OAAON,CAAe;AAClE,eAAS,QAAQ,GAAGQ,CAAK,MAAMd,CAAK;AAAA,IACtC;AACE,eAAS,QAAQA;AAAA,EAErB,GAAG,CAACE,EAAS,UAAUF,GAAOO,GAAiBD,CAAe,CAAC,GAG7D,gBAAAS,EAACC,GAAA,EACC,UAAA,gBAAAD,EAACE,GAAA,EAAa,iBAAAV,GACZ,UAAA,gBAAAQ,EAAC,QAAA,EAAK,WAAU,+DACd,UAAA,gBAAAA,EAACG,GAAA,EAAO,EAAA,CACV,GACF,GACF;AAEJ;"}
@@ -0,0 +1,21 @@
1
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
2
+ import { useTranslation as i } from "react-i18next";
3
+ import { u as l } from "./index-CfvdAI_Y.js";
4
+ const c = () => {
5
+ const { t } = i("common"), { config: o } = l();
6
+ return /* @__PURE__ */ r("div", { className: "flex flex-col items-center justify-center h-full p-8 md:p-10", children: [
7
+ /* @__PURE__ */ e(
8
+ "h1",
9
+ {
10
+ className: "m-0 text-3xl font-light text-foreground",
11
+ style: { fontFamily: "var(--heading-font-family, inherit)" },
12
+ children: t("welcome", { title: o.title })
13
+ }
14
+ ),
15
+ /* @__PURE__ */ e("p", { className: "mt-4 text-lg text-muted-foreground", children: t("getStarted") })
16
+ ] });
17
+ };
18
+ export {
19
+ c as HomeView
20
+ };
21
+ //# sourceMappingURL=HomeView-DwckTuxz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HomeView-DwckTuxz.js","sources":["../src/components/HomeView.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next';\nimport { useConfig } from '../features/config/useConfig';\n\nexport const HomeView = () => {\n const { t } = useTranslation('common');\n const { config } = useConfig();\n\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-8 md:p-10\">\n <h1\n className=\"m-0 text-3xl font-light text-foreground\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('welcome', { title: config.title })}\n </h1>\n <p className=\"mt-4 text-lg text-muted-foreground\">{t('getStarted')}</p>\n </div>\n );\n};\n"],"names":["HomeView","useTranslation","config","useConfig","jsxs","jsx"],"mappings":";;;AAGO,MAAMA,IAAW,MAAM;AAC5B,QAAM,EAAE,EAAA,IAAMC,EAAe,QAAQ,GAC/B,EAAE,QAAAC,EAAA,IAAWC,EAAA;AAEnB,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAU,gEACb,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,YAAY,sCAAA;AAAA,QAEpB,YAAE,WAAW,EAAE,OAAOH,EAAO,OAAO;AAAA,MAAA;AAAA,IAAA;AAAA,sBAEtC,KAAA,EAAE,WAAU,sCAAsC,UAAA,EAAE,YAAY,EAAA,CAAE;AAAA,EAAA,GACrE;AAEJ;"}
@@ -0,0 +1,52 @@
1
+ import { jsxs as a, jsx as r } from "react/jsx-runtime";
2
+ import { useTranslation as g } from "react-i18next";
3
+ import { shellui as u } from "@shellui/sdk";
4
+ import { u as m } from "./index-CfvdAI_Y.js";
5
+ const x = (t) => t.length === 0 ? [] : t.flatMap((n) => "title" in n && "items" in n ? n.items : n), v = () => {
6
+ const { config: t } = m(), { i18n: n } = g(), l = n.language || "en", s = (e, o) => typeof e == "string" ? e : e[o] || e.en || e.fr || Object.values(e)[0] || "", i = t?.navigation && t.navigation.length > 0 ? x(t.navigation).filter((e) => !e.hidden).filter((e, o, f) => o === f.findIndex((d) => d.path === e.path)) : [], c = (e) => {
7
+ u.navigate(e.startsWith("/") ? e : `/${e}`);
8
+ };
9
+ return /* @__PURE__ */ a("div", { className: "flex flex-col min-h-full", children: [
10
+ /* @__PURE__ */ a("div", { className: "flex-1 flex flex-col items-center justify-center px-6 py-12 text-muted-foreground", children: [
11
+ /* @__PURE__ */ r("span", { className: "text-6xl font-light tracking-tighter text-foreground/80 select-none", children: "404" }),
12
+ /* @__PURE__ */ r("p", { className: "mt-3 text-lg text-muted-foreground", children: "Page not found" })
13
+ ] }),
14
+ i.length > 0 && /* @__PURE__ */ r("footer", { className: "border-t border-border py-4 px-6 mt-auto bg-muted/30", children: /* @__PURE__ */ r(
15
+ "nav",
16
+ {
17
+ className: "flex flex-row flex-wrap justify-center items-center gap-x-2 gap-y-1 text-sm text-muted-foreground",
18
+ "aria-label": "Available pages",
19
+ children: i.map((e, o) => /* @__PURE__ */ a(
20
+ "span",
21
+ {
22
+ className: "inline-flex items-center gap-x-2",
23
+ children: [
24
+ o > 0 && /* @__PURE__ */ r(
25
+ "span",
26
+ {
27
+ className: "text-border select-none",
28
+ "aria-hidden": !0,
29
+ children: "·"
30
+ }
31
+ ),
32
+ /* @__PURE__ */ r(
33
+ "button",
34
+ {
35
+ type: "button",
36
+ onClick: () => c(`/${e.path}`),
37
+ className: "text-muted-foreground hover:text-foreground hover:underline underline-offset-2 cursor-pointer bg-transparent border-0 p-0 font-normal",
38
+ children: s(e.label, l)
39
+ }
40
+ )
41
+ ]
42
+ },
43
+ e.path
44
+ ))
45
+ }
46
+ ) })
47
+ ] });
48
+ };
49
+ export {
50
+ v as NotFoundView
51
+ };
52
+ //# sourceMappingURL=NotFoundView-DD7azhz-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotFoundView-DD7azhz-.js","sources":["../src/components/NotFoundView.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { useConfig } from '@/features/config/useConfig';\nimport type { NavigationItem, NavigationGroup } from '@/features/config/types';\n\nconst flattenNavigationItems = (\n navigation: (NavigationItem | NavigationGroup)[],\n): NavigationItem[] => {\n if (navigation.length === 0) return [];\n return navigation.flatMap((item) => {\n if ('title' in item && 'items' in item) {\n return (item as NavigationGroup).items;\n }\n return item as NavigationItem;\n });\n};\n\nexport const NotFoundView = () => {\n const { config } = useConfig();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n const resolveLocalizedString = (\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n ): string => {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n };\n\n const navItems =\n config?.navigation && config.navigation.length > 0\n ? flattenNavigationItems(config.navigation)\n .filter((item) => !item.hidden)\n .filter((item, index, self) => index === self.findIndex((i) => i.path === item.path))\n : [];\n\n const handleNavigate = (path: string) => {\n shellui.navigate(path.startsWith('/') ? path : `/${path}`);\n };\n\n return (\n <div className=\"flex flex-col min-h-full\">\n <div className=\"flex-1 flex flex-col items-center justify-center px-6 py-12 text-muted-foreground\">\n <span className=\"text-6xl font-light tracking-tighter text-foreground/80 select-none\">\n 404\n </span>\n <p className=\"mt-3 text-lg text-muted-foreground\">Page not found</p>\n </div>\n\n {navItems.length > 0 && (\n <footer className=\"border-t border-border py-4 px-6 mt-auto bg-muted/30\">\n <nav\n className=\"flex flex-row flex-wrap justify-center items-center gap-x-2 gap-y-1 text-sm text-muted-foreground\"\n aria-label=\"Available pages\"\n >\n {navItems.map((item, index) => (\n <span\n key={item.path}\n className=\"inline-flex items-center gap-x-2\"\n >\n {index > 0 && (\n <span\n className=\"text-border select-none\"\n aria-hidden\n >\n ·\n </span>\n )}\n <button\n type=\"button\"\n onClick={() => handleNavigate(`/${item.path}`)}\n className=\"text-muted-foreground hover:text-foreground hover:underline underline-offset-2 cursor-pointer bg-transparent border-0 p-0 font-normal\"\n >\n {resolveLocalizedString(item.label, currentLanguage)}\n </button>\n </span>\n ))}\n </nav>\n </footer>\n )}\n </div>\n );\n};\n"],"names":["flattenNavigationItems","navigation","item","NotFoundView","config","useConfig","i18n","useTranslation","currentLanguage","resolveLocalizedString","value","lang","navItems","index","self","i","handleNavigate","path","shellui","jsxs","jsx"],"mappings":";;;;AAKA,MAAMA,IAAyB,CAC7BC,MAEIA,EAAW,WAAW,IAAU,CAAA,IAC7BA,EAAW,QAAQ,CAACC,MACrB,WAAWA,KAAQ,WAAWA,IACxBA,EAAyB,QAE5BA,CACR,GAGUC,IAAe,MAAM;AAChC,QAAM,EAAE,QAAAC,EAAA,IAAWC,EAAA,GACb,EAAE,MAAAC,EAAA,IAASC,EAAA,GACXC,IAAkBF,EAAK,YAAY,MAEnCG,IAAyB,CAC7BC,GACAC,MAEI,OAAOD,KAAU,WAAiBA,IAC/BA,EAAMC,CAAI,KAAKD,EAAM,MAAMA,EAAM,MAAM,OAAO,OAAOA,CAAK,EAAE,CAAC,KAAK,IAGrEE,IACJR,GAAQ,cAAcA,EAAO,WAAW,SAAS,IAC7CJ,EAAuBI,EAAO,UAAU,EACrC,OAAO,CAACF,MAAS,CAACA,EAAK,MAAM,EAC7B,OAAO,CAACA,GAAMW,GAAOC,MAASD,MAAUC,EAAK,UAAU,CAACC,MAAMA,EAAE,SAASb,EAAK,IAAI,CAAC,IACtF,CAAA,GAEAc,IAAiB,CAACC,MAAiB;AACvC,IAAAC,EAAQ,SAASD,EAAK,WAAW,GAAG,IAAIA,IAAO,IAAIA,CAAI,EAAE;AAAA,EAC3D;AAEA,SACE,gBAAAE,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qFACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,uEAAsE,UAAA,OAEtF;AAAA,MACA,gBAAAA,EAAC,KAAA,EAAE,WAAU,sCAAqC,UAAA,iBAAA,CAAc;AAAA,IAAA,GAClE;AAAA,IAECR,EAAS,SAAS,KACjB,gBAAAQ,EAAC,UAAA,EAAO,WAAU,wDAChB,UAAA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,cAAW;AAAA,QAEV,UAAAR,EAAS,IAAI,CAACV,GAAMW,MACnB,gBAAAM;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAU;AAAA,YAET,UAAA;AAAA,cAAAN,IAAQ,KACP,gBAAAO;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,eAAW;AAAA,kBACZ,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAIH,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,MAAMJ,EAAe,IAAId,EAAK,IAAI,EAAE;AAAA,kBAC7C,WAAU;AAAA,kBAET,UAAAO,EAAuBP,EAAK,OAAOM,CAAe;AAAA,gBAAA;AAAA,cAAA;AAAA,YACrD;AAAA,UAAA;AAAA,UAjBKN,EAAK;AAAA,QAAA,CAmBb;AAAA,MAAA;AAAA,IAAA,EACH,CACF;AAAA,EAAA,GAEJ;AAEJ;"}