@powerhousedao/connect 6.1.0-staging.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/{AddDriveModal-ZK9-BWMB.js → AddDriveModal-Cg2qcYp6.js} +9 -5
  2. package/dist/AddDriveModal-Cg2qcYp6.js.map +1 -0
  3. package/dist/{ClearStorageModal-BLr3sRfl.js → ClearStorageModal-D2K3LkHV.js} +5 -6
  4. package/dist/ClearStorageModal-D2K3LkHV.js.map +1 -0
  5. package/dist/{CookiesPolicyModal-DiXQV82b.js → CookiesPolicyModal-4QzcllDR.js} +4 -4
  6. package/dist/{CookiesPolicyModal-DiXQV82b.js.map → CookiesPolicyModal-4QzcllDR.js.map} +1 -1
  7. package/dist/{CreateDocumentModal-BhJh4nWt.js → CreateDocumentModal-7vgZ8nbM.js} +6 -4
  8. package/dist/{CreateDocumentModal-BhJh4nWt.js.map → CreateDocumentModal-7vgZ8nbM.js.map} +1 -1
  9. package/dist/{DebugSettingsModal-DHORxOiI.js → DebugSettingsModal-B1FRL4rp.js} +10 -10
  10. package/dist/DebugSettingsModal-B1FRL4rp.js.map +1 -0
  11. package/dist/{DeleteDriveModal-CbuIdjKY.js → DeleteDriveModal-ABue_rOY.js} +6 -4
  12. package/dist/{DeleteDriveModal-CbuIdjKY.js.map → DeleteDriveModal-ABue_rOY.js.map} +1 -1
  13. package/dist/{DeleteItemModal-9ErYlauT.js → DeleteItemModal-B6aHnYPD.js} +6 -4
  14. package/dist/{DeleteItemModal-9ErYlauT.js.map → DeleteItemModal-B6aHnYPD.js.map} +1 -1
  15. package/dist/{DownloadDocumentWithErrorsModal-KZGWQ4J7.js → DownloadDocumentWithErrorsModal-CaAPGg04.js} +13 -12
  16. package/dist/DownloadDocumentWithErrorsModal-CaAPGg04.js.map +1 -0
  17. package/dist/{DriveSettingsModal-DEk05PS7.js → DriveSettingsModal-CNtCO4-y.js} +12 -6
  18. package/dist/{DriveSettingsModal-DEk05PS7.js.map → DriveSettingsModal-CNtCO4-y.js.map} +1 -1
  19. package/dist/{InspectorModal-DrBnrYZl.js → InspectorModal-ywEL5GKA.js} +15 -14
  20. package/dist/InspectorModal-ywEL5GKA.js.map +1 -0
  21. package/dist/{SettingsModal-CwIcZXAy.js → SettingsModal-5dMD1lq9.js} +26 -27
  22. package/dist/SettingsModal-5dMD1lq9.js.map +1 -0
  23. package/dist/{build-info-Megqmixp.js → build-info-B3CWTvMu.js} +4 -4
  24. package/dist/{build-info-Megqmixp.js.map → build-info-B3CWTvMu.js.map} +1 -1
  25. package/dist/{connect.config-Cuh0hj_Q.js → connect.config-B2xP5Iez.js} +9 -3
  26. package/dist/{connect.config-Cuh0hj_Q.js.map → connect.config-B2xP5Iez.js.map} +1 -1
  27. package/dist/{i18n-4rfcgnb9.js → i18n-BuVT7wFQ.js} +4 -4
  28. package/dist/{i18n-4rfcgnb9.js.map → i18n-BuVT7wFQ.js.map} +1 -1
  29. package/dist/{load-DOIDDXvY.js → load-D-7n7rPU.js} +9 -8
  30. package/dist/{load-DOIDDXvY.js.map → load-D-7n7rPU.js.map} +1 -1
  31. package/dist/main.js +1 -1
  32. package/dist/{package-B4r0SFiy.js → package-Dk3L0oWJ.js} +17 -10
  33. package/dist/package-Dk3L0oWJ.js.map +1 -0
  34. package/dist/pglite.worker.js +7 -6
  35. package/dist/pglite.worker.js.map +1 -1
  36. package/dist/pglite.worker.legacy.js +7 -6
  37. package/dist/pglite.worker.legacy.js.map +1 -1
  38. package/dist/{reactor-CppbYt7w.js → reactor-BixVsAMj.js} +27 -18
  39. package/dist/reactor-BixVsAMj.js.map +1 -0
  40. package/dist/{registerServiceWorker-CMRF2LWE.js → registerServiceWorker-BkUnxLqB.js} +13 -11
  41. package/dist/{registerServiceWorker-CMRF2LWE.js.map → registerServiceWorker-BkUnxLqB.js.map} +1 -1
  42. package/dist/{sidebar-BLHOoVIg.js → sidebar-CO3JjI3G.js} +447 -62
  43. package/dist/sidebar-CO3JjI3G.js.map +1 -0
  44. package/dist/start-connect.js +1 -1
  45. package/dist/style.css +4888 -12764
  46. package/package.json +20 -13
  47. package/style.css +28 -0
  48. package/dist/AddDriveModal-ZK9-BWMB.js.map +0 -1
  49. package/dist/ClearStorageModal-BLr3sRfl.js.map +0 -1
  50. package/dist/DebugSettingsModal-DHORxOiI.js.map +0 -1
  51. package/dist/DownloadDocumentWithErrorsModal-KZGWQ4J7.js.map +0 -1
  52. package/dist/InspectorModal-DrBnrYZl.js.map +0 -1
  53. package/dist/SettingsModal-CwIcZXAy.js.map +0 -1
  54. package/dist/package-B4r0SFiy.js.map +0 -1
  55. package/dist/reactor-CppbYt7w.js.map +0 -1
  56. package/dist/sidebar-BLHOoVIg.js.map +0 -1
@@ -1,18 +1,19 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ebf04d37-dff0-53fa-872d-097855e3824e")}catch(e){}}();
3
- import { n as defaultPHAppConfig, r as defaultPHDocumentEditorConfig, t as connectConfig } from "./connect.config-Cuh0hj_Q.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="239c52db-b664-5e9c-ac37-c27d54ef59b8")}catch(e){}}();
3
+ import { n as defaultPHAppConfig, r as defaultPHDocumentEditorConfig, t as connectConfig } from "./connect.config-B2xP5Iez.js";
4
4
  import { n as toast, t as ToastContainer } from "./toast-DnODOv28.js";
5
- import { t as i18n } from "./i18n-4rfcgnb9.js";
5
+ import { t as i18n } from "./i18n-BuVT7wFQ.js";
6
6
  import { c as subscribeReactorPgMajor, d as createFileDataStore, f as idbError, l as IDB_STORE_NAME, m as readPgVersionFile, p as openIdb, r as getCachedReactorPgMajor, u as PRIMARY_IDB_NAMES } from "./pglite-runtime-Btp8ZXVH.js";
7
- import { t as serviceWorkerManager } from "./registerServiceWorker-CMRF2LWE.js";
8
- import { driveCollectionId, getRevisionFromDate, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useDefaultAppModule, useDocumentById, useDocumentModelModuleById, useDocumentOperations, useDrives, useEditorModuleById, useFallbackEditorModule, useNodeParentFolderById, usePHModal, usePackageDiscoveryService, useRevisionHistoryVisible, useSelectedDocument, useSelectedDocumentId, useSelectedDrive, useSelectedDriveSafe, useSelectedFolder, useSelectedTimelineItem, useSyncList, useUser, useVetraPackageManager, useVetraPackages } from "@powerhousedao/reactor-browser";
7
+ import { t as serviceWorkerManager } from "./registerServiceWorker-BkUnxLqB.js";
8
+ import { driveCollectionId, getRevisionFromDate, initTheme, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useDefaultAppModule, useDocumentById, useDocumentModelModuleById, useDocumentOperations, useDrives, useEditorModuleById, useFallbackEditorModule, useNodeParentFolderById, usePHModal, usePackageDiscoveryService, useReactorClientModule, useRevisionHistoryVisible, useSelectedDocument, useSelectedDocumentId, useSelectedDriveSafe, useSelectedFolder, useSelectedTimelineItem, useSyncList, useTheme, useUser, useVetraPackageManager, useVetraPackages } from "@powerhousedao/reactor-browser";
9
9
  import { childLogger } from "document-model";
10
10
  import React, { StrictMode, Suspense, lazy, useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
11
+ import { z } from "zod";
11
12
  import { Trans, useTranslation } from "react-i18next";
12
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
14
  import { Outlet, RouterProvider, createBrowserRouter, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from "react-router-dom";
14
15
  import { useHotkeys } from "react-hotkeys-hook";
15
- import { AnimatedLoader, ConnectSidebar, ConnectTooltipProvider, CookieBanner, DefaultEditorLoader, DropZoneWrapper, HomeScreen, HomeScreenAddDriveItem, HomeScreenItem, PackageInstallModal, RevisionHistory, SidebarAddDriveItem, SidebarItem, useEns } from "@powerhousedao/design-system/connect";
16
+ import { ConnectSidebar, ConnectTooltipProvider, CookieBanner, DefaultEditorLoader, DropZoneWrapper, HomeScreen, HomeScreenAddDriveItem, HomeScreenItem, LogoAnimation, PackageInstallModal, RevisionHistory, SidebarAddDriveItem, SidebarItem, useEns } from "@powerhousedao/design-system/connect";
16
17
  import { GenericDriveExplorer } from "@powerhousedao/powerhouse-vetra-packages/editors";
17
18
  import { Icon, Modal, PowerhouseButton } from "@powerhousedao/design-system";
18
19
  import { ErrorBoundary } from "react-error-boundary";
@@ -54,10 +55,250 @@ function subscribe$1(fn) {
54
55
  const useAcceptedCookies = () => {
55
56
  return [useSyncExternalStore(subscribe$1, getCookies, getCookies), setCookies];
56
57
  };
58
+ //#endregion
59
+ //#region src/services/openpanel/buffer.ts
60
+ const buffer = [];
61
+ let errorHandler;
62
+ function defaultOnError(err) {
63
+ console.warn("[useOpenPanel] track failed:", err);
64
+ }
65
+ /**
66
+ * Forward a single event to the active client, swallowing any throw.
67
+ *
68
+ * The outer try/catch handles synchronous throws from `client.track`; the
69
+ * inner `.catch()` handles rejected promises. Both are needed because
70
+ * `Promise.resolve(x).catch()` cannot catch a throw from evaluating `x`.
71
+ */
72
+ function forward(client, name, props) {
73
+ try {
74
+ Promise.resolve(client.track(name, props)).catch((err) => (errorHandler ?? defaultOnError)(err));
75
+ } catch (err) {
76
+ (errorHandler ?? defaultOnError)(err);
77
+ }
78
+ }
79
+ /**
80
+ * Drain the pre-init buffer in FIFO order through `client.track`, then forward
81
+ * subsequent events directly. Called once from `getOpenPanelClient()`.
82
+ */
83
+ function drainOpenPanelBuffer(client, onError) {
84
+ errorHandler = onError;
85
+ const pending = buffer.splice(0, buffer.length);
86
+ for (const [name, props] of pending) forward(client, name, props);
87
+ }
88
+ /**
89
+ * Clear the buffer and reset the active client. Buffered pre-consent events
90
+ * are discarded so they are not replayed if the user later re-accepts.
91
+ */
92
+ function clearOpenPanelBuffer() {
93
+ buffer.length = 0;
94
+ errorHandler = void 0;
95
+ }
96
+ //#endregion
97
+ //#region src/services/openpanel/client.ts
98
+ let client;
99
+ /**
100
+ * Returns the cached `OpenPanel` singleton, building it on first call.
101
+ *
102
+ * When `config.clientId` is empty it returns `undefined` without importing
103
+ * `@openpanel/web`, so the bundler can tree-shake the SDK out of production.
104
+ */
105
+ async function getOpenPanelClient(config) {
106
+ if (!config.clientId) return;
107
+ if (client) return client;
108
+ const { OpenPanel: OpenPanelClass } = await import("@openpanel/web");
109
+ client = new OpenPanelClass({
110
+ clientId: config.clientId,
111
+ ...config.apiUrl ? { apiUrl: config.apiUrl } : {}
112
+ });
113
+ drainOpenPanelBuffer(client);
114
+ return client;
115
+ }
116
+ /**
117
+ * Clears the cached singleton and the pre-init buffer. Call on consent
118
+ * revocation or during tests; buffered events are discarded, not replayed.
119
+ */
120
+ function resetOpenPanelClient() {
121
+ client = void 0;
122
+ clearOpenPanelBuffer();
123
+ }
124
+ //#endregion
125
+ //#region src/services/openpanel/events.json
126
+ var events_default = [
127
+ {
128
+ "documentType": "powerhouse/document-drive",
129
+ "actionTypes": [
130
+ "ADD_FOLDER",
131
+ "DELETE_NODE",
132
+ "ADD_FILE",
133
+ "UPDATE_FILE",
134
+ "COPY_NODE",
135
+ "MOVE_NODE",
136
+ "SET_DRIVE_NAME",
137
+ "SET_DRIVE_ICON"
138
+ ]
139
+ },
140
+ {
141
+ "documentType": "powerhouse/document-model",
142
+ "actionTypes": [
143
+ "SET_MODEL_NAME",
144
+ "SET_MODEL_ID",
145
+ "ADD_MODULE",
146
+ "DELETE_MODULE",
147
+ "ADD_OPERATION",
148
+ "DELETE_OPERATION"
149
+ ]
150
+ },
151
+ {
152
+ "documentType": "powerhouse/reactor-drive",
153
+ "actionTypes": [
154
+ "ADD_FOLDER",
155
+ "REMOVE_FOLDER",
156
+ "UPDATE_FOLDER"
157
+ ]
158
+ }
159
+ ];
160
+ //#endregion
161
+ //#region src/services/openpanel/events.ts
162
+ const EventMappingSchema = z.object({
163
+ documentType: z.string().min(1),
164
+ actionTypes: z.array(z.string().min(1)).min(1),
165
+ alias: z.string().optional()
166
+ }).strict();
167
+ const EventMappingsSchema = z.array(EventMappingSchema).readonly();
168
+ /**
169
+ * Parses and validates the event mapping table, returning the validated array
170
+ * and an O(1) lookup map. Accepts a `raw` override for tests. Throws on zod
171
+ * failures and on duplicate `(documentType, actionType)` pairs.
172
+ */
173
+ function loadEvents(raw = events_default) {
174
+ const result = EventMappingsSchema.safeParse(raw);
175
+ if (!result.success) throw new Error(`Invalid OpenPanel events.json: ${result.error.message}`);
176
+ const mappings = result.data;
177
+ const lookupMap = /* @__PURE__ */ new Map();
178
+ for (const mapping of mappings) {
179
+ let inner = lookupMap.get(mapping.documentType);
180
+ if (!inner) {
181
+ inner = /* @__PURE__ */ new Map();
182
+ lookupMap.set(mapping.documentType, inner);
183
+ }
184
+ for (const actionType of mapping.actionTypes) {
185
+ if (inner.has(actionType)) throw new Error(`Duplicate OpenPanel event mapping for ${mapping.documentType}/${actionType}`);
186
+ inner.set(actionType, mapping);
187
+ }
188
+ }
189
+ return {
190
+ mappings,
191
+ lookupMap
192
+ };
193
+ }
194
+ const { mappings: defaultMappings, lookupMap: defaultLookupMap } = loadEvents();
195
+ /** Validated mapping array from the bundled events.json. */
196
+ const eventMappings = defaultMappings;
197
+ /** O(1) lookup map: documentType → actionType → mapping. */
198
+ const eventLookupMap = defaultLookupMap;
199
+ /**
200
+ * Normalizes a document type into a safe event-name segment: lowercased, `/`
201
+ * replaced with `.`, and any character outside `[a-z0-9._-]` stripped.
202
+ * e.g. `powerhouse/document-drive` → `powerhouse.document-drive`.
203
+ */
204
+ function normalize(documentType) {
205
+ return documentType.toLowerCase().replace(/\//g, ".").replace(/[^a-z0-9._-]/g, "");
206
+ }
207
+ /**
208
+ * Derives the OpenPanel event name: `mapping.alias` when present, otherwise
209
+ * `${normalize(documentType)}.${actionType.toLowerCase()}`.
210
+ */
211
+ function deriveEventName(mapping, op) {
212
+ if (mapping.alias) return mapping.alias;
213
+ return `${normalize(op.context.documentType)}.${op.operation.action.type.toLowerCase()}`;
214
+ }
215
+ /** Builds the default properties attached to every OpenPanel event. */
216
+ function buildDefaultProperties(op) {
217
+ return {
218
+ documentType: op.context.documentType,
219
+ actionType: op.operation.action.type,
220
+ documentId: op.context.documentId,
221
+ scope: op.context.scope,
222
+ branch: op.context.branch,
223
+ app: "connect"
224
+ };
225
+ }
226
+ //#endregion
227
+ //#region src/services/openpanel/processor.ts
228
+ /**
229
+ * Read-only reactor `IProcessor` that translates matching document operations
230
+ * into OpenPanel analytics events. Operations whose `(documentType, actionType)`
231
+ * pair is absent from the lookup map are skipped; per-operation errors are
232
+ * routed to `onError` and never thrown back to the manager.
233
+ */
234
+ var OpenPanelProcessor = class {
235
+ constructor(client, lookupMap, onError = (err) => console.warn("[OpenPanelProcessor] Error tracking event:", err)) {
236
+ this.client = client;
237
+ this.lookupMap = lookupMap;
238
+ this.onError = onError;
239
+ }
240
+ async onOperations(operations) {
241
+ for (const op of operations) {
242
+ const inner = this.lookupMap.get(op.context.documentType);
243
+ if (!inner) continue;
244
+ const mapping = inner.get(op.operation.action.type);
245
+ if (!mapping) continue;
246
+ const name = deriveEventName(mapping, op);
247
+ const payload = buildDefaultProperties(op);
248
+ try {
249
+ await this.client.track(name, payload);
250
+ } catch (err) {
251
+ this.onError(err, op);
252
+ }
253
+ }
254
+ }
255
+ onDisconnect() {
256
+ this.client.flush?.();
257
+ return Promise.resolve();
258
+ }
259
+ };
260
+ //#endregion
261
+ //#region src/services/openpanel/factory.ts
262
+ /**
263
+ * Returns a `ProcessorFactory` that, for each drive, creates a single
264
+ * `OpenPanelProcessor` record whose `filter.documentType` is the union of all
265
+ * document types present in the event mapping table.
266
+ */
267
+ function createOpenPanelProcessorFactory(config) {
268
+ return function openPanelProcessorFactory(_driveHeader) {
269
+ const documentType = Array.from(config.events.lookupMap.keys());
270
+ return [{
271
+ processor: new OpenPanelProcessor(config.client, config.events.lookupMap, config.onError),
272
+ filter: { documentType },
273
+ startFrom: config.startFrom ?? "current"
274
+ }];
275
+ };
276
+ }
277
+ //#endregion
278
+ //#region src/hooks/useIsEmbedded.ts
279
+ /**
280
+ * Detects whether Connect is being rendered inside another app (e.g. inside
281
+ * an iframe in the vetra-cli drive editor). When `?embed=1` is present in the
282
+ * URL, chrome that doesn't make sense in the embedded context — the cookie
283
+ * banner, the outer sidebar — is suppressed.
284
+ */
285
+ function getIsEmbedded() {
286
+ if (typeof window === "undefined") return false;
287
+ try {
288
+ const value = new URLSearchParams(window.location.search).get("embed");
289
+ return value !== null && value !== "0" && value !== "false";
290
+ } catch {
291
+ return false;
292
+ }
293
+ }
294
+ function useIsEmbedded() {
295
+ return getIsEmbedded();
296
+ }
57
297
  const COOKIE_BANNER_KEY_STORAGE = `${connectConfig.routerBasename}:display-cookie-banner`;
58
298
  const listeners$2 = /* @__PURE__ */ new Set();
59
299
  let bannerShown = getInitial();
60
300
  function getInitial() {
301
+ if (getIsEmbedded()) return false;
61
302
  try {
62
303
  return localStorage.getItem(COOKIE_BANNER_KEY_STORAGE) !== "false";
63
304
  } catch (error) {
@@ -208,6 +449,144 @@ const Analytics = () => {
208
449
  return null;
209
450
  };
210
451
  //#endregion
452
+ //#region src/components/openpanel-traits.ts
453
+ /**
454
+ * Builds the OpenPanel identity traits from a renown User.
455
+ *
456
+ * Rules:
457
+ * - `credential` (contains a JWT) is **never** forwarded.
458
+ * - `did` / `profileId` is sent as the top-level `profileId` key in the
459
+ * `client.identify()` call — it is **not** duplicated inside traits.
460
+ * - Optional fields (`ens`, `profile`) are only included when their value is
461
+ * non-nullish (guards against `null` from `RenownProfile` fields as well
462
+ * as plain `undefined`).
463
+ *
464
+ * Mirror the Sentry pattern in `store/user.ts`: destructure off `credential`
465
+ * first, then assemble the trait payload from the remainder.
466
+ */
467
+ function buildTraits(user) {
468
+ const { credential: _credential, ...rest } = user;
469
+ const traits = {
470
+ address: rest.address,
471
+ networkId: rest.networkId,
472
+ chainId: rest.chainId
473
+ };
474
+ if (rest.ens?.name != null) traits.ensName = rest.ens.name;
475
+ if (rest.ens?.avatarUrl != null) traits.ensAvatar = rest.ens.avatarUrl;
476
+ if (rest.profile?.username != null) traits.username = rest.profile.username;
477
+ if (rest.profile?.userImage != null) traits.userImage = rest.profile.userImage;
478
+ if (rest.profile?.documentId != null) traits.profileDocumentId = rest.profile.documentId;
479
+ if (rest.profile?.createdAt != null) traits.profileCreatedAt = rest.profile.createdAt;
480
+ return traits;
481
+ }
482
+ //#endregion
483
+ //#region src/components/openpanel.tsx
484
+ /**
485
+ * `OpenPanel` is a `null`-rendering component that manages the full lifecycle
486
+ * of the OpenPanel analytics subsystem.
487
+ *
488
+ * Gates:
489
+ * - `useAcceptedCookies().analytics === true` — the existing analytics cookie.
490
+ * - `connectConfig.openPanel.clientId` non-empty — no client ID → no-op.
491
+ *
492
+ * Behaviour when both gates pass:
493
+ * 1. Lazy-imports `@openpanel/web` and builds the singleton via
494
+ * `getOpenPanelClient(connectConfig.openPanel)`.
495
+ * 2. Exposes the client on `window.openPanel` for the card-6 `useOpenPanel()`
496
+ * hook to consume.
497
+ * 3. If `connectConfig.openPanel.trackOperations`, registers the processor
498
+ * factory against `processorManager` so document operations are forwarded.
499
+ * 4. Calls `client.identify()` when the renown user transitions from
500
+ * `undefined` → defined (login).
501
+ * 5. Calls `client.clear()` when the user transitions from defined →
502
+ * `undefined` (logout).
503
+ *
504
+ * Teardown (unmount **or** consent revocation):
505
+ * - `unregisterFactory("openpanel")` to remove the processor.
506
+ * - `resetOpenPanelClient()` to clear the singleton.
507
+ * - `window.openPanel` is cleared.
508
+ *
509
+ * Mirrors the Sentry pattern in `store/user.ts` for login/logout detection.
510
+ * Analytics failures are caught and forwarded to `console.warn` — they must
511
+ * never throw into the application.
512
+ *
513
+ * Mounted next to `<Analytics />` in `app.tsx`.
514
+ */
515
+ function OpenPanel() {
516
+ const [{ analytics }] = useAcceptedCookies();
517
+ const user = useUser();
518
+ const reactorClientModule = useReactorClientModule();
519
+ const [client, setClient] = useState();
520
+ /**
521
+ * Tracks the previous `user` value so we can detect the two transitions:
522
+ * undefined → defined (login)
523
+ * defined → undefined (logout)
524
+ */
525
+ const prevUserRef = useRef(void 0);
526
+ const enabled = analytics && !!connectConfig.openPanel.clientId;
527
+ const processorManager = reactorClientModule?.reactorModule?.processorManager;
528
+ useEffect(() => {
529
+ if (!enabled) return;
530
+ let cancelled = false;
531
+ (async () => {
532
+ let builtClient;
533
+ try {
534
+ builtClient = await getOpenPanelClient(connectConfig.openPanel);
535
+ } catch (err) {
536
+ console.warn("[OpenPanel] Failed to build client:", err);
537
+ return;
538
+ }
539
+ if (cancelled || !builtClient) return;
540
+ setClient(builtClient);
541
+ window.openPanel = builtClient;
542
+ if (connectConfig.openPanel.trackOperations && processorManager) try {
543
+ await processorManager.registerFactory("openpanel", createOpenPanelProcessorFactory({
544
+ client: builtClient,
545
+ events: {
546
+ mappings: eventMappings,
547
+ lookupMap: eventLookupMap
548
+ },
549
+ startFrom: "current"
550
+ }));
551
+ if (cancelled) await processorManager.unregisterFactory("openpanel").catch((err) => console.warn("[OpenPanel] Failed to unregister factory after cancellation:", err));
552
+ } catch (err) {
553
+ console.warn("[OpenPanel] Failed to register processor factory:", err);
554
+ }
555
+ })();
556
+ return () => {
557
+ cancelled = true;
558
+ prevUserRef.current = void 0;
559
+ if (connectConfig.openPanel.trackOperations && processorManager) processorManager.unregisterFactory("openpanel").catch((err) => console.warn("[OpenPanel] Failed to unregister processor factory:", err));
560
+ resetOpenPanelClient();
561
+ window.openPanel = void 0;
562
+ setClient(void 0);
563
+ };
564
+ }, [enabled, processorManager]);
565
+ useEffect(() => {
566
+ if (!enabled || !client) return;
567
+ const prev = prevUserRef.current;
568
+ prevUserRef.current = user;
569
+ if (!prev && user) try {
570
+ client.identify({
571
+ profileId: user.did,
572
+ properties: buildTraits(user)
573
+ });
574
+ } catch (err) {
575
+ console.warn("[OpenPanel] Failed to identify user:", err);
576
+ }
577
+ else if (prev && !user) try {
578
+ client.clear();
579
+ } catch (err) {
580
+ console.warn("[OpenPanel] Failed to clear user:", err);
581
+ }
582
+ }, [
583
+ client,
584
+ user,
585
+ enabled
586
+ ]);
587
+ return null;
588
+ }
589
+ //#endregion
211
590
  //#region src/components/document-editor-container.tsx
212
591
  function DocumentEditorContainer() {
213
592
  const [selectedDocument] = useSelectedDocument();
@@ -217,7 +596,7 @@ function DocumentEditorContainer() {
217
596
  }, []);
218
597
  useCallback(() => {
219
598
  setSelectedNode(parentFolder);
220
- }, [parentFolder, setSelectedNode]);
599
+ }, [parentFolder]);
221
600
  return /* @__PURE__ */ jsx("div", {
222
601
  id: "document-editor-container",
223
602
  className: "flex-1",
@@ -269,7 +648,7 @@ function DetailedFallback({ error, resetErrorBoundary }) {
269
648
  return /* @__PURE__ */ jsx("div", {
270
649
  className: "z-10 mx-auto flex max-w-[80%] flex-1 items-center justify-center p-6",
271
650
  children: /* @__PURE__ */ jsxs("div", {
272
- className: "w-full max-w-lg rounded-lg border border-gray-500 bg-white p-6 shadow-sm",
651
+ className: "w-full max-w-lg rounded-lg border border-gray-500 bg-gray-50 p-6 shadow-sm dark:border-slate-400 dark:bg-slate-800",
273
652
  children: [
274
653
  /* @__PURE__ */ jsxs("div", {
275
654
  className: "mb-3 flex items-center gap-2",
@@ -282,16 +661,16 @@ function DetailedFallback({ error, resetErrorBoundary }) {
282
661
  })]
283
662
  }),
284
663
  /* @__PURE__ */ jsx("p", {
285
- className: "mb-4 text-sm text-gray-700",
664
+ className: "mb-4 text-sm text-gray-700 dark:text-slate-200",
286
665
  children: errorMessage
287
666
  }),
288
667
  errorDetails !== "{}" && /* @__PURE__ */ jsxs("details", {
289
668
  className: "group",
290
669
  children: [/* @__PURE__ */ jsx("summary", {
291
- className: "cursor-pointer text-sm font-medium text-gray-700 underline select-none hover:text-gray-700",
670
+ className: "cursor-pointer text-sm font-medium text-gray-700 underline select-none hover:text-gray-700 dark:text-slate-200 dark:hover:text-slate-200",
292
671
  children: "Show details"
293
672
  }), /* @__PURE__ */ jsx("pre", {
294
- className: "mt-2 max-h-48 overflow-auto rounded-sm bg-gray-100 p-3 text-xs",
673
+ className: "mt-2 max-h-48 overflow-auto rounded-sm bg-gray-100 p-3 text-xs dark:bg-slate-700",
295
674
  children: errorDetails
296
675
  })]
297
676
  }),
@@ -385,10 +764,11 @@ function ErrorBoundary$1(props) {
385
764
  //#endregion
386
765
  //#region src/components/app-container.tsx
387
766
  function AppContainer() {
388
- const [selectedDrive] = useSelectedDrive();
767
+ const [selectedDrive] = useSelectedDriveSafe();
389
768
  const selectedDocumentId = useSelectedDocumentId();
390
- const app = useAppModuleById(selectedDrive.header.meta?.preferredEditor);
769
+ const app = useAppModuleById(selectedDrive?.header.meta?.preferredEditor);
391
770
  const defaultApp = useDefaultAppModule();
771
+ if (!selectedDrive) return /* @__PURE__ */ jsx(EditorLoader, {});
392
772
  const AppComponent = app?.Component ?? defaultApp?.Component ?? GenericDriveExplorer.Component;
393
773
  if (!AppComponent) throw new Error("No app component found");
394
774
  return /* @__PURE__ */ jsx(ErrorBoundary$1, {
@@ -719,12 +1099,12 @@ const MigrationOverlay = () => {
719
1099
  return /* @__PURE__ */ jsx("div", {
720
1100
  className: "absolute inset-0 z-20 flex items-center justify-center",
721
1101
  children: /* @__PURE__ */ jsxs("div", {
722
- className: "rounded-lg bg-white/90 px-6 py-4 text-sm text-gray-900 shadow-lg",
1102
+ className: "rounded-lg bg-white/90 px-6 py-4 text-sm text-gray-900 shadow-lg dark:bg-slate-900/90 dark:text-slate-50",
723
1103
  children: [/* @__PURE__ */ jsx("div", {
724
1104
  className: "font-medium",
725
1105
  children: "Upgrading local database…"
726
1106
  }), /* @__PURE__ */ jsx("div", {
727
- className: "text-gray-600",
1107
+ className: "text-gray-700 dark:text-slate-200",
728
1108
  children: PHASE_LABEL[status.phase]
729
1109
  })]
730
1110
  })
@@ -733,6 +1113,7 @@ const MigrationOverlay = () => {
733
1113
  const Loader = ({ delay = LOADER_DELAY }) => {
734
1114
  const isSSR = typeof window === "undefined";
735
1115
  const showInitialLoader = typeof document !== "undefined" && document.body.getAttribute("data-show-loader") === "true";
1116
+ if (!isSSR) initTheme();
736
1117
  const [showLoading, setShowLoading] = useState(!delay || showInitialLoader);
737
1118
  useEffect(() => {
738
1119
  const id = setTimeout(() => {
@@ -744,7 +1125,7 @@ const Loader = ({ delay = LOADER_DELAY }) => {
744
1125
  className: `skeleton-loader absolute inset-0 z-10 flex items-center justify-center ${showLoading ? "" : "hidden"}`,
745
1126
  children: [/* @__PURE__ */ jsx("div", {
746
1127
  className: "animate-pulse overflow-hidden rounded-full shadow-lg",
747
- children: /* @__PURE__ */ jsx(AnimatedLoader, {})
1128
+ children: /* @__PURE__ */ jsx(LogoAnimation, {})
748
1129
  }), isSSR ? /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: `setTimeout(() => {
749
1130
  document.querySelector('.skeleton-loader')?.classList.remove('hidden');
750
1131
  document.body.setAttribute('data-show-loader', 'true');
@@ -755,9 +1136,9 @@ const AppSkeleton = (props) => {
755
1136
  const isSSR = typeof window === "undefined";
756
1137
  const isHomeScreen = !isSSR && window.location.pathname === getBasePath();
757
1138
  return /* @__PURE__ */ jsxs("div", {
758
- className: "flex h-screen overflow-hidden",
1139
+ className: "flex h-screen overflow-hidden bg-gray-50 dark:bg-slate-700",
759
1140
  children: [
760
- /* @__PURE__ */ jsx(ConnectSidebar, {
1141
+ !(!isSSR && getIsEmbedded()) && /* @__PURE__ */ jsx(ConnectSidebar, {
761
1142
  className: "animate-pulse",
762
1143
  onLogin: void 0,
763
1144
  onDisconnect: void 0,
@@ -820,7 +1201,7 @@ const MigrationBanner = () => {
820
1201
  return /* @__PURE__ */ jsx("div", {
821
1202
  className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
822
1203
  children: /* @__PURE__ */ jsxs("div", {
823
- className: "flex max-w-3xl items-center gap-3 rounded-lg border border-yellow-500 bg-yellow-400 px-4 py-3 text-sm text-gray-900 shadow-lg",
1204
+ className: "flex max-w-3xl items-center gap-3 rounded-lg border border-yellow-500 bg-yellow-400 px-4 py-3 text-sm text-gray-900 shadow-lg dark:border-yellow-400 dark:bg-yellow-500 dark:text-slate-50",
824
1205
  children: [
825
1206
  /* @__PURE__ */ jsxs("div", {
826
1207
  className: "flex-1",
@@ -834,7 +1215,7 @@ const MigrationBanner = () => {
834
1215
  ]
835
1216
  }),
836
1217
  /* @__PURE__ */ jsxs("div", {
837
- className: "text-gray-800",
1218
+ className: "text-gray-900 dark:text-slate-100",
838
1219
  children: [
839
1220
  "Migrate to Postgres ",
840
1221
  17,
@@ -842,7 +1223,7 @@ const MigrationBanner = () => {
842
1223
  ]
843
1224
  }),
844
1225
  error && /* @__PURE__ */ jsxs("div", {
845
- className: "mt-2 font-medium text-red-900",
1226
+ className: "mt-2 font-medium text-red-900 dark:text-red-400",
846
1227
  children: ["Migration failed: ", error]
847
1228
  })
848
1229
  ]
@@ -851,14 +1232,14 @@ const MigrationBanner = () => {
851
1232
  type: "button",
852
1233
  disabled: migrating,
853
1234
  onClick: handleMigrate,
854
- className: "rounded-sm bg-gray-900 px-3 py-1 text-sm font-medium text-white hover:bg-gray-800 disabled:opacity-50",
1235
+ className: "rounded-sm bg-gray-900 px-3 py-1 text-sm font-medium text-white hover:bg-gray-800 disabled:opacity-50 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-100",
855
1236
  children: migrating ? "Migrating…" : "Migrate now"
856
1237
  }),
857
1238
  /* @__PURE__ */ jsx("button", {
858
1239
  type: "button",
859
1240
  disabled: migrating,
860
1241
  onClick: dismiss,
861
- className: "rounded-sm border border-gray-900 bg-transparent px-3 py-1 text-sm font-medium text-gray-900 hover:bg-gray-900/10 disabled:opacity-50",
1242
+ className: "rounded-sm border border-gray-900 bg-transparent px-3 py-1 text-sm font-medium text-gray-900 hover:bg-gray-900/10 disabled:opacity-50 dark:border-slate-50 dark:text-slate-50",
862
1243
  children: "Dismiss"
863
1244
  })
864
1245
  ]
@@ -867,17 +1248,17 @@ const MigrationBanner = () => {
867
1248
  };
868
1249
  //#endregion
869
1250
  //#region src/components/modal/modals-container.tsx
870
- const AddDriveModal$1 = lazy(() => import("./AddDriveModal-ZK9-BWMB.js").then((m) => ({ default: m.AddDriveModal })));
871
- const ClearStorageModal = lazy(() => import("./ClearStorageModal-BLr3sRfl.js").then((m) => ({ default: m.ClearStorageModal })));
872
- const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-DiXQV82b.js").then((m) => ({ default: m.CookiesPolicyModal })));
873
- const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-BhJh4nWt.js").then((m) => ({ default: m.CreateDocumentModal })));
874
- const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-DHORxOiI.js").then((m) => ({ default: m.DebugSettingsModal })));
875
- const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-CbuIdjKY.js").then((m) => ({ default: m.DeleteDriveModal })));
876
- const DeleteItemModal = lazy(() => import("./DeleteItemModal-9ErYlauT.js").then((m) => ({ default: m.DeleteItemModal })));
1251
+ const AddDriveModal$1 = lazy(() => import("./AddDriveModal-Cg2qcYp6.js").then((m) => ({ default: m.AddDriveModal })));
1252
+ const ClearStorageModal = lazy(() => import("./ClearStorageModal-D2K3LkHV.js").then((m) => ({ default: m.ClearStorageModal })));
1253
+ const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-4QzcllDR.js").then((m) => ({ default: m.CookiesPolicyModal })));
1254
+ const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-7vgZ8nbM.js").then((m) => ({ default: m.CreateDocumentModal })));
1255
+ const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-B1FRL4rp.js").then((m) => ({ default: m.DebugSettingsModal })));
1256
+ const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-ABue_rOY.js").then((m) => ({ default: m.DeleteDriveModal })));
1257
+ const DeleteItemModal = lazy(() => import("./DeleteItemModal-B6aHnYPD.js").then((m) => ({ default: m.DeleteItemModal })));
877
1258
  const DisclaimerModal = lazy(() => import("./DisclaimerModal-CfDeiBz8.js").then((m) => ({ default: m.DisclaimerModal })));
878
- const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-DEk05PS7.js").then((m) => ({ default: m.DriveSettingsModal })));
879
- const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-KZGWQ4J7.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
880
- const SettingsModal$1 = lazy(() => import("./SettingsModal-CwIcZXAy.js").then((m) => ({ default: m.SettingsModal })));
1259
+ const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-CNtCO4-y.js").then((m) => ({ default: m.DriveSettingsModal })));
1260
+ const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-CaAPGg04.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
1261
+ const SettingsModal$1 = lazy(() => import("./SettingsModal-5dMD1lq9.js").then((m) => ({ default: m.SettingsModal })));
881
1262
  const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-BwI5E5k3.js").then((m) => ({ default: m.UpgradeDriveModal })));
882
1263
  const modalComponents = {
883
1264
  addDrive: AddDriveModal$1,
@@ -890,13 +1271,13 @@ const modalComponents = {
890
1271
  disclaimer: DisclaimerModal,
891
1272
  driveSettings: DriveSettingsModal$1,
892
1273
  downloadDocumentWithErrors: DownloadDocumentWithErrorsModal,
893
- inspector: lazy(() => import("./InspectorModal-DrBnrYZl.js").then((m) => ({ default: m.InspectorModal }))),
1274
+ inspector: lazy(() => import("./InspectorModal-ywEL5GKA.js").then((m) => ({ default: m.InspectorModal }))),
894
1275
  settings: SettingsModal$1,
895
1276
  upgradeDrive: UpgradeDriveModal,
896
1277
  missingPackage: lazy(() => import("./MissingPackageModal-CUdcDjSO.js").then((m) => ({ default: m.ConnectMissingPackageModal })))
897
1278
  };
898
- const ModalsContainer = lazy(async () => {
899
- return { default: () => {
1279
+ const ModalsContainer = lazy(() => {
1280
+ return Promise.resolve({ default: () => {
900
1281
  const phModal = usePHModal();
901
1282
  if (!phModal?.type) return null;
902
1283
  const ModalComponent = modalComponents[phModal.type];
@@ -908,12 +1289,12 @@ const ModalsContainer = lazy(async () => {
908
1289
  children: /* @__PURE__ */ jsx(ModalComponent, {})
909
1290
  })
910
1291
  }) : null;
911
- } };
1292
+ } });
912
1293
  });
913
1294
  //#endregion
914
1295
  //#region src/components/app-loader.tsx
915
1296
  const AppLoader = (props) => {
916
- const Load = lazy(() => import("./load-DOIDDXvY.js").then((m) => m.loadComponent(props.localPackage)));
1297
+ const Load = lazy(() => import("./load-D-7n7rPU.js").then((m) => m.loadComponent(props.localPackage)));
917
1298
  return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsxs(ErrorBoundary$1, {
918
1299
  fallbackRender: (props) => /* @__PURE__ */ jsx(AppSkeleton, { children: /* @__PURE__ */ jsx(DetailedFallback, { ...props }) }),
919
1300
  resetKeys: [props.localPackage],
@@ -962,11 +1343,11 @@ function MissingModelBanner() {
962
1343
  const [open, setOpen] = useState(false);
963
1344
  if (failed.length === 0) return null;
964
1345
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
965
- className: "flex items-center justify-between gap-3 bg-amber-100 px-4 py-2 text-sm text-amber-900",
1346
+ className: "flex items-center justify-between gap-3 bg-amber-100 px-4 py-2 text-sm text-amber-900 dark:bg-amber-800 dark:text-amber-100",
966
1347
  children: [/* @__PURE__ */ jsx("span", { children: failed.length === 1 ? "1 document type couldn't load (missing model)." : `${failed.length} document types couldn't load (missing models).` }), /* @__PURE__ */ jsx("button", {
967
1348
  type: "button",
968
1349
  onClick: () => setOpen(true),
969
- className: "rounded-md border border-amber-300 bg-white px-3 py-1 text-amber-900 hover:bg-amber-50",
1350
+ className: "rounded-md border border-amber-300 bg-gray-50 px-3 py-1 text-amber-900 hover:bg-amber-50 dark:border-amber-600 dark:bg-slate-800 dark:text-amber-100 dark:hover:bg-amber-900",
970
1351
  children: "View"
971
1352
  })]
972
1353
  }), /* @__PURE__ */ jsx(MissingModelDetailsModal, {
@@ -999,18 +1380,18 @@ function MissingModelDetailsModal(props) {
999
1380
  },
1000
1381
  contentProps: { className: "rounded-3xl" },
1001
1382
  children: /* @__PURE__ */ jsxs("div", {
1002
- className: "w-[520px] max-w-[90vw] bg-white p-6",
1383
+ className: "w-[520px] max-w-[90vw] bg-gray-50 p-6 dark:bg-slate-800",
1003
1384
  children: [
1004
1385
  /* @__PURE__ */ jsx("div", {
1005
- className: "border-b border-slate-100 pb-2 text-2xl font-bold text-gray-800",
1386
+ className: "border-b border-gray-100 pb-2 text-2xl font-bold text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100",
1006
1387
  children: "Missing document models"
1007
1388
  }),
1008
1389
  /* @__PURE__ */ jsx("div", {
1009
- className: "my-4 text-sm text-gray-600",
1390
+ className: "my-4 text-sm text-gray-700 dark:text-slate-200",
1010
1391
  children: "The following document types couldn't be loaded. Documents using them won't display until the underlying package is installed."
1011
1392
  }),
1012
1393
  failed.length === 0 ? /* @__PURE__ */ jsx("div", {
1013
- className: "rounded-xl bg-slate-50 p-4 text-sm text-gray-600",
1394
+ className: "rounded-xl bg-gray-50 p-4 text-sm text-gray-700 dark:bg-slate-800 dark:text-slate-200",
1014
1395
  children: "No outstanding failures."
1015
1396
  }) : /* @__PURE__ */ jsx("div", {
1016
1397
  className: "flex max-h-[60vh] flex-col gap-3 overflow-y-auto",
@@ -1018,18 +1399,18 @@ function MissingModelDetailsModal(props) {
1018
1399
  const isRetrying = retrying.has(entry.documentType);
1019
1400
  const retryDisabled = !canRetry(entry.reason) || isRetrying;
1020
1401
  return /* @__PURE__ */ jsxs("div", {
1021
- className: "rounded-xl bg-slate-50 p-4",
1402
+ className: "rounded-xl bg-gray-50 p-4 dark:bg-slate-800",
1022
1403
  children: [
1023
1404
  /* @__PURE__ */ jsx("div", {
1024
- className: "mb-1 font-mono text-sm font-semibold text-gray-800",
1405
+ className: "mb-1 font-mono text-sm font-semibold text-gray-900 dark:text-slate-100",
1025
1406
  children: entry.documentType
1026
1407
  }),
1027
1408
  /* @__PURE__ */ jsx("div", {
1028
- className: "mb-2 text-xs text-gray-600",
1409
+ className: "mb-2 text-xs text-gray-700 dark:text-slate-200",
1029
1410
  children: reasonLabels[entry.reason]
1030
1411
  }),
1031
1412
  entry.packageNames.length > 0 ? /* @__PURE__ */ jsxs("div", {
1032
- className: "mb-2 text-xs text-gray-500",
1413
+ className: "mb-2 text-xs text-gray-500 dark:text-slate-400",
1033
1414
  children: [
1034
1415
  "Package",
1035
1416
  entry.packageNames.length > 1 ? "s" : "",
@@ -1039,7 +1420,7 @@ function MissingModelDetailsModal(props) {
1039
1420
  ]
1040
1421
  }) : null,
1041
1422
  entry.error ? /* @__PURE__ */ jsx("div", {
1042
- className: "mb-2 font-mono text-xs wrap-break-word text-red-700",
1423
+ className: "mb-2 font-mono text-xs wrap-break-word text-red-700 dark:text-red-100",
1043
1424
  children: entry.error.message
1044
1425
  }) : null,
1045
1426
  /* @__PURE__ */ jsx("div", {
@@ -1049,7 +1430,7 @@ function MissingModelDetailsModal(props) {
1049
1430
  onClick: () => void handleRetry(entry.documentType),
1050
1431
  disabled: retryDisabled,
1051
1432
  title: canRetry(entry.reason) ? void 0 : "No registry is configured; nothing to retry against.",
1052
- className: twMerge("min-h-[32px] rounded-xl px-3 py-1 text-sm font-semibold text-white transition-all hover:scale-105", retryDisabled ? "cursor-not-allowed bg-gray-300 hover:scale-100" : "bg-gray-800 active:opacity-75"),
1433
+ className: twMerge("min-h-[32px] rounded-xl px-3 py-1 text-sm font-semibold text-white transition-all hover:scale-105 dark:text-slate-900", retryDisabled ? "cursor-not-allowed bg-gray-300 hover:scale-100 dark:bg-slate-600 dark:text-slate-100" : "bg-gray-800 active:opacity-75 dark:bg-slate-100"),
1053
1434
  children: isRetrying ? "Retrying..." : "Try install again"
1054
1435
  })
1055
1436
  })
@@ -1062,7 +1443,7 @@ function MissingModelDetailsModal(props) {
1062
1443
  children: /* @__PURE__ */ jsx("button", {
1063
1444
  type: "button",
1064
1445
  onClick: onClose,
1065
- className: "min-h-[36px] rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm font-semibold text-slate-800 hover:bg-slate-50",
1446
+ className: "min-h-[36px] rounded-xl border border-gray-200 bg-gray-50 px-4 py-2 text-sm font-semibold text-gray-800 hover:bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-800",
1066
1447
  children: "Close"
1067
1448
  })
1068
1449
  })
@@ -1088,10 +1469,11 @@ function PackageInstallPrompt() {
1088
1469
  //#endregion
1089
1470
  //#region src/components/app.tsx
1090
1471
  const App = () => {
1472
+ useTheme();
1091
1473
  useEffect(() => {
1092
1474
  const handlePreloadError = (event) => {
1093
1475
  const payload = event.payload;
1094
- const failedUrl = (payload instanceof Error ? payload.message : String(payload ?? "")).match(/https?:\/\/[^\s"']+/)?.[0];
1476
+ const failedUrl = (payload instanceof Error ? payload.message : typeof payload === "string" ? payload : "").match(/https?:\/\/[^\s"']+/)?.[0];
1095
1477
  if (failedUrl && !failedUrl.startsWith(window.location.origin)) {
1096
1478
  console.debug(`[Connect] Skipping reload — vite:preloadError for off-origin URL: ${failedUrl}`);
1097
1479
  return;
@@ -1113,7 +1495,8 @@ const App = () => {
1113
1495
  /* @__PURE__ */ jsx(MissingModelBanner, {}),
1114
1496
  /* @__PURE__ */ jsx(Router, {}),
1115
1497
  /* @__PURE__ */ jsx(PackageInstallPrompt, {}),
1116
- /* @__PURE__ */ jsx(Analytics, {})
1498
+ /* @__PURE__ */ jsx(Analytics, {}),
1499
+ /* @__PURE__ */ jsx(OpenPanel, {})
1117
1500
  ] });
1118
1501
  };
1119
1502
  //#endregion
@@ -1151,8 +1534,8 @@ const CookieBanner$1 = () => {
1151
1534
  if (!showBanner) return null;
1152
1535
  return /* @__PURE__ */ jsxs("div", {
1153
1536
  className: "absolute inset-0 z-10000 backdrop-blur-sm",
1154
- children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black opacity-15" }), /* @__PURE__ */ jsx("div", {
1155
- className: "absolute inset-x-0 bottom-0 flex justify-center bg-white px-10 pt-10 pb-16 shadow-lg",
1537
+ children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gray-900 opacity-15 dark:bg-slate-50" }), /* @__PURE__ */ jsx("div", {
1538
+ className: "absolute inset-x-0 bottom-0 flex justify-center bg-gray-50 px-10 pt-10 pb-16 shadow-lg dark:bg-slate-800",
1156
1539
  children: /* @__PURE__ */ jsx(CookieBanner, {
1157
1540
  className: "max-w-[1024px]",
1158
1541
  cookies: cookiesInput,
@@ -1161,12 +1544,12 @@ const CookieBanner$1 = () => {
1161
1544
  submitLabel: t("cookieBanner.accept"),
1162
1545
  rejectLabel: t("cookieBanner.reject"),
1163
1546
  children: /* @__PURE__ */ jsx("p", {
1164
- className: "font-semibold text-gray-500",
1547
+ className: "font-semibold text-gray-500 dark:text-slate-400",
1165
1548
  children: /* @__PURE__ */ jsx(Trans, {
1166
1549
  i18nKey: "cookieBanner.message",
1167
1550
  components: { a: /* @__PURE__ */ jsx("a", {
1168
1551
  onClick: () => showPHModal({ type: "cookiesPolicy" }),
1169
- className: "cursor-pointer text-gray-900 hover:underline"
1552
+ className: "cursor-pointer text-gray-900 hover:underline dark:text-slate-50"
1170
1553
  }, "cookieBanner.message-link") }
1171
1554
  }, "cookieBanner.message")
1172
1555
  })
@@ -1345,14 +1728,14 @@ const DocumentEditor = (props) => {
1345
1728
  //#region src/components/root.tsx
1346
1729
  function Root() {
1347
1730
  return /* @__PURE__ */ jsx("div", {
1348
- className: "h-screen",
1731
+ className: "h-screen bg-gray-50 dark:bg-slate-800",
1349
1732
  children: /* @__PURE__ */ jsx("div", {
1350
1733
  className: `flex h-screen items-stretch overflow-auto`,
1351
1734
  role: "presentation",
1352
1735
  tabIndex: 0,
1353
1736
  children: /* @__PURE__ */ jsxs(Suspense, {
1354
1737
  name: "Root",
1355
- children: [/* @__PURE__ */ jsx(Sidebar, {}), /* @__PURE__ */ jsx("div", {
1738
+ children: [!useIsEmbedded() && /* @__PURE__ */ jsx(Sidebar, {}), /* @__PURE__ */ jsx("div", {
1356
1739
  className: "relative flex-1 overflow-auto",
1357
1740
  children: /* @__PURE__ */ jsx(Outlet, {})
1358
1741
  })]
@@ -1452,7 +1835,9 @@ function Sidebar() {
1452
1835
  onClickSettings,
1453
1836
  address: user?.address,
1454
1837
  onLogin: openRenown,
1455
- onDisconnect: logout,
1838
+ onDisconnect: () => {
1839
+ logout();
1840
+ },
1456
1841
  ensName: ensName || ensInfo.data?.ens,
1457
1842
  avatarUrl: avatarUrl || ensInfo.data?.avatar_small || ensInfo.data?.avatar_url || void 0,
1458
1843
  etherscanUrl,
@@ -1474,5 +1859,5 @@ function Sidebar() {
1474
1859
  //#endregion
1475
1860
  export { AppLoader as t };
1476
1861
 
1477
- //# sourceMappingURL=sidebar-BLHOoVIg.js.map
1478
- //# debugId=ebf04d37-dff0-53fa-872d-097855e3824e
1862
+ //# sourceMappingURL=sidebar-CO3JjI3G.js.map
1863
+ //# debugId=239c52db-b664-5e9c-ac37-c27d54ef59b8