@marimo-team/frontend 0.23.16-dev3 → 0.23.16-dev5

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.
package/dist/index.html CHANGED
@@ -66,7 +66,7 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-Dbc5mg7a.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-CMZzy-dF.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-TXkS1QI3.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/objects-BlG0ZrO0.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/chunk-LvLJmgfZ.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.23.16-dev3",
3
+ "version": "0.23.16-dev5",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -0,0 +1,27 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { describe, expect, it } from "vitest";
4
+ import { getFileRenderMode } from "../file-render-mode";
5
+
6
+ describe("getFileRenderMode", () => {
7
+ it.each([
8
+ ["text/plain", false, "text"],
9
+ ["text/x-rust", false, "text"],
10
+ ["application/json", false, "text"],
11
+ ["application/xml", false, "text"],
12
+ ["text/csv", false, "csv"],
13
+ ["image/png", true, "media"],
14
+ ["video/mp4", true, "media"],
15
+ ["application/pdf", true, "media"],
16
+ ["application/x-apple-diskimage", true, "unsupported"],
17
+ ["application/zip", true, "unsupported"],
18
+ ["application/octet-stream", false, "unsupported"],
19
+ [null, false, "text"],
20
+ [null, true, "unsupported"],
21
+ ] as const)(
22
+ "maps %s with isBase64=%s to %s",
23
+ (mimeType, isBase64, expected) => {
24
+ expect(getFileRenderMode(mimeType, isBase64)).toBe(expected);
25
+ },
26
+ );
27
+ });
@@ -0,0 +1,150 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { fireEvent, render, screen, waitFor } from "@testing-library/react";
4
+ import { Provider } from "jotai";
5
+ import type React from "react";
6
+ import { beforeEach, describe, expect, it, vi } from "vitest";
7
+ import { MockRequestClient } from "@/__mocks__/requests";
8
+ import { TooltipProvider } from "@/components/ui/tooltip";
9
+ import { requestClientAtom } from "@/core/network/requests";
10
+ import type { FileDetailsResponse, FileInfo } from "@/core/network/types";
11
+ import { store } from "@/core/state/jotai";
12
+ import { FileViewer, MAX_FILE_PREVIEW_BYTES } from "../file-viewer";
13
+
14
+ vi.mock("@/plugins/impl/code/LazyAnyLanguageCodeMirror", () => ({
15
+ LazyAnyLanguageCodeMirror: ({
16
+ value,
17
+ onChange,
18
+ }: {
19
+ value?: string;
20
+ onChange?: (value: string) => void;
21
+ }) => (
22
+ <textarea
23
+ data-testid="code-editor"
24
+ value={value ?? ""}
25
+ onChange={(evt) => onChange?.(evt.target.value)}
26
+ />
27
+ ),
28
+ }));
29
+
30
+ vi.mock("@/core/wasm/utils", () => ({ isWasm: () => false }));
31
+
32
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
33
+ <Provider store={store}>
34
+ <TooltipProvider>{children}</TooltipProvider>
35
+ </Provider>
36
+ );
37
+
38
+ const file: FileInfo = {
39
+ id: "/workspace/installer.dmg",
40
+ path: "/workspace/installer.dmg",
41
+ name: "installer.dmg",
42
+ isDirectory: false,
43
+ isMarimoFile: false,
44
+ size: 20 * 1024 * 1024,
45
+ };
46
+
47
+ function renderViewer(response: FileDetailsResponse) {
48
+ const client = MockRequestClient.create({
49
+ sendFileDetails: vi.fn().mockResolvedValue(response),
50
+ });
51
+ store.set(requestClientAtom, client);
52
+ render(<FileViewer file={file} onOpenNotebook={vi.fn()} />, { wrapper });
53
+ return client;
54
+ }
55
+
56
+ describe("FileViewer bounded previews", () => {
57
+ beforeEach(() => {
58
+ store.set(requestClientAtom, null);
59
+ });
60
+
61
+ it("requests a bounded preview and shows oversized metadata", async () => {
62
+ const client = renderViewer({
63
+ file,
64
+ contents: null,
65
+ mimeType: "application/x-apple-diskimage",
66
+ isBase64: false,
67
+ isTooLarge: true,
68
+ });
69
+
70
+ expect(await screen.findByText(/too large to preview/i)).toBeVisible();
71
+ expect(screen.getByText("20 MB")).toBeVisible();
72
+ expect(screen.getByRole("button", { name: /download/i })).toBeVisible();
73
+ expect(screen.queryByTestId("code-editor")).not.toBeInTheDocument();
74
+ expect(client.sendFileDetails).toHaveBeenCalledWith({
75
+ path: file.path,
76
+ maxBytes: MAX_FILE_PREVIEW_BYTES,
77
+ });
78
+ });
79
+
80
+ it("shows unsupported metadata with a download action, not base64 text", async () => {
81
+ renderViewer({
82
+ file: { ...file, size: 4 },
83
+ contents: "AAEC",
84
+ mimeType: "application/x-apple-diskimage",
85
+ isBase64: true,
86
+ isTooLarge: false,
87
+ });
88
+
89
+ expect(await screen.findByText(/cannot be previewed/i)).toBeVisible();
90
+ expect(screen.getByRole("button", { name: /download/i })).toBeVisible();
91
+ expect(screen.queryByTestId("code-editor")).not.toBeInTheDocument();
92
+ });
93
+
94
+ it("continues to render small text files", async () => {
95
+ renderViewer({
96
+ file: { ...file, name: "notes.txt", size: 5 },
97
+ contents: "hello",
98
+ mimeType: "text/plain",
99
+ isBase64: false,
100
+ isTooLarge: false,
101
+ });
102
+
103
+ await waitFor(() => {
104
+ expect(screen.getByTestId("code-editor")).toBeInTheDocument();
105
+ });
106
+ expect(screen.queryByText(/too large to preview/i)).not.toBeInTheDocument();
107
+ });
108
+
109
+ it("preserves edits to an initially empty text file across remount", async () => {
110
+ const emptyFile: FileInfo = {
111
+ id: "/workspace/empty.txt",
112
+ path: "/workspace/empty.txt",
113
+ name: "empty.txt",
114
+ isDirectory: false,
115
+ isMarimoFile: false,
116
+ size: 0,
117
+ };
118
+ const response: FileDetailsResponse = {
119
+ file: emptyFile,
120
+ contents: "",
121
+ mimeType: "text/plain",
122
+ isBase64: false,
123
+ isTooLarge: false,
124
+ };
125
+ const client = MockRequestClient.create({
126
+ sendFileDetails: vi.fn().mockResolvedValue(response),
127
+ });
128
+ store.set(requestClientAtom, client);
129
+
130
+ const { unmount } = render(
131
+ <FileViewer file={emptyFile} onOpenNotebook={vi.fn()} />,
132
+ { wrapper },
133
+ );
134
+
135
+ const editor =
136
+ await screen.findByTestId<HTMLTextAreaElement>("code-editor");
137
+ fireEvent.change(editor, { target: { value: "draft" } });
138
+ unmount();
139
+
140
+ render(<FileViewer file={emptyFile} onOpenNotebook={vi.fn()} />, {
141
+ wrapper,
142
+ });
143
+
144
+ const reopened =
145
+ await screen.findByTestId<HTMLTextAreaElement>("code-editor");
146
+ await waitFor(() => {
147
+ expect(reopened.value).toBe("draft");
148
+ });
149
+ });
150
+ });
@@ -0,0 +1,51 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { DownloadIcon } from "lucide-react";
4
+ import { useLocale } from "react-aria";
5
+ import { Button } from "@/components/ui/button";
6
+ import type { FileInfo } from "@/core/network/types";
7
+ import { formatBytes } from "@/utils/formatting";
8
+
9
+ interface Props {
10
+ file: FileInfo;
11
+ mimeType: string;
12
+ message: string;
13
+ onDownload?: () => void;
14
+ }
15
+
16
+ export const FilePreviewMetadata = ({
17
+ file,
18
+ mimeType,
19
+ message,
20
+ onDownload,
21
+ }: Props) => {
22
+ const { locale } = useLocale();
23
+ return (
24
+ <div className="p-4 text-sm">
25
+ <div className="grid grid-cols-[auto_1fr] gap-x-4 gap-y-2">
26
+ <span className="text-muted-foreground font-medium">Path</span>
27
+ <span className="font-mono text-xs break-all">{file.path}</span>
28
+ <span className="text-muted-foreground font-medium">Type</span>
29
+ <span>{mimeType}</span>
30
+ {file.size != null && (
31
+ <>
32
+ <span className="text-muted-foreground font-medium">Size</span>
33
+ <span>{formatBytes(file.size, locale)}</span>
34
+ </>
35
+ )}
36
+ </div>
37
+ <div className="mt-4 text-muted-foreground italic">{message}</div>
38
+ {onDownload && (
39
+ <Button
40
+ variant="outline"
41
+ size="sm"
42
+ className="mt-4"
43
+ onClick={onDownload}
44
+ >
45
+ <DownloadIcon className="h-3.5 w-3.5 mr-2" />
46
+ Download
47
+ </Button>
48
+ )}
49
+ </div>
50
+ );
51
+ };
@@ -0,0 +1,32 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { isMediaMime, MIME_TO_LANGUAGE } from "./renderers";
4
+
5
+ export type FileRenderMode = "text" | "csv" | "media" | "unsupported";
6
+
7
+ export function getFileRenderMode(
8
+ mimeType: string | null | undefined,
9
+ isBase64: boolean | undefined,
10
+ ): FileRenderMode {
11
+ const mime = mimeType || "text/plain";
12
+
13
+ if (isMediaMime(mime)) {
14
+ return "media";
15
+ }
16
+ if (isBase64) {
17
+ return "unsupported";
18
+ }
19
+ if (mime === "text/csv") {
20
+ return "csv";
21
+ }
22
+ if (
23
+ mime.startsWith("text/") ||
24
+ (mime !== "default" && mime in MIME_TO_LANGUAGE)
25
+ ) {
26
+ return "text";
27
+ }
28
+ if (mimeType == null) {
29
+ return "text";
30
+ }
31
+ return "unsupported";
32
+ }
@@ -25,11 +25,11 @@ import { copyToClipboard } from "@/utils/copy";
25
25
  import type { Base64String } from "@/utils/json/base64";
26
26
  import { downloadFile } from "./download";
27
27
  import { FilePreviewHeader } from "./file-header";
28
- import {
29
- FileContentRenderer,
30
- isMediaMime,
31
- MIME_TO_LANGUAGE,
32
- } from "./renderers";
28
+ import { FilePreviewMetadata } from "./file-preview-metadata";
29
+ import { getFileRenderMode } from "./file-render-mode";
30
+ import { FileContentRenderer } from "./renderers";
31
+
32
+ export const MAX_FILE_PREVIEW_BYTES = 10 * 1024 * 1024;
33
33
 
34
34
  interface Props {
35
35
  file: FileInfo;
@@ -50,9 +50,15 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
50
50
 
51
51
  const { data, isPending, error, setData, refetch } =
52
52
  useAsyncData(async () => {
53
- const details = await sendFileDetails({ path: file.path });
54
- const contents = details.contents || "";
55
- setInternalValue(unsavedContentsForFile.get(file.path) || contents);
53
+ const details = await sendFileDetails({
54
+ path: file.path,
55
+ maxBytes: MAX_FILE_PREVIEW_BYTES,
56
+ });
57
+ const mode = getFileRenderMode(details.mimeType, details.isBase64);
58
+ if (!details.isTooLarge && mode === "text") {
59
+ const contents = details.contents || "";
60
+ setInternalValue(unsavedContentsForFile.get(file.path) ?? contents);
61
+ }
56
62
  return details;
57
63
  }, [file.path]);
58
64
 
@@ -72,13 +78,19 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
72
78
  );
73
79
  };
74
80
 
75
- // On file change or unmount, save the unsaved contents
81
+ // On file change or unmount, save the unsaved contents. Only editable text
82
+ // previews participate in editor state; oversized and non-text responses
83
+ // carry no draft to preserve.
76
84
  // We use a ref for internalValue so we don't call this effect on each keystroke
77
85
  const internalValueRef = useRef<string>(internalValue);
78
86
  internalValueRef.current = internalValue;
79
87
  useEffect(() => {
80
88
  return () => {
81
- if (!data?.contents) {
89
+ if (
90
+ data?.contents == null ||
91
+ data.isTooLarge ||
92
+ getFileRenderMode(data.mimeType, data.isBase64) !== "text"
93
+ ) {
82
94
  return;
83
95
  }
84
96
  const draft = internalValueRef.current;
@@ -88,7 +100,13 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
88
100
  unsavedContentsForFile.set(file.path, draft);
89
101
  }
90
102
  };
91
- }, [file.path, data?.contents]);
103
+ }, [
104
+ file.path,
105
+ data?.contents,
106
+ data?.isTooLarge,
107
+ data?.mimeType,
108
+ data?.isBase64,
109
+ ]);
92
110
 
93
111
  if (error) {
94
112
  return <ErrorBanner error={error} />;
@@ -99,7 +117,10 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
99
117
  }
100
118
 
101
119
  const mimeType = data.mimeType || "text/plain";
102
- const isEditable = mimeType in MIME_TO_LANGUAGE;
120
+ const renderMode = getFileRenderMode(data.mimeType, data.isBase64);
121
+ const isText = renderMode === "text";
122
+ const isCsv = renderMode === "csv";
123
+ const isMedia = renderMode === "media";
103
124
  const isActiveNotebook =
104
125
  currentNotebookFilename &&
105
126
  data.file.isMarimoFile &&
@@ -108,22 +129,27 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
108
129
  // but this is an okay heuristic for now.
109
130
  file.path.endsWith(`/${currentNotebookFilename}`));
110
131
 
111
- if (!data.contents && !isEditable) {
112
- // Show details instead of contents
113
- return (
114
- <div className="grid grid-cols-2 gap-2 p-6">
115
- <div className="font-bold text-muted-foreground">Name</div>
116
- <div>{data.file.name}</div>
117
- <div className="font-bold text-muted-foreground">Type</div>
118
- <div>{mimeType}</div>
119
- </div>
120
- );
121
- }
122
-
123
132
  const handleDownload = async () => {
124
133
  await downloadFile(file.path, data.file.name);
125
134
  };
126
135
 
136
+ const saveKeymapExtension = keymap.of([
137
+ {
138
+ key: hotkeys.getHotkey("global.save").key,
139
+ stopPropagation: true,
140
+ run: () => {
141
+ if (internalValue !== data.contents) {
142
+ void handleSaveFile();
143
+ return true;
144
+ }
145
+ return false;
146
+ },
147
+ },
148
+ ]);
149
+
150
+ // Defined before the metadata-only returns so refresh, download, and
151
+ // open-notebook stay available while edit-only copy/save are withheld from
152
+ // non-text previews.
127
153
  const header = (
128
154
  <FilePreviewHeader
129
155
  filename={data.file.name}
@@ -142,7 +168,7 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
142
168
  </Button>
143
169
  </Tooltip>
144
170
  )}
145
- {!isMediaMime(mimeType) && (
171
+ {isText && (
146
172
  <>
147
173
  <Tooltip content="Copy contents to clipboard">
148
174
  <Button
@@ -172,8 +198,23 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
172
198
  />
173
199
  );
174
200
 
175
- const isMedia = isMediaMime(mimeType);
176
- const isText = !isMedia && mimeType !== "text/csv";
201
+ if (data.isTooLarge || renderMode === "unsupported") {
202
+ return (
203
+ <>
204
+ {header}
205
+ <FilePreviewMetadata
206
+ file={data.file}
207
+ mimeType={mimeType}
208
+ message={
209
+ data.isTooLarge
210
+ ? "File is too large to preview."
211
+ : "This file type cannot be previewed."
212
+ }
213
+ onDownload={disableFileDownloads ? undefined : handleDownload}
214
+ />
215
+ </>
216
+ );
217
+ }
177
218
 
178
219
  const warningBanner = isText && isActiveNotebook && (
179
220
  <Alert variant="warning" className="rounded-none">
@@ -192,35 +233,20 @@ export const FileViewer: React.FC<Props> = ({ file, onOpenNotebook }) => {
192
233
  <FileContentRenderer
193
234
  mimeType={mimeType}
194
235
  contents={
195
- isMedia
196
- ? undefined
197
- : isText
198
- ? internalValue
199
- : (data.contents ?? undefined)
236
+ isText
237
+ ? internalValue
238
+ : isCsv
239
+ ? (data.contents ?? undefined)
240
+ : undefined
200
241
  }
201
242
  mediaSource={
202
- isMedia
243
+ isMedia && data.contents
203
244
  ? { base64: data.contents as Base64String, mime: mimeType }
204
245
  : undefined
205
246
  }
206
247
  readOnly={!isText}
207
- onChange={setInternalValue}
208
- extensions={[
209
- // Command S for save
210
- keymap.of([
211
- {
212
- key: hotkeys.getHotkey("global.save").key,
213
- stopPropagation: true,
214
- run: () => {
215
- if (internalValue !== data.contents) {
216
- handleSaveFile();
217
- return true;
218
- }
219
- return false;
220
- },
221
- },
222
- ]),
223
- ]}
248
+ onChange={isText ? setInternalValue : undefined}
249
+ extensions={isText ? [saveKeymapExtension] : []}
224
250
  />
225
251
  </>
226
252
  );
@@ -191,7 +191,9 @@ export interface EditRequests {
191
191
  request: FileMoveRequest,
192
192
  ) => Promise<FileMoveResponse>;
193
193
  sendUpdateFile: (request: FileUpdateRequest) => Promise<FileUpdateResponse>;
194
- sendFileDetails: (request: { path: string }) => Promise<FileDetailsResponse>;
194
+ sendFileDetails: (
195
+ request: FileDetailsRequest,
196
+ ) => Promise<FileDetailsResponse>;
195
197
  // Homepage requests
196
198
  openTutorial: (request: OpenTutorialRequest) => Promise<MarimoFile>;
197
199
  getRecentFiles: () => Promise<RecentFilesResponse>;
@@ -1,26 +0,0 @@
1
- import{s as Ge}from"./chunk-LvLJmgfZ.js";import{i as It,l as Fe,n as ae,p as Je,u as ge}from"./useEvent-D91BmmQi.js";import{t as Et}from"./react-Bj1aDYRI.js";import{Ar as At,E as Ht,Hi as qt,Ki as Ye,zn as Xe}from"./cells-Cf7bHHq3.js";import"./react-dom-CSu739Rf.js";import{t as fe}from"./compiler-runtime-B3qBwwSJ.js";import{g as Me}from"./useEventListener-B_w3A283.js";import{t as Ut}from"./invariant-CkiqGLcK.js";import{g as Kt,p as Ze}from"./utils-Z80SV4_d.js";import{T as je,r as Wt}from"./config-BbOTTCYY.js";import{t as oe}from"./cn-DYvqRARy.js";import{t as Gt}from"./jsx-runtime-Blw4afVn.js";import"./fullscreen-dUjPYOmm.js";import{r as Jt}from"./config-COUOIPEq.js";import{o as Yt}from"./alert-dialog-BXegNC0I.js";import"./popover-DrHQ3KEt.js";import{a as X,c as ue,p as Xt,r as Zt,t as Qt}from"./dropdown-menu-BFZLnWeO.js";import{Lt as Pe,a as ea,i as Qe,m as ta,o as De}from"./JsonOutput-CkCD-FgM.js";import{c as aa,i as ze,r as et}from"./download-BomYt3nl.js";import{r as tt}from"./radio-group-CLBjGkt5.js";import{t as Z}from"./tooltip-CFX4fYHU.js";import{n as ra,t as H}from"./button-eIihcbUw.js";import{Tt as na}from"./dist-12S8I4CH.js";import"./cjs-D5tzp-Y6.js";import"./main-BNL5rxQw.js";import"./useNonce-CbdaHKzX.js";import{n as sa,r as Te,t as oa}from"./requests-9-v2bhoi.js";import{t as ne}from"./createLucideIcon-w-Qo9n0R.js";import{a as la,i as at,l as rt,n as _e,o as ye,r as ia,s as Oe,t as ca}from"./state-WBgc7MiA.js";import{n as da}from"./LazyAnyLanguageCodeMirror-sVm_hz8A.js";import{t as ma}from"./x-C-Eq0ag8.js";import{a as pa,i as $e,n as ha,r as nt,t as be}from"./tree-actions-CsC2XmGo.js";import{a as xa}from"./markdown-renderer-QvXG0CRk.js";import{u as fa}from"./toDate-Ct2FT81-.js";import{t as st}from"./copy-3iHFdt22.js";import{t as Le}from"./external-link-BOlXZUla.js";import{a as ua,i as ot,n as lt,r as ya,t as ga}from"./file-icons-Cb54mIL8.js";import{t as it}from"./file-CJH9JNGH.js";import{i as ct,r as ja,t as dt}from"./add-connection-dialog-B-jCRNTN.js";import{n as ve,t as ba}from"./spinner-D-V4psAa.js";import{a as va,c as wa,d as Na,f as ka,i as Sa,l as Ca,n as Fa,r as _a,t as Ma,u as Pa}from"./file-name-input-BWFcK1ey.js";import{t as mt}from"./plus-AgXtozBz.js";import{t as pt}from"./refresh-cw-CYq4mK5a.js";import{t as Da}from"./save-DBuEmnnF.js";import{t as za}from"./triangle-alert-BL4YVsPy.js";import{n as Ta,t as Oa}from"./es-1D83cgiu.js";import"./dist-DcwTQG1A.js";import"./dist-DnjsPBRJ.js";import"./dist-BJZAIIze.js";import"./dist-aRc_dRed.js";import"./dist-CPjTeT8p.js";import{t as re}from"./use-toast-BwJoaaDM.js";import{t as $a}from"./paths-BKO-pHK6.js";import"./session-CEFnN9Cq.js";import"./purify.es-CWmnYhGI.js";import"./dates-D-kIKDYA.js";import{n as we}from"./copy-BtTOqPTS.js";import{t as La}from"./copy-icon-C2pG0ZNK.js";import{t as ht}from"./context-BFPaAUK_.js";import{n as xt}from"./ImperativeModal-BIavOiUv.js";import{t as Ba}from"./blob-C3EfaMOb.js";import"./tooltip-HLb6RxVp.js";import"./vega-loader.browser-Dun7Qe4B.js";import"./defaultLocale-DOVIEEPN.js";import"./defaultLocale-BUCH2FMc.js";import{n as Ra,t as Va}from"./alert-jlwhGxSb.js";import{n as ft}from"./error-banner-B6eIlxzg.js";import"./chunk-5FQGJX7Z-Cp0LZT-a.js";import"./html-to-image-CwmX28T9.js";import{o as Ia}from"./focus-DiEyfiAG.js";import{n as Be}from"./useAsyncData-Bg5iAViP.js";import"./react-resizable-panels.browser.esm-Z-MD3n3J.js";import{a as Ea,f as Aa,o as ut,t as Ha}from"./command-CAJLPEBq.js";import{a as qa}from"./renderShortcut-BZLr8D7H.js";import{t as Ua}from"./bundle.esm-D0TWQ6iT.js";import{n as Ka}from"./pathUtils-Bfcp5m-a.js";import{n as Wa}from"./semaphore-DtBYRzWS.js";import{t as Ga}from"./empty-state-CqJvEFRk.js";import{t as Re}from"./formatting-B_41gSF5.js";import{a as Ja,i as Ya,n as yt,r as gt,t as jt}from"./components-BH6gDVv6.js";import{n as bt,t as Xa}from"./marimo-icons-C_nFooxr.js";import{t as Za}from"./links-CToBjIIj.js";var Qa=ne("book-plus",[["path",{d:"M12 7v6",key:"lw1j43"}],["path",{d:"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20",key:"k3hazp"}],["path",{d:"M9 10h6",key:"9gxzsh"}]]),er=ne("copy-minus",[["line",{x1:"12",x2:"18",y1:"15",y2:"15",key:"1nscbv"}],["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]),vt=ne("file-plus-corner",[["path",{d:"M11.35 22H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v5.35",key:"17jvcc"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M14 19h6",key:"bvotb8"}],["path",{d:"M17 16v6",key:"18yu1i"}]]),tr=ne("file-symlink",[["path",{d:"M4 11V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h7",key:"huwfnr"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"m10 18 3-3-3-3",key:"18f6ys"}]]),wt=ne("folder-plus",[["path",{d:"M12 10v6",key:"1bos4e"}],["path",{d:"M9 13h6",key:"1uhe8q"}],["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]]),Nt=ne("list-tree",[["path",{d:"M8 5h13",key:"1pao27"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 19h8",key:"c3s6r1"}],["path",{d:"M3 10a2 2 0 0 0 2 2h3",key:"1npucw"}],["path",{d:"M3 5v12a2 2 0 0 0 2 2h3",key:"x1gjn2"}]]),ar=ne("square-play",[["rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",key:"h1oib"}],["path",{d:"M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z",key:"kmsa83"}]]),kt=ne("view",[["path",{d:"M21 17v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2",key:"mrq65r"}],["path",{d:"M21 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v2",key:"be3xqs"}],["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["path",{d:"M18.944 12.33a1 1 0 0 0 0-.66 7.5 7.5 0 0 0-13.888 0 1 1 0 0 0 0 .66 7.5 7.5 0 0 0 13.888 0",key:"11ak4c"}]]),$=Ge(Et(),1),rr=fe(),a=Ge(Gt(),1);const St=t=>{let e=(0,rr.c)(17),{filename:r,filenameIcon:s,onBack:l,onRefresh:n,onDownload:p,actions:i}=t,m;e[0]===l?m=e[1]:(m=l&&(0,a.jsx)(Z,{content:"Back to file list",children:(0,a.jsx)(H,{variant:"text",size:"xs",onClick:l,children:(0,a.jsx)(rt,{className:"h-4 w-4"})})}),e[0]=l,e[1]=m);let o;e[2]!==r||e[3]!==s?(o=r?(0,a.jsxs)("span",{className:"flex items-center gap-1.5 flex-1 min-w-0 text-xs font-semibold truncate",children:[s,r]}):(0,a.jsx)("span",{className:"flex-1"}),e[2]=r,e[3]=s,e[4]=o):o=e[4];let u;e[5]===n?u=e[6]:(u=n&&(0,a.jsx)(Z,{content:"Refresh",children:(0,a.jsx)(H,{variant:"text",size:"xs",onClick:n,children:(0,a.jsx)(pt,{className:"h-3.5 w-3.5"})})}),e[5]=n,e[6]=u);let h;e[7]===p?h=e[8]:(h=p&&(0,a.jsx)(Z,{content:"Download",children:(0,a.jsx)(H,{variant:"text",size:"xs",onClick:p,children:(0,a.jsx)(Pe,{className:"h-3.5 w-3.5"})})}),e[7]=p,e[8]=h);let f;e[9]!==i||e[10]!==u||e[11]!==h?(f=(0,a.jsxs)("div",{className:"flex items-center gap-0.5 shrink-0",children:[u,i,h]}),e[9]=i,e[10]=u,e[11]=h,e[12]=f):f=e[12];let y;return e[13]!==m||e[14]!==o||e[15]!==f?(y=(0,a.jsxs)("div",{className:"flex items-center shrink-0 border-b px-1 gap-1",children:[m,o,f]}),e[13]=m,e[14]=o,e[15]=f,e[16]=y):y=e[16],y};var nr=new Set(["http","file","in-memory"]);function Ve(t){return JSON.stringify(t).slice(1,-1)}const Ct=[{id:"read-file",label:"Insert read snippet",icon:Qa,getCode:t=>{if(t.entry.kind==="directory")return null;let e=Ve(t.entry.path);return t.backendType==="obstore"?`_data = ${t.variableName}.get("${e}").bytes()
2
- _data`:`_data = ${t.variableName}.cat_file("${e}")
3
- _data`}},{id:"download-file",label:"Insert download snippet",icon:tr,getCode:t=>{if(t.entry.kind==="directory")return null;let e=Ve(t.entry.path);if(t.backendType==="obstore")return nr.has(t.protocol)?null:`from datetime import timedelta
4
- from obstore import sign
5
-
6
- signed_url = sign(
7
- ${t.variableName}, "GET", "${e}",
8
- expires_in=timedelta(hours=1),
9
- )
10
- signed_url`;let r=Ve(t.entry.path.split("/").pop()||"download");return`${t.variableName}.get("${e}", "${r}")`}}];var sr=100*1024*1024;function or(t){let e=t.endsWith("/")?t.slice(0,-1):t,r=e.split("/");return r[r.length-1]||e}const lr=({entry:t,namespace:e,protocol:r,backendType:s,onBack:l})=>{let{locale:n}=ht(),p=tt(),i=or(t.path),m=t.mimeType||"text/plain",o=De(m),u=o&&t.size>sr&&t.size>0,{data:h,isPending:f,error:y,refetch:g}=Be(async()=>{if(u)return null;let c=await Oe.request({namespace:e,path:t.path,preview:!o});if(c.error)throw Error(c.error);if(!c.url)throw Error("No URL returned");if(o)return{type:"media",url:c.url};let b=await fetch(c.url);if(!b.ok)throw Error(`Failed to fetch preview: ${b.statusText}`);return{type:"text",content:await b.text()}},[e,t.path,o,u]),k=(0,$.useCallback)(async()=>{try{let c=await Oe.request({namespace:e,path:t.path});if(c.error){re({title:"Download failed",description:c.error,variant:"danger"});return}c.url&&ze(c.url,c.filename??i)}catch(c){Me.error("Failed to download storage entry",c),re({title:"Download failed",description:String(c),variant:"danger"})}},[e,t.path,i]),x=Ct.map(c=>{let b=c.getCode({variableName:e,protocol:r,entry:t,backendType:s});if(b===null)return null;let C=c.icon;return(0,a.jsx)(Z,{content:c.label,children:(0,a.jsx)(H,{variant:"text",size:"xs",onClick:()=>p(b),"aria-label":c.label,children:(0,a.jsx)(C,{className:"h-3.5 w-3.5"})})},c.id)}),F=(0,a.jsx)(St,{filename:i,filenameIcon:ot(i),onBack:l,onDownload:k,actions:x}),j=({includeMime:c=!1})=>(0,a.jsxs)("div",{className:"grid grid-cols-[auto_1fr] gap-x-4 gap-y-1.5 p-4 text-xs",children:[(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Path"}),(0,a.jsxs)("div",{className:"truncate flex items-center gap-1.5",children:[(0,a.jsx)("span",{className:"font-mono text-[11px]",children:t.path}),(0,a.jsx)(La,{value:t.path,className:"h-3 w-3"})]}),c&&(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Type"}),c&&(0,a.jsx)("span",{children:m}),t.size>0&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Size"}),(0,a.jsx)("span",{children:Re(t.size,n)})]}),t.lastModified!=null&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Modified"}),(0,a.jsx)("span",{children:new Date(t.lastModified*1e3).toLocaleString()})]})]});return u?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[F,j({includeMime:!0}),(0,a.jsxs)("div",{className:"px-4 pb-4 text-xs text-muted-foreground italic",children:["File is too large to preview (",Re(t.size,n),")."]})]}):f?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[F,j({}),(0,a.jsxs)("div",{className:"flex-1 flex items-center justify-center gap-2 text-xs text-muted-foreground min-h-24",children:[(0,a.jsx)(ve,{className:"h-4 w-4 animate-spin"}),"Loading preview..."]})]}):y?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[F,j({includeMime:!0}),(0,a.jsxs)("div",{className:"px-4 pb-4 text-xs text-destructive",children:["Failed to load preview: ",y.message]}),(0,a.jsx)("div",{className:"px-4 pb-4",children:(0,a.jsxs)(H,{variant:"secondary",size:"xs",onClick:g,children:[(0,a.jsx)(pt,{className:"h-3 w-3 mr-1"}),"Retry"]})})]}):h?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[F,j({}),(0,a.jsx)(Qe,{mimeType:m,contents:h.type==="text"?h.content:void 0,mediaSource:h.type==="media"?{url:h.url}:void 0})]}):(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[F,j({includeMime:!0}),(0,a.jsxs)("div",{className:"p-4 flex items-center gap-2 text-xs text-muted-foreground",children:[(0,a.jsx)(it,{className:"h-4 w-4"}),"Preview not available for this file type."]})]})};var Ie=fe(),ir=16;function le(t){return{paddingLeft:t*ir}}function cr(t,e){return new Date(t*1e3).toLocaleDateString(e,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function Ee(t){let e=t.endsWith("/")?t.slice(0,-1):t,r=e.split("/");return r[r.length-1]||e}function Ae(t){return t.endsWith("/")?t:`${t}/`}function He(t,e){var s;let r=(s=t.metadata)==null?void 0:s.id;return typeof r=="string"&&r.length>0?r:`${t.path}::${e}`}function qe(t,{namespace:e,searchValue:r,entriesByPath:s}){let l=r.trim().toLowerCase(),n=t.path.toLowerCase();if(Ee(t.path).toLowerCase().includes(l)||n.includes(l))return!0;if(t.kind==="directory"){let p=s.get(ye(e,Ae(t.path)));if(p)return p.some(i=>qe(i,{namespace:e,searchValue:r,entriesByPath:s}))}return!1}function Ne(t,e){return e.searchValue.trim()?t.filter(r=>qe(r,e)):t}var dr=5;function mr(t){return{query:t,status:"idle"}}function Ft(t){return t.status==="idle"||t.status==="error"||t.status==="capped"}function _t(t,e,r){var s;return e.get(t)===void 0||((s=r.get(t))==null?void 0:s.nextPageToken)!=null}function pr({hasSearch:t,hasLoadedMatches:e,isPending:r,remoteSearch:s,searchKey:l,entriesByPath:n,pageMetadataByPath:p}){return!t||e||r||!Ft(s)?!1:_t(l,n,p)}function Ue(t){let e=t.trim(),r=e.lastIndexOf("/");return r===-1?"":e.slice(0,r+1)}function hr(t,e){let r=e.trim().toLowerCase();return r?t.path.toLowerCase().includes(r)||Ee(t.path).toLowerCase().includes(r):!0}var Mt=t=>{let e=(0,Ie.c)(15),{depth:r,isLoading:s,error:l,onLoadMore:n}=t,p;e[0]===r?p=e[1]:(p=le(r),e[0]=r,e[1]=p);let i;e[2]===s?i=e[3]:(i=s&&(0,a.jsx)(ve,{className:"h-3 w-3 mr-1 animate-spin"}),e[2]=s,e[3]=i);let m=s?"Loading...":"Load more",o;e[4]!==s||e[5]!==n||e[6]!==i||e[7]!==m?(o=(0,a.jsxs)(H,{variant:"text",size:"xs",className:"h-6 px-0 hover:text-blue-600",disabled:s,onClick:n,children:[i,m]}),e[4]=s,e[5]=n,e[6]=i,e[7]=m,e[8]=o):o=e[8];let u;e[9]===l?u=e[10]:(u=l&&(0,a.jsxs)("span",{className:"ml-2 text-destructive",children:["Failed to load: ",l.message]}),e[9]=l,e[10]=u);let h;return e[11]!==p||e[12]!==o||e[13]!==u?(h=(0,a.jsxs)("div",{className:"py-px text-xs",style:p,children:[o,u]}),e[11]=p,e[12]=o,e[13]=u,e[14]=h):h=e[14],h},xr=t=>{let e=(0,Ie.c)(44),{namespace:r,protocol:s,rootPath:l,backendType:n,prefix:p,depth:i,locale:m,searchValue:o,onOpenFile:u}=t,{entriesByPath:h}=_e(),{entries:f,isPending:y,error:g,hasMore:k,loadMore:x,isLoadingMore:F,loadMoreError:j}=at(r,p);if(y){let d;e[0]===i?d=e[1]:(d=le(i),e[0]=i,e[1]=d);let v;e[2]===Symbol.for("react.memo_cache_sentinel")?(v=(0,a.jsx)(ve,{className:"h-3 w-3 animate-spin"}),e[2]=v):v=e[2];let S;return e[3]===d?S=e[4]:(S=(0,a.jsxs)("div",{className:"flex items-center gap-1.5 py-1 text-xs text-muted-foreground",style:d,children:[v,"Loading..."]}),e[3]=d,e[4]=S),S}if(g){let d;e[5]===i?d=e[6]:(d=le(i),e[5]=i,e[6]=d);let v;return e[7]!==g.message||e[8]!==d?(v=(0,a.jsxs)("div",{className:"py-1 text-xs text-destructive",style:d,children:["Failed to load: ",g.message]}),e[7]=g.message,e[8]=d,e[9]=v):v=e[9],v}if(f.length===0){let d;e[10]===i?d=e[11]:(d=le(i),e[10]=i,e[11]=d);let v;return e[12]===d?v=e[13]:(v=(0,a.jsx)("div",{className:"py-1 text-xs text-muted-foreground italic",style:d,children:"Empty"}),e[12]=d,e[13]=v),v}let c;if(e[14]!==n||e[15]!==f||e[16]!==i||e[17]!==h||e[18]!==m||e[19]!==r||e[20]!==u||e[21]!==s||e[22]!==l||e[23]!==o){let d=Ne(f,{namespace:r,searchValue:o,entriesByPath:h}),v;e[25]!==n||e[26]!==f||e[27]!==i||e[28]!==m||e[29]!==r||e[30]!==u||e[31]!==s||e[32]!==l||e[33]!==o?(v=S=>{let _=He(S,f.indexOf(S));return(0,a.jsx)(Ke,{rowKey:_,entry:S,namespace:r,protocol:s,rootPath:l,backendType:n,depth:i,locale:m,searchValue:o,onOpenFile:u},_)},e[25]=n,e[26]=f,e[27]=i,e[28]=m,e[29]=r,e[30]=u,e[31]=s,e[32]=l,e[33]=o,e[34]=v):v=e[34],c=d.map(v),e[14]=n,e[15]=f,e[16]=i,e[17]=h,e[18]=m,e[19]=r,e[20]=u,e[21]=s,e[22]=l,e[23]=o,e[24]=c}else c=e[24];let b;e[35]!==i||e[36]!==k||e[37]!==F||e[38]!==x||e[39]!==j?(b=k&&(0,a.jsx)(Mt,{depth:i,isLoading:F,error:j,onLoadMore:x}),e[35]=i,e[36]=k,e[37]=F,e[38]=x,e[39]=j,e[40]=b):b=e[40];let C;return e[41]!==c||e[42]!==b?(C=(0,a.jsxs)(a.Fragment,{children:[c,b]}),e[41]=c,e[42]=b,e[43]=C):C=e[43],C},Ke=({entry:t,rowKey:e,namespace:r,protocol:s,rootPath:l,backendType:n,depth:p,locale:i,searchValue:m,onOpenFile:o})=>{var C;let[u,h]=(0,$.useState)(!1),{entriesByPath:f}=_e(),y=tt(),g=t.kind==="directory",k=Ee(t.path),x=!!m.trim(),F=g&&x&&k.toLowerCase().includes(m.trim().toLowerCase()),j=g&&x&&!!((C=f.get(ye(r,Ae(t.path))))!=null&&C.some(d=>qe(d,{namespace:r,searchValue:m,entriesByPath:f}))),c=u||j,b=(0,$.useCallback)(async()=>{try{let d=await Oe.request({namespace:r,path:t.path});if(d.error){re({title:"Download failed",description:d.error,variant:"danger"});return}d.url&&ze(d.url,d.filename??"download")}catch(d){Me.error("Failed to download storage entry",d),re({title:"Download failed",description:String(d),variant:"danger"})}},[r,t.path]);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(ut,{className:oe("text-xs flex items-center gap-1.5 cursor-pointer rounded-none group h-6.5",g&&"font-medium"),style:le(p),value:`${r}:${e}`,onSelect:()=>{g?h(!c):o({entry:t,namespace:r,protocol:s,backendType:n})},children:[g?(0,a.jsx)($e,{isExpanded:c,className:"h-3 w-3"}):(0,a.jsx)("span",{className:"w-3 shrink-0"}),g?(0,a.jsx)(ua,{className:oe("h-3.5 w-3.5 shrink-0",lt.directory)}):ot(k),(0,a.jsx)("span",{className:"truncate flex-1 text-left",children:k}),(0,a.jsxs)("div",{className:"flex items-center",children:[t.size>0&&(0,a.jsx)("span",{className:"text-[10px] text-muted-foreground pr-2 opacity-0 group-hover:opacity-100 transition-opacity tabular-nums",children:Re(t.size,i)}),t.lastModified!=null&&(0,a.jsx)(Z,{content:`Last modified: ${new Date(t.lastModified*1e3).toLocaleString()}`,children:(0,a.jsx)("span",{className:"text-[10px] text-muted-foreground pr-1 opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap",children:cr(t.lastModified,i)})}),(0,a.jsxs)(Qt,{children:[(0,a.jsx)(Xt,{asChild:!0,children:(0,a.jsx)(ha,{iconClassName:"h-3 w-3",onClick:d=>d.stopPropagation()})}),(0,a.jsxs)(Zt,{align:"end",onClick:d=>d.stopPropagation(),onCloseAutoFocus:d=>d.preventDefault(),children:[!g&&(0,a.jsxs)(X,{onSelect:()=>o({entry:t,namespace:r,protocol:s,backendType:n}),children:[(0,a.jsx)(kt,{className:"h-3.5 w-3.5 mr-2"}),"View"]}),(0,a.jsxs)(X,{onSelect:async()=>{await we(t.path),re({title:"Copied to clipboard"})},children:[(0,a.jsx)(st,{className:be}),"Copy path"]}),!g&&(0,a.jsxs)(X,{onSelect:()=>b(),children:[(0,a.jsx)(Pe,{className:"h-3.5 w-3.5 mr-2"}),"Download"]}),(0,a.jsx)(ue,{}),Ct.map(d=>{let v=d.getCode({variableName:r,protocol:s,entry:t,backendType:n});if(v===null)return null;let S=d.icon;return(0,a.jsxs)(X,{onSelect:()=>y(v),children:[(0,a.jsx)(S,{className:be}),d.label]},d.id)})]})]})]})]}),g&&c&&(0,a.jsx)(xr,{namespace:r,protocol:s,rootPath:l,backendType:n,prefix:Ae(t.path),depth:p+1,locale:i,searchValue:F?"":m,onOpenFile:o})]})},fr=t=>{let e=(0,Ie.c)(64),{namespace:r,locale:s,searchValue:l,remoteSearch:n,onContinueRemoteSearch:p,onOpenFile:i}=t,[m,o]=(0,$.useState)(!0),{entriesByPath:u,pageMetadataByPath:h}=_e(),{clearNamespaceCache:f}=ia(),y=r.name??r.displayName,{entries:g,isPending:k,error:x,hasMore:F,loadMore:j,isLoadingMore:c,loadMoreError:b,refetch:C}=at(y),d;e[0]!==f||e[1]!==y||e[2]!==C?(d=P=>{P.stopPropagation(),f(y),C()},e[0]=f,e[1]=y,e[2]=C,e[3]=d):d=e[3];let v=d,S=k?r.storageEntries:g,_;if(e[4]!==S||e[5]!==u||e[6]!==x||e[7]!==v||e[8]!==F||e[9]!==m||e[10]!==c||e[11]!==k||e[12]!==j||e[13]!==b||e[14]!==s||e[15]!==r.backendType||e[16]!==r.displayName||e[17]!==r.name||e[18]!==r.protocol||e[19]!==r.rootPath||e[20]!==y||e[21]!==p||e[22]!==i||e[23]!==h||e[24]!==n||e[25]!==l){let P=Ne(S,{namespace:y,searchValue:l,entriesByPath:u}),M=Ue(l),z=ye(y,M),A=M===""?[]:u.get(z)??[],T=Ne(A,{namespace:y,searchValue:l,entriesByPath:u}),G=!!l.trim(),ee=P.length>0||T.length>0,Q=M!==""&&pr({hasSearch:G,hasLoadedMatches:ee,isPending:k,remoteSearch:n,searchKey:z,entriesByPath:u,pageMetadataByPath:h}),J=G&&P.length===0,B;e:{if(k&&S.length===0){let w;e[27]===Symbol.for("react.memo_cache_sentinel")?(w=(0,a.jsxs)("span",{className:"flex items-center gap-1.5",children:[(0,a.jsx)(ve,{className:"h-3 w-3 animate-spin"}),"Loading..."]}),e[27]=w):w=e[27],B=w;break e}if(n.status==="searching"){let w;e[28]===Symbol.for("react.memo_cache_sentinel")?(w=(0,a.jsxs)("span",{className:"flex items-center gap-1.5",children:[(0,a.jsx)(ve,{className:"h-3 w-3 animate-spin"}),"Searching more entries..."]}),e[28]=w):w=e[28],B=w;break e}if(n.status==="error"){let w;e[29]===n.error.message?w=e[30]:(w=(0,a.jsxs)("span",{className:"text-destructive",children:["Search failed: ",n.error.message]}),e[29]=n.error.message,e[30]=w),B=w;break e}if(n.status==="capped"){let w;e[31]===p?w=e[32]:(w=(0,a.jsx)(H,{variant:"text",size:"xs",className:"h-5 px-0 text-xs hover:text-blue-600",onClick:p,children:"Continue searching"}),e[31]=p,e[32]=w);let D;e[33]===Symbol.for("react.memo_cache_sentinel")?(D=(0,a.jsx)("span",{className:"text-[10px]",children:"(or press Enter)"}),e[33]=D):D=e[33];let L;e[34]===w?L=e[35]:(L=(0,a.jsxs)("span",{className:"flex items-center gap-1.5",children:["Searched more entries.",w,D]}),e[34]=w,e[35]=L),B=L;break e}if(n.status==="exhausted"&&!ee){B="No matches";break e}if(!G&&!k&&S.length===0){B="No entries";break e}if(Q){let w;e[36]===p?w=e[37]:(w=(0,a.jsx)(H,{variant:"text",size:"xs",className:"h-5 px-0 text-xs hover:text-blue-600",onClick:p,children:"Search more entries"}),e[36]=p,e[37]=w);let D;e[38]===Symbol.for("react.memo_cache_sentinel")?(D=(0,a.jsx)("span",{className:"text-[10px]",children:"(or press Enter)"}),e[38]=D):D=e[38];let L;e[39]===w?L=e[40]:(L=(0,a.jsxs)("span",{className:"flex items-center gap-1.5",children:["No loaded matches.",w,D]}),e[39]=w,e[40]=L),B=L;break e}if(G&&!ee&&S.length>0){B="No matches";break e}B=null}let W=B,R;e[41]===m?R=e[42]:(R=()=>o(!m),e[41]=m,e[42]=R);let V;e[43]===m?V=e[44]:(V=(0,a.jsx)($e,{isExpanded:m,className:"h-3 w-3"}),e[43]=m,e[44]=V);let q;e[45]===r.protocol?q=e[46]:(q=(0,a.jsx)(ja,{protocol:r.protocol}),e[45]=r.protocol,e[46]=q);let I;e[47]===r.displayName?I=e[48]:(I=(0,a.jsx)("span",{children:r.displayName}),e[47]=r.displayName,e[48]=I);let E;e[49]===r.name?E=e[50]:(E=r.name&&(0,a.jsxs)("span",{className:"text-xs text-muted-foreground font-normal",children:["(",(0,a.jsx)(Ja,{variableName:r.name}),")"]}),e[49]=r.name,e[50]=E);let U;e[51]===v?U=e[52]:(U=(0,a.jsx)(nt,{onClick:v,tooltip:"Refresh storage connection",className:"p-0",iconClassName:"h-3 w-3"}),e[51]=v,e[52]=U);let Y=r.rootPath||"(root)",N;e[53]===Y?N=e[54]:(N=(0,a.jsx)("span",{className:"text-[10px] text-muted-foreground font-normal tabular-nums ml-auto",children:Y}),e[53]=Y,e[54]=N);let O;e[55]!==r.name||e[56]!==N||e[57]!==R||e[58]!==V||e[59]!==q||e[60]!==I||e[61]!==E||e[62]!==U?(O=(0,a.jsxs)(ut,{value:r.name,onSelect:R,className:"flex flex-row font-semibold h-7 text-xs gap-1.5 bg-(--slate-2) text-muted-foreground rounded-none",children:[V,q,I,E,U,N]}),e[55]=r.name,e[56]=N,e[57]=R,e[58]=V,e[59]=q,e[60]=I,e[61]=E,e[62]=U,e[63]=O):O=e[63],_=(0,a.jsxs)(a.Fragment,{children:[O,m&&(0,a.jsxs)(a.Fragment,{children:[x&&S.length===0&&(0,a.jsx)(ta,{error:x,style:le(1),className:"py-1 text-xs h-auto overflow-auto max-h-32 items-start",showIcon:!1}),!x&&W&&(0,a.jsx)("div",{className:"py-1 text-xs text-muted-foreground italic",style:le(1),children:W}),P.map(w=>{let D=He(w,S.indexOf(w));return(0,a.jsx)(Ke,{rowKey:D,entry:w,namespace:y,protocol:r.protocol,rootPath:r.rootPath,backendType:r.backendType,depth:1,locale:s,searchValue:l,onOpenFile:i},D)}),J&&T.map(w=>{let D=He(w,A.indexOf(w));return(0,a.jsx)(Ke,{rowKey:`remote-search:${D}`,entry:w,namespace:y,protocol:r.protocol,rootPath:r.rootPath,backendType:r.backendType,depth:1,locale:s,searchValue:l,onOpenFile:i},`remote-search:${D}`)}),F&&!Q&&(0,a.jsx)(Mt,{depth:1,isLoading:c,error:b,onLoadMore:j})]})]}),e[4]=S,e[5]=u,e[6]=x,e[7]=v,e[8]=F,e[9]=m,e[10]=c,e[11]=k,e[12]=j,e[13]=b,e[14]=s,e[15]=r.backendType,e[16]=r.displayName,e[17]=r.name,e[18]=r.protocol,e[19]=r.rootPath,e[20]=y,e[21]=p,e[22]=i,e[23]=h,e[24]=n,e[25]=l,e[26]=_}else _=e[26];return _};const ur=()=>{let{namespaces:t,entriesByPath:e,pageMetadataByPath:r}=_e(),{locale:s}=ht(),[l,n]=(0,$.useState)(""),[p,i]=(0,$.useState)({}),[m,o]=(0,$.useState)(null),u=la(),h=!!l.trim(),f=l.trim(),y=(0,$.useCallback)(j=>{let c=p[j];return(c==null?void 0:c.query)===f?c:mr(f)},[f,p]),g=(0,$.useCallback)((j,c)=>{i(b=>({...b,[j]:c}))},[]),k=(0,$.useCallback)(j=>{if(!f)return!1;let c=j.name??j.displayName,b=Ue(f);if(b===""||!Ft(y(c))||Ne(e.get(ye(c,""))??j.storageEntries,{namespace:c,searchValue:f,entriesByPath:e}).length>0)return!1;let C=ye(c,b);return Ne(e.get(C)??[],{namespace:c,searchValue:f,entriesByPath:e}).length>0?!1:_t(C,e,r)},[f,e,r,y]),x=(0,$.useCallback)(async j=>{var P;if(!k(j))return;let c=f,b=j.name??j.displayName,C=Ue(c),d=ye(b,C),v=e.get(d),S=((P=r.get(d))==null?void 0:P.nextPageToken)??null,_=v!==void 0;g(b,{query:c,status:"searching"});try{for(let M=0;M<dr;M++){let z=!_||S!==null,A=[];if(z){let T=await u({namespace:b,prefix:C,pageToken:S,append:_});A=T.entries,S=T.next_page_token??null,_=!0}if((z?A:v??[]).some(T=>hr(T,c))){g(b,{query:c,status:"found"});return}if(S===null){g(b,{query:c,status:"exhausted"});return}}g(b,{query:c,status:"capped"})}catch(M){g(b,{query:c,status:"error",error:M instanceof Error?M:Error(String(M))})}},[k,f,e,u,r,g]),F=(0,$.useCallback)(()=>{let j=t.filter(k);for(let c of j)x(c)},[k,x,t]);return t.length===0?(0,a.jsx)(Ga,{title:"No storage connected",description:(0,a.jsxs)("span",{children:["Create an obstore or fsspec connection in your notebook. See the"," ",(0,a.jsx)("a",{className:"text-link",href:"https://docs.marimo.io/guides/working_with_data/remote_storage/#quick-start",target:"_blank",rel:"noopener noreferrer",children:"docs"}),"."]}),action:(0,a.jsx)(dt,{defaultTab:"storage",children:(0,a.jsxs)(H,{variant:"outline",size:"sm",children:["Add remote storage",(0,a.jsx)(mt,{className:"h-4 w-4 ml-2"})]})}),icon:(0,a.jsx)(ct,{className:"h-8 w-8"})}):(0,a.jsxs)("div",{className:"h-full flex flex-col",children:[m&&(0,a.jsx)(lr,{entry:m.entry,namespace:m.namespace,protocol:m.protocol,backendType:m.backendType,onBack:()=>o(null)}),(0,a.jsxs)(Ha,{className:oe("border-b bg-background rounded-none h-full pb-10 overflow-auto outline-hidden scrollbar-thin",m&&"hidden"),shouldFilter:!1,children:[(0,a.jsxs)("div",{className:"flex items-center w-full border-b",children:[(0,a.jsx)(Ea,{placeholder:"Search entries...",className:"h-6 m-1",value:l,onValueChange:n,onKeyDown:j=>{j.key==="Enter"&&t.some(k)&&(j.preventDefault(),F())},rootClassName:"flex-1 border-b-0"}),h&&(0,a.jsx)(H,{variant:"text",size:"xs",className:"float-right border-none px-2 m-0 h-full",onClick:()=>n(""),children:(0,a.jsx)(ma,{className:"h-4 w-4"})}),(0,a.jsx)(Z,{content:"Search by file name within loaded entries, or by prefix (e.g. 'folder/x') for backend search. Press Enter to fetch more results.",delayDuration:200,children:(0,a.jsx)(fa,{className:"h-3.5 w-3.5 shrink-0 cursor-help text-muted-foreground hover:text-foreground mr-2"})}),(0,a.jsx)(dt,{defaultTab:"storage",children:(0,a.jsx)(H,{variant:"ghost",size:"sm",className:"px-2 border-0 border-l border-muted-background rounded-none focus-visible:ring-0 focus-visible:ring-offset-0",children:(0,a.jsx)(mt,{className:"h-4 w-4"})})})]}),(0,a.jsx)(Aa,{className:"flex flex-col",children:t.map(j=>{let c=j.name??j.displayName;return(0,a.jsx)(fr,{namespace:j,locale:s,searchValue:l,remoteSearch:y(c),onContinueRemoteSearch:()=>{x(j)},onOpenFile:o},c)})})]})]})};var Pt=fe(),Dt=(0,$.createContext)(null);function yr(){return(0,$.useContext)(Dt)??void 0}var gr=t=>{let e=(0,Pt.c)(3),{children:r}=t,s=Na(),l;return e[0]!==r||e[1]!==s?(l=(0,a.jsx)(Dt.Provider,{value:s,children:r}),e[0]=r,e[1]=s,e[2]=l):l=e[2],l};const jr=t=>{let e=(0,Pt.c)(5),{children:r}=t,[s,l]=(0,$.useState)(null),n;e[0]!==r||e[1]!==s?(n=s&&(0,a.jsx)(ka,{backend:Pa,options:{rootElement:s},children:(0,a.jsx)(gr,{children:r})}),e[0]=r,e[1]=s,e[2]=n):n=e[2];let p;return e[3]===n?p=e[4]:(p=(0,a.jsx)("div",{ref:l,className:"contents",children:n}),e[3]=n,e[4]=p),p};async function zt(t,e){if(!je()){ze(Wt().formatNavigableHttpURL("api/files/download",new URLSearchParams({path:t})).toString(),e);return}let r=await oa().sendFileDetails({path:t});r.isBase64&&r.contents?et(Ba(xa(r.contents,r.mimeType||"application/octet-stream")),e):et(new Blob([r.contents||""],{type:r.mimeType||"application/octet-stream"}),e)}var We=new Map;const br=({file:t,onOpenNotebook:e})=>{let{sendFileDetails:r,sendUpdateFile:s}=Te(),l=ge(Kt),n=ge(Ze),p=ge(qt),[i,m]=(0,$.useState)(""),{data:o,isPending:u,error:h,setData:f,refetch:y}=Be(async()=>{let d=await r({path:t.path}),v=d.contents||"";return m(We.get(t.path)||v),d},[t.path]),g=async()=>{i!==(o==null?void 0:o.contents)&&await s({path:t.path,contents:i}).then(d=>{d.success&&(f(v=>({...v,contents:i})),m(i))})},k=(0,$.useRef)(i);if(k.current=i,(0,$.useEffect)(()=>()=>{if(!(o!=null&&o.contents))return;let d=k.current;d===o.contents?We.delete(t.path):We.set(t.path,d)},[t.path,o==null?void 0:o.contents]),h)return(0,a.jsx)(ft,{error:h});if(u||!o)return null;let x=o.mimeType||"text/plain",F=x in ea,j=p&&o.file.isMarimoFile&&(t.path===p||t.path.endsWith(`/${p}`));if(!o.contents&&!F)return(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2 p-6",children:[(0,a.jsx)("div",{className:"font-bold text-muted-foreground",children:"Name"}),(0,a.jsx)("div",{children:o.file.name}),(0,a.jsx)("div",{className:"font-bold text-muted-foreground",children:"Type"}),(0,a.jsx)("div",{children:x})]});let c=(0,a.jsx)(St,{filename:o.file.name,onRefresh:y,onDownload:n?void 0:async()=>{await zt(t.path,o.file.name)},actions:(0,a.jsxs)(a.Fragment,{children:[t.isMarimoFile&&!je()&&(0,a.jsx)(Z,{content:"Open notebook",children:(0,a.jsx)(H,{variant:"text",size:"xs",onClick:d=>e(d),children:(0,a.jsx)(Le,{className:"h-3.5 w-3.5"})})}),!De(x)&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(Z,{content:"Copy contents to clipboard",children:(0,a.jsx)(H,{variant:"text",size:"xs",onClick:async()=>{await we(i)},children:(0,a.jsx)(st,{className:"h-3.5 w-3.5"})})}),(0,a.jsx)(Z,{content:qa("global.save"),children:(0,a.jsx)(H,{variant:"text",size:"xs",onClick:g,disabled:i===o.contents,children:(0,a.jsx)(Da,{className:"h-3.5 w-3.5"})})})]})]})}),b=De(x),C=!b&&x!=="text/csv";return(0,a.jsxs)(a.Fragment,{children:[c,C&&j&&(0,a.jsxs)(Va,{variant:"warning",className:"rounded-none",children:[(0,a.jsx)(za,{className:"h-4 w-4"}),(0,a.jsx)(Ra,{children:"Editing the notebook file directly while running in marimo's editor may cause unintended changes. Please use with caution."})]}),(0,a.jsx)(Qe,{mimeType:x,contents:b?void 0:C?i:o.contents??void 0,mediaSource:b?{base64:o.contents,mime:x}:void 0,readOnly:!C,onChange:m,extensions:[na.of([{key:l.getHotkey("global.save").key,stopPropagation:!0,run:()=>i===o.contents?!1:(g(),!0)}])]})]})},Tt=Je(t=>{let e=t(sa);return Ut(e,"no requestClientAtom set"),new wa({listFiles:e.sendListFiles,createFileOrFolder:e.sendCreateFileOrFolder,deleteFileOrFolder:e.sendDeleteFileOrFolder,copyFileOrFolder:e.sendCopyFileOrFolder,renameFileOrFolder:e.sendRenameFileOrFolder})}),vr=Je({});async function wr(){await It.get(Tt).refreshAll([])}var se=" ";const Ot={directory:t=>`os.listdir("${t}")`,python:t=>`with open("${t}", "r") as _f:
11
- ${se}...
12
- `,json:t=>`with open("${t}", "r") as _f:
13
- ${se}_data = json.load(_f)
14
- `,code:t=>`with open("${t}", "r") as _f:
15
- ${se}...
16
- `,text:t=>`with open("${t}", "r") as _f:
17
- ${se}...
18
- `,image:t=>`mo.image("${t}")`,audio:t=>`mo.audio("${t}")`,video:t=>`mo.video("${t}")`,pdf:t=>`with open("${t}", "rb") as _f:
19
- ${se}...
20
- `,zip:t=>`with open("${t}", "rb") as _f:
21
- ${se}...
22
- `,data:t=>`with open("${t}", "r") as _f:
23
- ${se}...
24
- `,unknown:t=>`with open("${t}", "r") as _f:
25
- ${se}...
26
- `};var Nr=fe(),kr=1024*1024*100,Sr=5;function $t(t){let e=(0,Nr.c)(7),r;e[0]===t?r=e[1]:(r=t===void 0?{}:t,e[0]=t,e[1]=r);let s=r,{sendCreateFileOrFolder:l}=Te(),n;e[2]===l?n=e[3]:(n=async i=>{if(i.length===0)return;let m=i.length===1;await aa(m?"Uploading file...":"Uploading files...",async o=>{o.addTotal(i.length),await Wa(i,Sr,async u=>{let h=Dr(Pr(u)),f="";h&&(f=$a.guessDeliminator(h).dirname(h)),await l({path:f,type:"file",name:u.name,file:u}),o.increment(1)}),await wr()},{title:m?"File uploaded":`${i.length} files uploaded`})},e[2]=l,e[3]=n);let p;return e[4]!==s||e[5]!==n?(p={multiple:!0,maxSize:kr,onError:Mr,onDropRejected:Cr,onDrop:n,...s},e[4]=s,e[5]=n,e[6]=p):p=e[6],Oa(p)}function Cr(t){re({title:"File upload failed",description:(0,a.jsx)("div",{className:"flex flex-col gap-1",children:t.map(Fr)}),variant:"danger"})}function Fr(t){return(0,a.jsxs)("div",{children:[t.file.name," (",t.errors.map(_r).join(", "),")"]},t.file.name)}function _r(t){return t.message}function Mr(t){Me.error(t),re({title:"File upload failed",description:t.message,variant:"danger"})}function Pr(t){if(t.webkitRelativePath)return t.webkitRelativePath;if("path"in t&&typeof t.path=="string")return t.path;if("relativePath"in t&&typeof t.relativePath=="string")return t.relativePath}function Dr(t){if(t)return t.replace(/^\/+/,"")}var ke=fe(),zr=Ye("marimo:showHiddenFiles",!0,Xe,{getOnInit:!0}),Lt=$.createContext(null);const Tr=t=>{let e=(0,ke.c)(73),{height:r}=t,s=(0,$.useRef)(null),l=yr(),[n]=Fe(Tt),p;e[0]===Symbol.for("react.memo_cache_sentinel")?(p=[],e[0]=p):p=e[0];let[i,m]=(0,$.useState)(p),[o,u]=(0,$.useState)(null),[h,f]=Fe(zr),{openPrompt:y}=xt(),[g,k]=Fe(vr),x;e[1]===n?x=e[2]:(x=()=>n.initialize(m),e[1]=n,e[2]=x);let F;e[3]===Symbol.for("react.memo_cache_sentinel")?(F=[],e[3]=F):F=e[3];let{isPending:j,error:c}=Be(x,F),b;e[4]!==g||e[5]!==n?(b=()=>n.refreshAll(Object.keys(g).filter(N=>g[N])),e[4]=g,e[5]=n,e[6]=b):b=e[6];let C=ae(b),d;e[7]!==f||e[8]!==h?(d=()=>{f(!h)},e[7]=f,e[8]=h,e[9]=d):d=e[9];let v=ae(d),S;e[10]!==y||e[11]!==n?(S=async()=>{y({title:"Folder name",onConfirm:async N=>{n.createFolder(N,null)}})},e[10]=y,e[11]=n,e[12]=S):S=e[12];let _=ae(S),P;e[13]!==y||e[14]!==n?(P=async()=>{y({title:"File name",onConfirm:async N=>{n.createFile({name:N,parentId:null})}})},e[13]=y,e[14]=n,e[15]=P):P=e[15];let M=ae(P),z;e[16]!==y||e[17]!==n?(z=async()=>{y({title:"Notebook name",onConfirm:async N=>{n.createFile({name:N,parentId:null,type:"notebook"})}})},e[16]=y,e[17]=n,e[18]=z):z=e[18];let A=ae(z),T;e[19]===k?T=e[20]:(T=()=>{var N;(N=s.current)==null||N.closeAll(),k({})},e[19]=k,e[20]=T);let G=ae(T),ee;e[21]!==i||e[22]!==h?(ee=Rt(i,h),e[21]=i,e[22]=h,e[23]=ee):ee=e[23];let Q=ee;if(j){let N;return e[24]===Symbol.for("react.memo_cache_sentinel")?(N=(0,a.jsx)(ba,{size:"medium",centered:!0}),e[24]=N):N=e[24],N}if(c){let N;return e[25]===c?N=e[26]:(N=(0,a.jsx)(ft,{error:c}),e[25]=c,e[26]=N),N}if(o){let N;e[27]===Symbol.for("react.memo_cache_sentinel")?(N=()=>u(null),e[27]=N):N=e[27];let O;e[28]===Symbol.for("react.memo_cache_sentinel")?(O=(0,a.jsx)(H,{onClick:N,"data-testid":"file-explorer-back-button",variant:"text",size:"xs",className:"mb-0",children:(0,a.jsx)(rt,{size:16})}),e[28]=O):O=e[28];let w;e[29]===o.name?w=e[30]:(w=(0,a.jsxs)("div",{className:"flex items-center pl-1 pr-3 shrink-0 border-b justify-between",children:[O,(0,a.jsx)("span",{className:"font-bold",children:o.name})]}),e[29]=o.name,e[30]=w);let D;e[31]!==o.path||e[32]!==n?(D=ie=>Bt(ie,n.relativeFromRoot(o.path)),e[31]=o.path,e[32]=n,e[33]=D):D=e[33];let L;e[34]!==o||e[35]!==D?(L=(0,a.jsx)($.Suspense,{children:(0,a.jsx)(br,{onOpenNotebook:D,file:o})}),e[34]=o,e[35]=D,e[36]=L):L=e[36];let te;return e[37]!==w||e[38]!==L?(te=(0,a.jsxs)(a.Fragment,{children:[w,L]}),e[37]=w,e[38]=L,e[39]=te):te=e[39],te}let J;e[40]!==G||e[41]!==M||e[42]!==_||e[43]!==A||e[44]!==v||e[45]!==C||e[46]!==h||e[47]!==n?(J=(0,a.jsx)($r,{onRefresh:C,onHidden:v,showHiddenFiles:h,onCreateFile:M,onCreateNotebook:A,onCreateFolder:_,onCollapseAll:G,tree:n}),e[40]=G,e[41]=M,e[42]=_,e[43]=A,e[44]=v,e[45]=C,e[46]=h,e[47]=n,e[48]=J):J=e[48];let B=r-33,W,R,V;e[49]===n?(W=e[50],R=e[51],V=e[52]):(W=async N=>{let{ids:O}=N;for(let w of O)await n.delete(w)},R=async N=>{let{id:O,name:w}=N;await n.rename(O,w)},V=async N=>{let{dragIds:O,parentId:w}=N;await n.move(O,w)},e[49]=n,e[50]=W,e[51]=R,e[52]=V);let q;e[53]===Symbol.for("react.memo_cache_sentinel")?(q=N=>{let O=N[0];O&&(O.data.isDirectory||u(O.data))},e[53]=q):q=e[53];let I;e[54]!==g||e[55]!==k||e[56]!==n?(I=async N=>{if(await n.expand(N)){let O=g[N]??!1;k({...g,[N]:!O})}},e[54]=g,e[55]=k,e[56]=n,e[57]=I):I=e[57];let E;e[58]!==l||e[59]!==g||e[60]!==B||e[61]!==W||e[62]!==R||e[63]!==V||e[64]!==I||e[65]!==Q?(E=(0,a.jsx)(Ca,{width:"100%",ref:s,height:B,className:"h-full",data:Q,initialOpenState:g,openByDefault:!1,dndManager:l,renderCursor:Ir,disableDrop:Er,onDelete:W,onRename:R,onMove:V,onSelect:q,onToggle:I,padding:15,rowHeight:30,indent:Or,overscanCount:1e3,disableMultiSelection:!0,children:Br}),e[58]=l,e[59]=g,e[60]=B,e[61]=W,e[62]=R,e[63]=V,e[64]=I,e[65]=Q,e[66]=E):E=e[66];let U;e[67]!==E||e[68]!==n?(U=(0,a.jsx)(Lt,{value:n,children:E}),e[67]=E,e[68]=n,e[69]=U):U=e[69];let Y;return e[70]!==J||e[71]!==U?(Y=(0,a.jsxs)(a.Fragment,{children:[J,U]}),e[70]=J,e[71]=U,e[72]=Y):Y=e[72],Y};var Or=15,$r=t=>{let e=(0,ke.c)(37),{onRefresh:r,onHidden:s,showHiddenFiles:l,onCreateFile:n,onCreateNotebook:p,onCreateFolder:i,onCollapseAll:m}=t,o;e[0]===Symbol.for("react.memo_cache_sentinel")?(o={noDrag:!0,noDragEventsBubbling:!0},e[0]=o):o=e[0];let{getRootProps:u,getInputProps:h}=$t(o),f;e[1]===Symbol.for("react.memo_cache_sentinel")?(f=(0,a.jsx)(bt,{size:16}),e[1]=f):f=e[1];let y;e[2]===p?y=e[3]:(y=(0,a.jsx)(Z,{content:"Add notebook",children:(0,a.jsx)(H,{"data-testid":"file-explorer-add-notebook-button",onClick:p,variant:"text",size:"xs",children:f})}),e[2]=p,e[3]=y);let g;e[4]===Symbol.for("react.memo_cache_sentinel")?(g=(0,a.jsx)(vt,{size:16}),e[4]=g):g=e[4];let k;e[5]===n?k=e[6]:(k=(0,a.jsx)(Z,{content:"Add file",children:(0,a.jsx)(H,{"data-testid":"file-explorer-add-file-button",onClick:n,variant:"text",size:"xs",children:g})}),e[5]=n,e[6]=k);let x;e[7]===Symbol.for("react.memo_cache_sentinel")?(x=(0,a.jsx)(wt,{size:16}),e[7]=x):x=e[7];let F;e[8]===i?F=e[9]:(F=(0,a.jsx)(Z,{content:"Add folder",children:(0,a.jsx)(H,{"data-testid":"file-explorer-add-folder-button",onClick:i,variant:"text",size:"xs",children:x})}),e[8]=i,e[9]=F);let j;e[10]===u?j=e[11]:(j=u({}),e[10]=u,e[11]=j);let c,b;e[12]===Symbol.for("react.memo_cache_sentinel")?(b=ra({variant:"text",size:"xs"}),c=(0,a.jsx)(Ta,{size:16}),e[12]=c,e[13]=b):(c=e[12],b=e[13]);let C;e[14]===j?C=e[15]:(C=(0,a.jsx)(Z,{content:"Upload file",children:(0,a.jsx)("button",{"data-testid":"file-explorer-upload-button",...j,className:b,children:c})}),e[14]=j,e[15]=C);let d;e[16]===h?d=e[17]:(d=h({}),e[16]=h,e[17]=d);let v;e[18]===d?v=e[19]:(v=(0,a.jsx)("input",{...d,type:"file"}),e[18]=d,e[19]=v);let S;e[20]===r?S=e[21]:(S=(0,a.jsx)(nt,{"data-testid":"file-explorer-refresh-button",onClick:r}),e[20]=r,e[21]=S);let _;e[22]!==s||e[23]!==l?(_=(0,a.jsx)(pa,{"data-testid":"file-explorer-hidden-files-button",isVisible:l,onToggle:s,showTooltip:"Show hidden files",hideTooltip:"Hide hidden files"}),e[22]=s,e[23]=l,e[24]=_):_=e[24];let P;e[25]===Symbol.for("react.memo_cache_sentinel")?(P=(0,a.jsx)(er,{size:16}),e[25]=P):P=e[25];let M;e[26]===m?M=e[27]:(M=(0,a.jsx)(Z,{content:"Collapse all folders",children:(0,a.jsx)(H,{"data-testid":"file-explorer-collapse-button",onClick:m,variant:"text",size:"xs",children:P})}),e[26]=m,e[27]=M);let z;return e[28]!==C||e[29]!==v||e[30]!==S||e[31]!==_||e[32]!==M||e[33]!==y||e[34]!==k||e[35]!==F?(z=(0,a.jsxs)("div",{className:"flex items-center justify-end px-2 shrink-0 border-b",children:[y,k,F,C,v,S,_,M]}),e[28]=C,e[29]=v,e[30]=S,e[31]=_,e[32]=M,e[33]=y,e[34]=k,e[35]=F,e[36]=z):z=e[36],z},Lr=t=>{let e=(0,ke.c)(9),{node:r,onOpenMarimoFile:s}=t,l;e[0]===r?l=e[1]:(l=i=>{r.data.isDirectory||(i.stopPropagation(),r.select())},e[0]=r,e[1]=l);let n;e[2]!==r.data.isMarimoFile||e[3]!==s?(n=r.data.isMarimoFile&&!je()&&(0,a.jsxs)("span",{"data-testid":"file-explorer-open-marimo-button",className:"shrink-0 ml-2 text-sm hidden group-hover:inline hover:underline",onClick:s,children:["open ",(0,a.jsx)(Le,{className:"inline ml-1",size:12})]}),e[2]=r.data.isMarimoFile,e[3]=s,e[4]=n):n=e[4];let p;return e[5]!==r.data.name||e[6]!==l||e[7]!==n?(p=(0,a.jsxs)("span",{className:"flex-1 overflow-hidden text-ellipsis",onClick:l,children:[r.data.name,n]}),e[5]=r.data.name,e[6]=l,e[7]=n,e[8]=p):p=e[8],p},Br=t=>{let e=(0,ke.c)(115),{node:r,style:s,dragHandle:l}=t,{openFile:n}=Te(),p=ge(Ze),i;e[0]!==r.data.isDirectory||e[1]!==r.data.name?(i=r.data.isDirectory?"directory":ya(r.data.name),e[0]=r.data.isDirectory,e[1]=r.data.name,e[2]=i):i=e[2];let m=i,o=ga[m],{openConfirm:u,openPrompt:h}=xt(),{createNewCell:f}=Ht(),y=Ia(),g;e[3]!==f||e[4]!==y?(g=K=>{f({code:K,before:!1,cellId:y??"__end__"})},e[3]=f,e[4]=y,e[5]=g):g=e[5];let k=g,x=(0,$.use)(Lt),F;e[6]!==r.data.path||e[7]!==x?(F=async K=>{Bt(K,x?x.relativeFromRoot(r.data.path):r.data.path)},e[6]=r.data.path,e[7]=x,e[8]=F):F=e[8];let j=F,c;e[9]!==r.data.name||e[10]!==r.id||e[11]!==r.tree||e[12]!==u?(c=async K=>{K.stopPropagation(),K.preventDefault(),u({title:"Delete file",description:`Are you sure you want to delete ${r.data.name}?`,confirmAction:(0,a.jsx)(Yt,{onClick:async()=>{await r.tree.delete(r.id)},"aria-label":"Confirm",children:"Delete"})})},e[9]=r.data.name,e[10]=r.id,e[11]=r.tree,e[12]=u,e[13]=c):c=e[13];let b=c,C;e[14]!==r||e[15]!==h||e[16]!==x?(C=async()=>{r.open(),h({title:"Folder name",onConfirm:async K=>{x==null||x.createFolder(K,r.id)}})},e[14]=r,e[15]=h,e[16]=x,e[17]=C):C=e[17];let d=ae(C),v;e[18]!==r||e[19]!==h||e[20]!==x?(v=async()=>{r.open(),h({title:"File name",onConfirm:async K=>{x==null||x.createFile({name:K,parentId:r.id})}})},e[18]=r,e[19]=h,e[20]=x,e[21]=v):v=e[21];let S=ae(v),_;e[22]!==r||e[23]!==h||e[24]!==x?(_=async()=>{r.open(),h({title:"Notebook name",onConfirm:async K=>{x==null||x.createFile({name:K,parentId:r.id,type:"notebook"})}})},e[22]=r,e[23]=h,e[24]=x,e[25]=_):_=e[25];let P=ae(_),M;e[26]!==r.data.name||e[27]!==r.id||e[28]!==x?(M=async()=>{x&&await x.copy(r.id,Ka(r.data.name))},e[26]=r.data.name,e[27]=r.id,e[28]=x,e[29]=M):M=e[29];let z=ae(M),A;e[30]===Symbol.for("react.memo_cache_sentinel")?(A=oe("flex items-center cursor-pointer ml-1 text-muted-foreground whitespace-nowrap group"),e[30]=A):A=e[30];let T,G;e[31]===r?(T=e[32],G=e[33]):(T=K=>{K.stopPropagation(),r.data.isDirectory&&r.toggle()},G=(0,a.jsx)(Rr,{node:r}),e[31]=r,e[32]=T,e[33]=G);let ee=r.willReceiveDrop&&r.data.isDirectory&&"bg-accent/80 hover:bg-accent/80 text-accent-foreground",Q;e[34]===ee?Q=e[35]:(Q=oe("flex items-center pl-1 py-1 cursor-pointer hover:bg-accent/50 hover:text-accent-foreground rounded-l flex-1 overflow-hidden group",ee),e[34]=ee,e[35]=Q);let J;e[36]!==o||e[37]!==m||e[38]!==r.data.isMarimoFile?(J=r.data.isMarimoFile?(0,a.jsx)(Xa,{className:"w-5 h-5 shrink-0 mr-2",strokeWidth:1.5}):(0,a.jsx)(o,{className:oe("w-5 h-5 shrink-0 mr-2",lt[m]),strokeWidth:1.5}),e[36]=o,e[37]=m,e[38]=r.data.isMarimoFile,e[39]=J):J=e[39];let B;e[40]!==j||e[41]!==r?(B=r.isEditing?(0,a.jsx)(Ma,{node:r}):(0,a.jsx)(Lr,{node:r,onOpenMarimoFile:j}),e[40]=j,e[41]=r,e[42]=B):B=e[42];let W;e[43]===r?W=e[44]:(W=!r.data.isDirectory&&(0,a.jsxs)(X,{onSelect:()=>r.select(),"data-testid":"file-explorer-open-file-menu-item",children:[(0,a.jsx)(kt,{className:"h-3.5 w-3.5 mr-2"}),"Open file"]}),e[43]=r,e[44]=W);let R;e[45]!==r.data.isDirectory||e[46]!==r.data.path||e[47]!==n?(R=!r.data.isDirectory&&!je()&&(0,a.jsxs)(X,{onSelect:()=>{n({path:r.data.path})},"data-testid":"file-explorer-open-external-menu-item",children:[(0,a.jsx)(Le,{className:"h-3.5 w-3.5 mr-2"}),"Open file in external editor"]}),e[45]=r.data.isDirectory,e[46]=r.data.path,e[47]=n,e[48]=R):R=e[48];let V;e[49]!==S||e[50]!==d||e[51]!==P||e[52]!==r.data.isDirectory?(V=r.data.isDirectory&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(X,{onSelect:()=>P(),"data-testid":"file-explorer-create-notebook-menu-item",children:[(0,a.jsx)(bt,{className:"h-3.5 w-3.5 mr-2"}),"Create notebook"]}),(0,a.jsxs)(X,{onSelect:()=>S(),"data-testid":"file-explorer-create-file-menu-item",children:[(0,a.jsx)(vt,{className:"h-3.5 w-3.5 mr-2"}),"Create file"]}),(0,a.jsxs)(X,{onSelect:()=>d(),"data-testid":"file-explorer-create-folder-menu-item",children:[(0,a.jsx)(wt,{className:"h-3.5 w-3.5 mr-2"}),"Create folder"]}),(0,a.jsx)(ue,{})]}),e[49]=S,e[50]=d,e[51]=P,e[52]=r.data.isDirectory,e[53]=V):V=e[53];let q;e[54]===r?q=e[55]:(q=(0,a.jsx)(va,{onSelect:()=>r.edit(),testId:"file-explorer-rename-menu-item"}),e[54]=r,e[55]=q);let I;e[56]===z?I=e[57]:(I=(0,a.jsx)(_a,{onSelect:z,testId:"file-explorer-duplicate-menu-item"}),e[56]=z,e[57]=I);let E;e[58]===r.data.path?E=e[59]:(E=async()=>{await we(r.data.path),re({title:"Copied to clipboard"})},e[58]=r.data.path,e[59]=E);let U;e[60]===Symbol.for("react.memo_cache_sentinel")?(U=(0,a.jsx)(Nt,{className:be}),e[60]=U):U=e[60];let Y;e[61]===E?Y=e[62]:(Y=(0,a.jsxs)(X,{onSelect:E,"data-testid":"file-explorer-copy-path-menu-item",children:[U,"Copy path"]}),e[61]=E,e[62]=Y);let N;e[63]!==r.data.path||e[64]!==x?(N=x&&(0,a.jsxs)(X,{onSelect:async()=>{await we(x.relativeFromRoot(r.data.path)),re({title:"Copied to clipboard"})},"data-testid":"file-explorer-copy-relative-path-menu-item",children:[(0,a.jsx)(Nt,{className:"h-3.5 w-3.5 mr-2"}),"Copy relative path"]}),e[63]=r.data.path,e[64]=x,e[65]=N):N=e[65];let O;e[66]===Symbol.for("react.memo_cache_sentinel")?(O=(0,a.jsx)(ue,{}),e[66]=O):O=e[66];let w;e[67]!==m||e[68]!==k||e[69]!==r.data?(w=()=>{let{path:K}=r.data;k(Ot[m](K))},e[67]=m,e[68]=k,e[69]=r.data,e[70]=w):w=e[70];let D;e[71]===Symbol.for("react.memo_cache_sentinel")?(D=(0,a.jsx)(da,{className:be}),e[71]=D):D=e[71];let L;e[72]===w?L=e[73]:(L=(0,a.jsxs)(X,{onSelect:w,"data-testid":"file-explorer-insert-snippet-menu-item",children:[D,"Insert snippet for reading file"]}),e[72]=w,e[73]=L);let te;e[74]!==m||e[75]!==r.data?(te=async()=>{re({title:"Copied to clipboard",description:"Code to open the file has been copied to your clipboard. You can also drag and drop this file into the editor"});let{path:K}=r.data;await we(Ot[m](K))},e[74]=m,e[75]=r.data,e[76]=te):te=e[76];let ie;e[77]===Symbol.for("react.memo_cache_sentinel")?(ie=(0,a.jsx)(At,{className:be}),e[77]=ie):ie=e[77];let ce;e[78]===te?ce=e[79]:(ce=(0,a.jsxs)(X,{onSelect:te,"data-testid":"file-explorer-copy-snippet-menu-item",children:[ie,"Copy snippet for reading file"]}),e[78]=te,e[79]=ce);let de;e[80]!==j||e[81]!==r.data.isMarimoFile?(de=r.data.isMarimoFile&&!je()&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(ue,{}),(0,a.jsxs)(X,{onSelect:j,"data-testid":"file-explorer-open-notebook-menu-item",children:[(0,a.jsx)(ar,{className:"h-3.5 w-3.5 mr-2"}),"Open notebook"]})]}),e[80]=j,e[81]=r.data.isMarimoFile,e[82]=de):de=e[82];let Se;e[83]===Symbol.for("react.memo_cache_sentinel")?(Se=(0,a.jsx)(ue,{}),e[83]=Se):Se=e[83];let me;e[84]!==p||e[85]!==r.data.isDirectory||e[86]!==r.data.name||e[87]!==r.data.path?(me=!r.data.isDirectory&&!p&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(X,{onSelect:async()=>{await zt(r.data.path,r.data.name)},"data-testid":"file-explorer-download-menu-item",children:[(0,a.jsx)(Pe,{className:"h-3.5 w-3.5 mr-2"}),"Download"]}),(0,a.jsx)(ue,{})]}),e[84]=p,e[85]=r.data.isDirectory,e[86]=r.data.name,e[87]=r.data.path,e[88]=me):me=e[88];let pe;e[89]===b?pe=e[90]:(pe=(0,a.jsx)(Fa,{onSelect:b,testId:"file-explorer-delete-menu-item"}),e[89]=b,e[90]=pe);let he;e[91]!==W||e[92]!==R||e[93]!==V||e[94]!==q||e[95]!==I||e[96]!==Y||e[97]!==N||e[98]!==L||e[99]!==ce||e[100]!==de||e[101]!==me||e[102]!==pe?(he=(0,a.jsxs)(Sa,{testId:"file-explorer-more-button",iconClassName:"w-5 h-5",children:[W,R,V,q,I,Y,N,O,L,ce,de,Se,me,pe]}),e[91]=W,e[92]=R,e[93]=V,e[94]=q,e[95]=I,e[96]=Y,e[97]=N,e[98]=L,e[99]=ce,e[100]=de,e[101]=me,e[102]=pe,e[103]=he):he=e[103];let xe;e[104]!==Q||e[105]!==J||e[106]!==B||e[107]!==he?(xe=(0,a.jsxs)("span",{className:Q,children:[J,B,he]}),e[104]=Q,e[105]=J,e[106]=B,e[107]=he,e[108]=xe):xe=e[108];let Ce;return e[109]!==l||e[110]!==s||e[111]!==T||e[112]!==G||e[113]!==xe?(Ce=(0,a.jsxs)("div",{style:s,ref:l,className:A,draggable:!0,onClick:T,children:[G,xe]}),e[109]=l,e[110]=s,e[111]=T,e[112]=G,e[113]=xe,e[114]=Ce):Ce=e[114],Ce},Rr=t=>{let e=(0,ke.c)(3),{node:r}=t;if(!r.data.isDirectory){let l;return e[0]===Symbol.for("react.memo_cache_sentinel")?(l=(0,a.jsx)("span",{className:"w-4 h-4 shrink-0"}),e[0]=l):l=e[0],l}let s;return e[1]===r.isOpen?s=e[2]:(s=(0,a.jsx)($e,{isExpanded:r.isOpen,className:"w-4 h-4"}),e[1]=r.isOpen,e[2]=s),s};function Bt(t,e){t.stopPropagation(),t.preventDefault(),Za(e)}function Rt(t,e){if(e)return t;let r=[];for(let s of t){if(Vr(s.name))continue;let l=s;if(s.children){let n=Rt(s.children,e);n!==s.children&&(l={...s,children:n})}r.push(l)}return r}function Vr(t){return!!t.startsWith(".")}function Ir(){return null}function Er(t){let{parentNode:e}=t;return!e.data.isDirectory}var Vt=fe(),Ar=Ye("marimo:file-explorer-panel:state",{openSections:["files"],hasUserInteracted:!1},Xe),Hr=t=>{let e=(0,Vt.c)(20),{height:r}=t,s;e[0]===Symbol.for("react.memo_cache_sentinel")?(s={noClick:!0,noKeyboard:!0},e[0]=s):s=e[0];let{getRootProps:l,getInputProps:n,isDragActive:p}=$t(s),i;e[1]===l?i=e[2]:(i=l(),e[1]=l,e[2]=i);let m;e[3]===Symbol.for("react.memo_cache_sentinel")?(m=oe("flex flex-col overflow-hidden relative"),e[3]=m):m=e[3];let o;e[4]===r?o=e[5]:(o={height:r},e[4]=r,e[5]=o);let u;e[6]===n?u=e[7]:(u=n(),e[6]=n,e[7]=u);let h;e[8]===u?h=e[9]:(h=(0,a.jsx)("input",{...u}),e[8]=u,e[9]=h);let f;e[10]===p?f=e[11]:(f=p&&(0,a.jsx)("div",{className:"absolute inset-0 flex items-center uppercase justify-center text-xl font-bold text-primary/90 bg-accent/85 z-10 border-2 border-dashed border-primary/90 rounded-lg pointer-events-none",children:"Drop files here"}),e[10]=p,e[11]=f);let y;e[12]===r?y=e[13]:(y=(0,a.jsx)(Tr,{height:r}),e[12]=r,e[13]=y);let g;return e[14]!==i||e[15]!==o||e[16]!==h||e[17]!==f||e[18]!==y?(g=(0,a.jsx)(jr,{children:(0,a.jsxs)("div",{...i,className:m,style:o,children:[h,f,y]})}),e[14]=i,e[15]=o,e[16]=h,e[17]=f,e[18]=y,e[19]=g):g=e[19],g},qr=33,Ur=()=>{let t=(0,Vt.c)(36),{ref:e,height:r}=Ua(),s=r===void 0?500:r,[l,n]=Fe(Ar),p=ge(ca).length,i;e:{if(!l.hasUserInteracted&&p>0){if(l.openSections.includes("remote-storage")){i=l.openSections;break e}let T;t[0]===l.openSections?T=t[1]:(T=[...l.openSections,"remote-storage"],t[0]=l.openSections,t[1]=T),i=T;break e}i=l.openSections}let m=i,o;t[2]===n?o=t[3]:(o=T=>{n({openSections:T,hasUserInteracted:!0})},t[2]=n,t[3]=o);let u=o,h=s-qr*2,f;t[4]===m?f=t[5]:(f=m.includes("remote-storage"),t[4]=m,t[5]=f);let y=f,g;t[6]!==m||t[7]!==y?(g=y&&m.includes("files"),t[6]=m,t[7]=y,t[8]=g):g=t[8];let k=g,x;t[9]!==h||t[10]!==k?(x=k?Math.round(h*.4):h,t[9]=h,t[10]=k,t[11]=x):x=t[11];let F=x,j=Math.max(200,k?h-F:h),c;t[12]===Symbol.for("react.memo_cache_sentinel")?(c=(0,a.jsx)(ct,{className:"w-4 h-4"}),t[12]=c):c=t[12];let b;t[13]===p?b=t[14]:(b=p>0&&(0,a.jsx)(Ya,{children:p}),t[13]=p,t[14]=b);let C;t[15]===b?C=t[16]:(C=(0,a.jsxs)(gt,{children:[c," Remote storage",b]}),t[15]=b,t[16]=C);let d;t[17]===F?d=t[18]:(d={maxHeight:F},t[17]=F,t[18]=d);let v;t[19]===Symbol.for("react.memo_cache_sentinel")?(v=(0,a.jsx)(ur,{}),t[19]=v):v=t[19];let S;t[20]===d?S=t[21]:(S=(0,a.jsx)(jt,{className:"overflow-auto",style:d,children:v}),t[20]=d,t[21]=S);let _;t[22]!==S||t[23]!==C?(_=(0,a.jsxs)(yt,{value:"remote-storage",children:[C,S]}),t[22]=S,t[23]=C,t[24]=_):_=t[24];let P;t[25]===Symbol.for("react.memo_cache_sentinel")?(P=(0,a.jsxs)(gt,{children:[(0,a.jsx)(it,{className:"w-4 h-4"}),"Files"]}),t[25]=P):P=t[25];let M;t[26]===j?M=t[27]:(M=(0,a.jsxs)(yt,{value:"files",children:[P,(0,a.jsx)(jt,{children:(0,a.jsx)(Hr,{height:j})})]}),t[26]=j,t[27]=M);let z;t[28]!==u||t[29]!==m||t[30]!==_||t[31]!==M?(z=(0,a.jsxs)(Jt,{type:"multiple",value:m,onValueChange:u,children:[_,M]}),t[28]=u,t[29]=m,t[30]=_,t[31]=M,t[32]=z):z=t[32];let A;return t[33]!==e||t[34]!==z?(A=(0,a.jsx)("div",{ref:e,className:"h-full overflow-auto",children:z}),t[33]=e,t[34]=z,t[35]=A):A=t[35],A};export{Ur as default};