@harryy/react-file-browser 1.2.0 → 1.4.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode"],"sources":["../src/core/use-file-browser.ts","../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.mjs","../node_modules/lucide-react/dist/esm/defaultAttributes.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs","../node_modules/lucide-react/dist/esm/context.mjs","../node_modules/lucide-react/dist/esm/Icon.mjs","../node_modules/lucide-react/dist/esm/createLucideIcon.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-down.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-left.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-right.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-up.mjs","../node_modules/lucide-react/dist/esm/icons/copy.mjs","../node_modules/lucide-react/dist/esm/icons/download.mjs","../node_modules/lucide-react/dist/esm/icons/ellipsis.mjs","../node_modules/lucide-react/dist/esm/icons/file.mjs","../node_modules/lucide-react/dist/esm/icons/folder-input.mjs","../node_modules/lucide-react/dist/esm/icons/folder.mjs","../node_modules/lucide-react/dist/esm/icons/grid-2x2.mjs","../node_modules/lucide-react/dist/esm/icons/info.mjs","../node_modules/lucide-react/dist/esm/icons/list.mjs","../node_modules/lucide-react/dist/esm/icons/pause.mjs","../node_modules/lucide-react/dist/esm/icons/pencil.mjs","../node_modules/lucide-react/dist/esm/icons/play.mjs","../node_modules/lucide-react/dist/esm/icons/scissors.mjs","../node_modules/lucide-react/dist/esm/icons/search.mjs","../node_modules/lucide-react/dist/esm/icons/square-check-big.mjs","../node_modules/lucide-react/dist/esm/icons/square.mjs","../node_modules/lucide-react/dist/esm/icons/trash-2.mjs","../node_modules/lucide-react/dist/esm/icons/upload.mjs","../node_modules/lucide-react/dist/esm/icons/x.mjs","../src/core/upload-drop.ts","../src/transfers/transfer-manager.ts","../src/components/responsive.tsx","../src/transfers/file-browser-provider.tsx","../src/components/file-browser.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { Dispatch, SetStateAction } from 'react'\nimport { FileBrowserAdapterError, FileBrowserBulkActionError } from './types'\nimport type { FileBrowserAdapter, FileNode } from './types'\nimport { joinFileBrowserPath, normalizeFileBrowserPath } from './path'\n\nexport type FileBrowserStatus = 'idle' | 'loading' | 'ready' | 'error'\nexport type FileBrowserView = 'grid' | 'list'\nexport type FileBrowserKindFilter = 'all' | 'files' | 'folders'\nexport type FileBrowserUploadConflictResolution = 'replace' | 'keep-both' | 'skip'\nexport type FileBrowserUploadFilesOptions = {\n\tonConflict?: FileBrowserUploadConflictResolution\n}\nexport type FileBrowserClipboard = { type: 'copy'; paths: string[] } | { type: 'cut'; paths: string[] } | null\n\nexport type FileBrowserCapabilities = {\n\tcreateFolder: boolean\n\trename: boolean\n\tmove: boolean\n\tcopy: boolean\n\tstat: boolean\n\texists: boolean\n\tmultipart: boolean\n\tbulkDownload: boolean\n}\n\nexport type FileBrowserPathChangeContext<TMetadata = unknown> =\n\t| {\n\t\t\tsource: 'item'\n\t\t\titem: FileNode<TMetadata>\n\t }\n\t| {\n\t\t\tsource: 'breadcrumb' | 'programmatic'\n\t\t\titem?: FileNode<TMetadata>\n\t }\n\nexport type UseFileBrowserOptions<TMetadata = unknown> = {\n\tadapter: FileBrowserAdapter<TMetadata>\n\tpath?: string\n\tinitialPath?: string\n\tonPathChange?: (path: string, context: FileBrowserPathChangeContext<TMetadata>) => void\n\tsearchQuery?: string\n\tinitialSearchQuery?: string\n\tonSearchQueryChange?: (query: string) => void\n}\n\nexport type UseFileBrowserResult<TMetadata = unknown> = {\n\tadapter: FileBrowserAdapter<TMetadata>\n\tcapabilities: FileBrowserCapabilities\n\tcurrentPath: string\n\tstatus: FileBrowserStatus\n\titems: FileNode<TMetadata>[]\n\terror: Error | null\n\thasMore: boolean\n\tselectedPaths: string[]\n\tselectedItems: FileNode<TMetadata>[]\n\tfocusedPath: string | null\n\tclipboard: FileBrowserClipboard\n\tview: FileBrowserView\n\tsearchQuery: string\n\tfilterKind: FileBrowserKindFilter\n\tsortBy: 'name' | 'modifiedAt' | 'size'\n\tsortDirection: 'asc' | 'desc'\n\tfilteredItems: FileNode<TMetadata>[]\n\tsetView: Dispatch<SetStateAction<FileBrowserView>>\n\tsetSearchQuery: Dispatch<SetStateAction<string>>\n\tsetFilterKind: Dispatch<SetStateAction<FileBrowserKindFilter>>\n\tsetSortBy: Dispatch<SetStateAction<'name' | 'modifiedAt' | 'size'>>\n\tsetSortDirection: Dispatch<SetStateAction<'asc' | 'desc'>>\n\trefresh: () => Promise<void>\n\tloadMore: () => Promise<void>\n\tnavigate: (path: string, context?: FileBrowserPathChangeContext<TMetadata>) => Promise<void>\n\topen: (node: FileNode<TMetadata>) => Promise<void>\n\tselectOnly: (path: string) => void\n\ttoggleSelection: (path: string) => void\n\tselectRange: (path: string) => void\n\tsetSelection: (paths: string[], options?: { additive?: boolean }) => void\n\tselectAllLoaded: () => void\n\tclearSelection: () => void\n\tcreateFolder: (name: string) => Promise<FileNode<TMetadata>>\n\trename: (path: string, newName: string) => Promise<FileNode<TMetadata>>\n\tdeleteSelected: () => Promise<void>\n\tdeletePaths: (paths: string[]) => Promise<void>\n\tmovePathsTo: (paths: string[], toDir: string) => Promise<void>\n\tmoveSelectedTo: (toDir: string) => Promise<void>\n\tcopySelection: (paths?: string[]) => void\n\tcutSelection: (paths?: string[]) => void\n\tpasteInto: (toDir: string) => Promise<void>\n\tuploadFiles: (files: File[] | FileList, options?: FileBrowserUploadFilesOptions) => Promise<FileNode<TMetadata>[]>\n}\n\nexport function useFileBrowser<TMetadata = unknown>({\n\tadapter,\n\tpath,\n\tinitialPath = '/',\n\tonPathChange,\n\tsearchQuery: controlledSearchQuery,\n\tinitialSearchQuery = '',\n\tonSearchQueryChange\n}: UseFileBrowserOptions<TMetadata>): UseFileBrowserResult<TMetadata> {\n\tconst controlledPath = path === undefined ? undefined : normalizeFileBrowserPath(path)\n\tconst [uncontrolledPath, setUncontrolledPath] = useState(() => normalizeFileBrowserPath(initialPath))\n\tconst currentPath = controlledPath ?? uncontrolledPath\n\tconst [status, setStatus] = useState<FileBrowserStatus>('loading')\n\tconst [items, setItems] = useState<FileNode<TMetadata>[]>([])\n\tconst [cursor, setCursor] = useState<string | undefined>()\n\tconst [error, setError] = useState<Error | null>(null)\n\tconst [selected, setSelected] = useState<Set<string>>(() => new Set())\n\tconst [focusedPath, setFocusedPath] = useState<string | null>(null)\n\tconst [rangeAnchor, setRangeAnchor] = useState<string | null>(null)\n\tconst [clipboard, setClipboard] = useState<FileBrowserClipboard>(null)\n\tconst [view, setView] = useState<FileBrowserView>('grid')\n\tconst [uncontrolledSearchQuery, setUncontrolledSearchQuery] = useState(initialSearchQuery)\n\tconst searchQuery = controlledSearchQuery ?? uncontrolledSearchQuery\n\tconst [filterKind, setFilterKind] = useState<FileBrowserKindFilter>('all')\n\tconst [sortBy, setSortBy] = useState<'name' | 'modifiedAt' | 'size'>('name')\n\tconst [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc')\n\tconst requestIdRef = useRef(0)\n\tconst currentPathRef = useRef(currentPath)\n\tconst cursorRef = useRef<string | undefined>(undefined)\n\tconst searchQueryRef = useRef(searchQuery)\n\tsearchQueryRef.current = searchQuery\n\n\tconst setSearchQuery = useCallback<Dispatch<SetStateAction<string>>>(\n\t\t(nextQuery) => {\n\t\t\tconst resolved = typeof nextQuery === 'function' ? nextQuery(searchQueryRef.current) : nextQuery\n\t\t\tsearchQueryRef.current = resolved\n\t\t\tif (controlledSearchQuery === undefined) {\n\t\t\t\tsetUncontrolledSearchQuery(resolved)\n\t\t\t}\n\t\t\tonSearchQueryChange?.(resolved)\n\t\t},\n\t\t[controlledSearchQuery, onSearchQueryChange]\n\t)\n\n\tconst capabilities = useMemo<FileBrowserCapabilities>(\n\t\t() => ({\n\t\t\tcreateFolder: typeof adapter.createFolder === 'function',\n\t\t\trename: typeof adapter.rename === 'function',\n\t\t\tmove: typeof adapter.move === 'function',\n\t\t\tcopy: typeof adapter.copy === 'function',\n\t\t\tstat: typeof adapter.stat === 'function',\n\t\t\texists: typeof adapter.exists === 'function',\n\t\t\tmultipart:\n\t\t\t\ttypeof adapter.createMultipartUpload === 'function' &&\n\t\t\t\ttypeof adapter.uploadPart === 'function' &&\n\t\t\t\ttypeof adapter.completeMultipartUpload === 'function',\n\t\t\tbulkDownload: typeof adapter.bulkDownloadUrl === 'function'\n\t\t}),\n\t\t[adapter]\n\t)\n\n\tconst selectedPaths = useMemo(() => sortPaths(Array.from(selected)), [selected])\n\tconst selectedItems = useMemo(() => items.filter((item) => selected.has(item.path)), [items, selected])\n\n\tconst filteredItems = useMemo(() => {\n\t\tconst query = searchQuery.trim().toLowerCase()\n\t\treturn [...items]\n\t\t\t.filter((item) => (query ? item.name.toLowerCase().includes(query) : true))\n\t\t\t.filter((item) => (filterKind === 'all' ? true : item.kind === (filterKind === 'files' ? 'file' : 'folder')))\n\t\t\t.sort((left, right) => compareNodes(left, right, sortBy, sortDirection))\n\t}, [filterKind, items, searchQuery, sortBy, sortDirection])\n\n\tconst loadPath = useCallback(\n\t\tasync (path: string, mode: 'replace' | 'append') => {\n\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\tconst requestId = ++requestIdRef.current\n\n\t\t\tsetStatus((current) => (mode === 'replace' || current === 'idle' ? 'loading' : current))\n\t\t\tsetError(null)\n\n\t\t\ttry {\n\t\t\t\tconst result = await adapter.list(normalized, {\n\t\t\t\t\tcursor: mode === 'append' ? cursorRef.current : undefined\n\t\t\t\t})\n\n\t\t\t\tif (requestId !== requestIdRef.current) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tsetItems((current) => (mode === 'append' ? mergeItems(current, result.items) : result.items))\n\t\t\t\tcursorRef.current = result.cursor\n\t\t\t\tsetCursor(result.cursor)\n\t\t\t\tsetStatus('ready')\n\t\t\t} catch (caught) {\n\t\t\t\tif (requestId !== requestIdRef.current) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tsetError(toError(caught))\n\t\t\t\tsetStatus('error')\n\t\t\t}\n\t\t},\n\t\t[adapter]\n\t)\n\n\tconst refresh = useCallback(async () => {\n\t\tawait loadPath(currentPath, 'replace')\n\t}, [currentPath, loadPath])\n\n\tconst navigate = useCallback(\n\t\tasync (nextPath: string, context: FileBrowserPathChangeContext<TMetadata> = { source: 'programmatic' }) => {\n\t\t\tconst normalized = normalizeFileBrowserPath(nextPath)\n\t\t\tif (normalized === currentPathRef.current) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tonPathChange?.(normalized, context)\n\t\t\tif (controlledPath !== undefined) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tcurrentPathRef.current = normalized\n\t\t\tsetUncontrolledPath(normalized)\n\t\t\tsetSelected(new Set())\n\t\t\tsetFocusedPath(null)\n\t\t\tsetRangeAnchor(null)\n\t\t\tcursorRef.current = undefined\n\t\t\tsetCursor(undefined)\n\t\t\tawait loadPath(normalized, 'replace')\n\t\t},\n\t\t[controlledPath, loadPath, onPathChange]\n\t)\n\n\tconst loadMore = useCallback(async () => {\n\t\tif (!cursor || status === 'loading') {\n\t\t\treturn\n\t\t}\n\n\t\tawait loadPath(currentPath, 'append')\n\t}, [currentPath, cursor, loadPath, status])\n\n\tuseEffect(() => {\n\t\tconst nextPath = currentPath\n\t\tif (nextPath !== currentPathRef.current) {\n\t\t\tcurrentPathRef.current = nextPath\n\t\t\tsetSelected(new Set())\n\t\t\tsetFocusedPath(null)\n\t\t\tsetRangeAnchor(null)\n\t\t}\n\t\tcursorRef.current = undefined\n\t\tsetCursor(undefined)\n\t\tvoid Promise.resolve().then(() => loadPath(nextPath, 'replace'))\n\t\t// Uncontrolled navigation loads directly. This effect handles adapter\n\t\t// replacement and externally controlled path changes only.\n\t\t// oxlint-disable-next-line react/exhaustive-deps\n\t}, [adapter, controlledPath])\n\n\tconst selectOnly = useCallback((path: string) => {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tsetSelected(new Set([normalized]))\n\t\tsetFocusedPath(normalized)\n\t\tsetRangeAnchor(normalized)\n\t}, [])\n\n\tconst toggleSelection = useCallback((path: string) => {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tsetSelected((current) => {\n\t\t\tconst next = new Set(current)\n\t\t\tif (next.has(normalized)) {\n\t\t\t\tnext.delete(normalized)\n\t\t\t} else {\n\t\t\t\tnext.add(normalized)\n\t\t\t}\n\t\t\treturn next\n\t\t})\n\t\tsetFocusedPath(normalized)\n\t}, [])\n\n\tconst selectRange = useCallback(\n\t\t(path: string) => {\n\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\tconst anchor = rangeAnchor ?? focusedPath ?? normalized\n\t\t\tconst visiblePaths = filteredItems.map((item) => item.path)\n\t\t\tconst anchorIndex = visiblePaths.indexOf(anchor)\n\t\t\tconst targetIndex = visiblePaths.indexOf(normalized)\n\n\t\t\tif (anchorIndex === -1 || targetIndex === -1) {\n\t\t\t\tselectOnly(normalized)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst start = Math.min(anchorIndex, targetIndex)\n\t\t\tconst end = Math.max(anchorIndex, targetIndex)\n\t\t\tsetSelected(new Set(visiblePaths.slice(start, end + 1)))\n\t\t\tsetFocusedPath(normalized)\n\t\t},\n\t\t[filteredItems, focusedPath, rangeAnchor, selectOnly]\n\t)\n\n\tconst setSelection = useCallback((paths: string[], options: { additive?: boolean } = {}) => {\n\t\tconst normalizedPaths = paths.map(normalizeFileBrowserPath)\n\t\tsetSelected((current) => {\n\t\t\tconst next = options.additive ? new Set(current) : new Set<string>()\n\t\t\tfor (const path of normalizedPaths) {\n\t\t\t\tnext.add(path)\n\t\t\t}\n\t\t\treturn next\n\t\t})\n\t\tsetFocusedPath(normalizedPaths.at(-1) ?? null)\n\t\tsetRangeAnchor(normalizedPaths.at(0) ?? null)\n\t}, [])\n\n\tconst selectAllLoaded = useCallback(() => {\n\t\tsetSelected(new Set(items.map((item) => item.path)))\n\t\tsetFocusedPath(items.at(0)?.path ?? null)\n\t\tsetRangeAnchor(items.at(0)?.path ?? null)\n\t}, [items])\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelected(new Set())\n\t\tsetFocusedPath(null)\n\t\tsetRangeAnchor(null)\n\t}, [])\n\n\tconst open = useCallback(\n\t\tasync (node: FileNode<TMetadata>) => {\n\t\t\tif (node.kind === 'folder') {\n\t\t\t\tawait navigate(node.path, { source: 'item', item: node })\n\t\t\t} else {\n\t\t\t\tselectOnly(node.path)\n\t\t\t}\n\t\t},\n\t\t[navigate, selectOnly]\n\t)\n\n\tconst createFolder = useCallback(\n\t\tasync (name: string) => {\n\t\t\tif (!adapter.createFolder) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Folder creation is not supported by this adapter')\n\t\t\t}\n\t\t\tconst path = joinFileBrowserPath(currentPath, name.trim())\n\t\t\tconst optimistic: FileNode<TMetadata> = {\n\t\t\t\tpath,\n\t\t\t\tname: name.trim(),\n\t\t\t\tkind: 'folder',\n\t\t\t\tmodifiedAt: new Date().toISOString()\n\t\t\t}\n\t\t\tsetItems((current) => mergeItems(current, [optimistic]))\n\n\t\t\ttry {\n\t\t\t\tconst created = await adapter.createFolder(path)\n\t\t\t\tsetItems((current) => mergeItems(removePaths(current, [path]), [created]))\n\t\t\t\treturn created\n\t\t\t} catch (caught) {\n\t\t\t\tsetItems((current) => removePaths(current, [path]))\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t},\n\t\t[adapter, currentPath]\n\t)\n\n\tconst rename = useCallback(\n\t\tasync (path: string, newName: string) => {\n\t\t\tif (!adapter.rename) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Rename is not supported by this adapter')\n\t\t\t}\n\n\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\tconst previous = items\n\t\t\tsetItems((current) =>\n\t\t\t\tcurrent.map((item) => (item.path === normalized ? { ...item, name: newName.trim() } : item))\n\t\t\t)\n\n\t\t\ttry {\n\t\t\t\tconst renamed = await adapter.rename(normalized, newName.trim())\n\t\t\t\tsetItems((current) => current.map((item) => (item.path === normalized ? renamed : item)))\n\t\t\t\treturn renamed\n\t\t\t} catch (caught) {\n\t\t\t\tsetItems(previous)\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t},\n\t\t[adapter, items]\n\t)\n\n\tconst deletePaths = useCallback(\n\t\tasync (paths: string[]) => {\n\t\t\tconst normalizedPaths = paths.map(normalizeFileBrowserPath)\n\t\t\tconst previousItems = items\n\t\t\tconst previousSelected = selected\n\n\t\t\tsetItems((current) => removePaths(current, normalizedPaths))\n\t\t\tsetSelected((current) => {\n\t\t\t\tconst next = new Set(current)\n\t\t\t\tfor (const path of normalizedPaths) {\n\t\t\t\t\tnext.delete(path)\n\t\t\t\t}\n\t\t\t\treturn next\n\t\t\t})\n\n\t\t\ttry {\n\t\t\t\tawait adapter.delete(normalizedPaths)\n\t\t\t} catch (caught) {\n\t\t\t\tif (caught instanceof FileBrowserBulkActionError) {\n\t\t\t\t\tconst succeededPaths = caught.succeededPaths.map(normalizeFileBrowserPath)\n\t\t\t\t\tconst failedPaths = caught.failures.map((failure) => normalizeFileBrowserPath(failure.path))\n\t\t\t\t\tsetItems(removePaths(previousItems, succeededPaths))\n\t\t\t\t\tsetSelected(new Set(failedPaths))\n\t\t\t\t\tsetFocusedPath(failedPaths.at(0) ?? null)\n\t\t\t\t\tsetRangeAnchor(failedPaths.at(0) ?? null)\n\t\t\t\t\tthrow caught\n\t\t\t\t}\n\t\t\t\tsetItems(previousItems)\n\t\t\t\tsetSelected(previousSelected)\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t},\n\t\t[adapter, items, selected]\n\t)\n\n\tconst deleteSelected = useCallback(async () => {\n\t\tawait deletePaths(selectedPaths)\n\t}, [deletePaths, selectedPaths])\n\n\tconst movePathsTo = useCallback(\n\t\tasync (paths: string[], toDir: string) => {\n\t\t\tif (!adapter.move) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Move is not supported by this adapter')\n\t\t\t}\n\n\t\t\tconst normalizedPaths = paths.map(normalizeFileBrowserPath)\n\t\t\tif (normalizedPaths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst destination = normalizeFileBrowserPath(toDir)\n\t\t\ttry {\n\t\t\t\tawait adapter.move(normalizedPaths, destination)\n\t\t\t} catch (caught) {\n\t\t\t\tif (caught instanceof FileBrowserBulkActionError) {\n\t\t\t\t\tconst succeededPaths = caught.succeededPaths.map(normalizeFileBrowserPath)\n\t\t\t\t\tconst failedPaths = caught.failures.map((failure) => normalizeFileBrowserPath(failure.path))\n\t\t\t\t\tif (destination === currentPath) {\n\t\t\t\t\t\tawait refresh()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetItems((current) => removePaths(current, succeededPaths))\n\t\t\t\t\t}\n\t\t\t\t\tsetSelected(new Set(failedPaths))\n\t\t\t\t\tsetFocusedPath(failedPaths.at(0) ?? null)\n\t\t\t\t\tsetRangeAnchor(failedPaths.at(0) ?? null)\n\t\t\t\t\tthrow caught\n\t\t\t\t}\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t\tsetSelected((current) => {\n\t\t\t\tconst next = new Set(current)\n\t\t\t\tfor (const path of normalizedPaths) {\n\t\t\t\t\tnext.delete(path)\n\t\t\t\t}\n\t\t\t\treturn next\n\t\t\t})\n\t\t\tsetFocusedPath(null)\n\t\t\tsetRangeAnchor(null)\n\n\t\t\tif (destination === currentPath) {\n\t\t\t\tawait refresh()\n\t\t\t} else {\n\t\t\t\tsetItems((current) => removePaths(current, normalizedPaths))\n\t\t\t}\n\t\t},\n\t\t[adapter, currentPath, refresh]\n\t)\n\n\tconst moveSelectedTo = useCallback(\n\t\tasync (toDir: string) => {\n\t\t\tawait movePathsTo(selectedPaths, toDir)\n\t\t\tsetClipboard((current) => (current?.type === 'cut' ? null : current))\n\t\t},\n\t\t[movePathsTo, selectedPaths]\n\t)\n\n\tconst copySelection = useCallback(\n\t\t(paths = selectedPaths) => {\n\t\t\tsetClipboard({ type: 'copy', paths: paths.map(normalizeFileBrowserPath) })\n\t\t},\n\t\t[selectedPaths]\n\t)\n\n\tconst cutSelection = useCallback(\n\t\t(paths = selectedPaths) => {\n\t\t\tsetClipboard({ type: 'cut', paths: paths.map(normalizeFileBrowserPath) })\n\t\t},\n\t\t[selectedPaths]\n\t)\n\n\tconst pasteInto = useCallback(\n\t\tasync (toDir: string) => {\n\t\t\tif (!clipboard || clipboard.paths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst destination = normalizeFileBrowserPath(toDir)\n\t\t\tif (clipboard.type === 'copy') {\n\t\t\t\tif (!adapter.copy) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Copy is not supported by this adapter')\n\t\t\t\t}\n\t\t\t\tawait adapter.copy(clipboard.paths, destination)\n\t\t\t} else {\n\t\t\t\tif (!adapter.move) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Move is not supported by this adapter')\n\t\t\t\t}\n\t\t\t\tawait movePathsTo(clipboard.paths, destination)\n\t\t\t\tsetClipboard(null)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (destination === currentPath) {\n\t\t\t\tawait refresh()\n\t\t\t}\n\t\t},\n\t\t[adapter, clipboard, currentPath, movePathsTo, refresh]\n\t)\n\n\tconst uploadFiles = useCallback(\n\t\tasync (files: File[] | FileList, options: FileBrowserUploadFilesOptions = {}) => {\n\t\t\tif (options.onConflict === 'skip') {\n\t\t\t\treturn []\n\t\t\t}\n\n\t\t\tconst fileArray = Array.from(files)\n\t\t\tconst uploaded: FileNode<TMetadata>[] = []\n\n\t\t\tfor (const file of fileArray) {\n\t\t\t\tconst path = joinFileBrowserPath(currentPathRef.current, file.name)\n\t\t\t\tconst result = await adapter.upload(path, file, {\n\t\t\t\t\tonConflict: options.onConflict ?? 'keep-both'\n\t\t\t\t})\n\t\t\t\tuploaded.push(result)\n\t\t\t\tsetItems((current) => mergeItems(current, [result]))\n\t\t\t}\n\n\t\t\treturn uploaded\n\t\t},\n\t\t[adapter]\n\t)\n\n\treturn {\n\t\tadapter,\n\t\tcapabilities,\n\t\tcurrentPath,\n\t\tstatus,\n\t\titems,\n\t\terror,\n\t\thasMore: Boolean(cursor),\n\t\tselectedPaths,\n\t\tselectedItems,\n\t\tfocusedPath,\n\t\tclipboard,\n\t\tview,\n\t\tsearchQuery,\n\t\tfilterKind,\n\t\tsortBy,\n\t\tsortDirection,\n\t\tfilteredItems,\n\t\tsetView,\n\t\tsetSearchQuery,\n\t\tsetFilterKind,\n\t\tsetSortBy,\n\t\tsetSortDirection,\n\t\trefresh,\n\t\tloadMore,\n\t\tnavigate,\n\t\topen,\n\t\tselectOnly,\n\t\ttoggleSelection,\n\t\tselectRange,\n\t\tsetSelection,\n\t\tselectAllLoaded,\n\t\tclearSelection,\n\t\tcreateFolder,\n\t\trename,\n\t\tdeleteSelected,\n\t\tdeletePaths,\n\t\tmovePathsTo,\n\t\tmoveSelectedTo,\n\t\tcopySelection,\n\t\tcutSelection,\n\t\tpasteInto,\n\t\tuploadFiles\n\t}\n}\n\nfunction mergeItems<TMetadata>(current: FileNode<TMetadata>[], incoming: FileNode<TMetadata>[]): FileNode<TMetadata>[] {\n\tconst map = new Map(current.map((item) => [item.path, item]))\n\tfor (const item of incoming) {\n\t\tmap.set(item.path, item)\n\t}\n\treturn Array.from(map.values()).sort((left, right) => compareNodes(left, right, 'name', 'asc'))\n}\n\nfunction removePaths<TMetadata>(items: FileNode<TMetadata>[], paths: string[]): FileNode<TMetadata>[] {\n\tconst remove = new Set(paths)\n\treturn items.filter((item) => !remove.has(item.path))\n}\n\nfunction compareNodes<TMetadata>(\n\tleft: FileNode<TMetadata>,\n\tright: FileNode<TMetadata>,\n\tsortBy: 'name' | 'modifiedAt' | 'size',\n\tdirection: 'asc' | 'desc'\n): number {\n\tconst multiplier = direction === 'asc' ? 1 : -1\n\n\tif (left.kind !== right.kind) {\n\t\treturn left.kind === 'folder' ? -1 : 1\n\t}\n\n\tif (sortBy === 'size') {\n\t\treturn ((left.size ?? 0) - (right.size ?? 0)) * multiplier\n\t}\n\n\tif (sortBy === 'modifiedAt') {\n\t\treturn String(left.modifiedAt ?? '').localeCompare(String(right.modifiedAt ?? '')) * multiplier\n\t}\n\n\treturn (\n\t\tleft.name.localeCompare(right.name, undefined, {\n\t\t\tnumeric: true,\n\t\t\tsensitivity: 'base'\n\t\t}) * multiplier\n\t)\n}\n\nfunction sortPaths(paths: string[]): string[] {\n\treturn [...paths].sort((left, right) => left.localeCompare(right))\n}\n\nfunction toError(caught: unknown): Error {\n\treturn caught instanceof Error ? caught : new Error(String(caught))\n}\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses };\n//# sourceMappingURL=mergeClasses.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n\nexport { toKebabCase };\n//# sourceMappingURL=toKebabCase.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\n\nexport { toCamelCase };\n//# sourceMappingURL=toCamelCase.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { toCamelCase } from './toCamelCase.mjs';\n\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\n\nexport { toPascalCase };\n//# sourceMappingURL=toPascalCase.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n return false;\n};\n\nexport { hasA11yProp };\n//# sourceMappingURL=hasA11yProp.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { createContext, useContext, useMemo, createElement } from 'react';\n\nconst LucideContext = createContext({});\nfunction LucideProvider({\n children,\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n}) {\n const value = useMemo(\n () => ({\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n }),\n [size, color, strokeWidth, absoluteStrokeWidth, className]\n );\n return createElement(LucideContext.Provider, { value }, children);\n}\nconst useLucideContext = () => useContext(LucideContext);\n\nexport { LucideProvider, useLucideContext };\n//# sourceMappingURL=context.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.mjs';\nimport { hasA11yProp } from './shared/src/utils/hasA11yProp.mjs';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { useLucideContext } from './context.mjs';\n\nconst Icon = forwardRef(\n ({ color, size, strokeWidth, absoluteStrokeWidth, className = \"\", children, iconNode, ...rest }, ref) => {\n const {\n size: contextSize = 24,\n strokeWidth: contextStrokeWidth = 2,\n absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,\n color: contextColor = \"currentColor\",\n className: contextClass = \"\"\n } = useLucideContext() ?? {};\n const calculatedStrokeWidth = absoluteStrokeWidth ?? contextAbsoluteStrokeWidth ? Number(strokeWidth ?? contextStrokeWidth) * 24 / Number(size ?? contextSize) : strokeWidth ?? contextStrokeWidth;\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size ?? contextSize ?? defaultAttributes.width,\n height: size ?? contextSize ?? defaultAttributes.height,\n stroke: color ?? contextColor,\n strokeWidth: calculatedStrokeWidth,\n className: mergeClasses(\"lucide\", contextClass, className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { toKebabCase } from './shared/src/utils/toKebabCase.mjs';\nimport { toPascalCase } from './shared/src/utils/toPascalCase.mjs';\nimport Icon from './Icon.mjs';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]];\nconst ChevronDown = createLucideIcon(\"chevron-down\", __iconNode);\n\nexport { __iconNode, ChevronDown as default };\n//# sourceMappingURL=chevron-down.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m15 18-6-6 6-6\", key: \"1wnfg3\" }]];\nconst ChevronLeft = createLucideIcon(\"chevron-left\", __iconNode);\n\nexport { __iconNode, ChevronLeft as default };\n//# sourceMappingURL=chevron-left.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m9 18 6-6-6-6\", key: \"mthhwq\" }]];\nconst ChevronRight = createLucideIcon(\"chevron-right\", __iconNode);\n\nexport { __iconNode, ChevronRight as default };\n//# sourceMappingURL=chevron-right.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m18 15-6-6-6 6\", key: \"153udz\" }]];\nconst ChevronUp = createLucideIcon(\"chevron-up\", __iconNode);\n\nexport { __iconNode, ChevronUp as default };\n//# sourceMappingURL=chevron-up.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"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\" }]\n];\nconst Copy = createLucideIcon(\"copy\", __iconNode);\n\nexport { __iconNode, Copy as default };\n//# sourceMappingURL=copy.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 15V3\", key: \"m9g1x1\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"path\", { d: \"m7 10 5 5 5-5\", key: \"brsn70\" }]\n];\nconst Download = createLucideIcon(\"download\", __iconNode);\n\nexport { __iconNode, Download as default };\n//# sourceMappingURL=download.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"19\", cy: \"12\", r: \"1\", key: \"1wjl8i\" }],\n [\"circle\", { cx: \"5\", cy: \"12\", r: \"1\", key: \"1pcz8c\" }]\n];\nconst Ellipsis = createLucideIcon(\"ellipsis\", __iconNode);\n\nexport { __iconNode, Ellipsis as default };\n//# sourceMappingURL=ellipsis.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }]\n];\nconst File = createLucideIcon(\"file\", __iconNode);\n\nexport { __iconNode, File as default };\n//# sourceMappingURL=file.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1\",\n key: \"fm4g5t\"\n }\n ],\n [\"path\", { d: \"M2 13h10\", key: \"pgb2dq\" }],\n [\"path\", { d: \"m9 16 3-3-3-3\", key: \"6m91ic\" }]\n];\nconst FolderInput = createLucideIcon(\"folder-input\", __iconNode);\n\nexport { __iconNode, FolderInput as default };\n//# sourceMappingURL=folder-input.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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\",\n key: \"1kt360\"\n }\n ]\n];\nconst Folder = createLucideIcon(\"folder\", __iconNode);\n\nexport { __iconNode, Folder as default };\n//# sourceMappingURL=folder.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }],\n [\"path\", { d: \"M3 12h18\", key: \"1i2n21\" }],\n [\"rect\", { x: \"3\", y: \"3\", width: \"18\", height: \"18\", rx: \"2\", key: \"h1oib\" }]\n];\nconst Grid2x2 = createLucideIcon(\"grid-2x2\", __iconNode);\n\nexport { __iconNode, Grid2x2 as default };\n//# sourceMappingURL=grid-2x2.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 16v-4\", key: \"1dtifu\" }],\n [\"path\", { d: \"M12 8h.01\", key: \"e9boi3\" }]\n];\nconst Info = createLucideIcon(\"info\", __iconNode);\n\nexport { __iconNode, Info as default };\n//# sourceMappingURL=info.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 5h.01\", key: \"18ugdj\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M3 19h.01\", key: \"noohij\" }],\n [\"path\", { d: \"M8 5h13\", key: \"1pao27\" }],\n [\"path\", { d: \"M8 12h13\", key: \"1za7za\" }],\n [\"path\", { d: \"M8 19h13\", key: \"m83p4d\" }]\n];\nconst List = createLucideIcon(\"list\", __iconNode);\n\nexport { __iconNode, List as default };\n//# sourceMappingURL=list.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { x: \"14\", y: \"3\", width: \"5\", height: \"18\", rx: \"1\", key: \"kaeet6\" }],\n [\"rect\", { x: \"5\", y: \"3\", width: \"5\", height: \"18\", rx: \"1\", key: \"1wsw3u\" }]\n];\nconst Pause = createLucideIcon(\"pause\", __iconNode);\n\nexport { __iconNode, Pause as default };\n//# sourceMappingURL=pause.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\",\n key: \"1a8usu\"\n }\n ],\n [\"path\", { d: \"m15 5 4 4\", key: \"1mk7zo\" }]\n];\nconst Pencil = createLucideIcon(\"pencil\", __iconNode);\n\nexport { __iconNode, Pencil as default };\n//# sourceMappingURL=pencil.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\",\n key: \"10ikf1\"\n }\n ]\n];\nconst Play = createLucideIcon(\"play\", __iconNode);\n\nexport { __iconNode, Play as default };\n//# sourceMappingURL=play.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n];\nconst Scissors = createLucideIcon(\"scissors\", __iconNode);\n\nexport { __iconNode, Scissors as default };\n//# sourceMappingURL=scissors.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M21 10.656V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h12.344\", key: \"2acyp4\" }\n ],\n [\"path\", { d: \"m9 11 3 3L22 4\", key: \"1pflzl\" }]\n];\nconst SquareCheckBig = createLucideIcon(\"square-check-big\", __iconNode);\n\nexport { __iconNode, SquareCheckBig as default };\n//# sourceMappingURL=square-check-big.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n];\nconst Square = createLucideIcon(\"square\", __iconNode);\n\nexport { __iconNode, Square as default };\n//# sourceMappingURL=square.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3v12\", key: \"1x0j5s\" }],\n [\"path\", { d: \"m17 8-5-5-5 5\", key: \"7q97r8\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }]\n];\nconst Upload = createLucideIcon(\"upload\", __iconNode);\n\nexport { __iconNode, Upload as default };\n//# sourceMappingURL=upload.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.mjs.map\n","export type FileBrowserUploadCandidate = {\n\tfile: File\n\trelativePath: string\n}\n\ntype FileSystemEntryLike = FileSystemFileEntryLike | FileSystemDirectoryEntryLike\n\ntype FileSystemFileEntryLike = {\n\tisFile: true\n\tisDirectory: false\n\tname: string\n\tfile: (success: (file: File) => void, error?: (error: DOMException) => void) => void\n}\n\ntype FileSystemDirectoryEntryLike = {\n\tisFile: false\n\tisDirectory: true\n\tname: string\n\tcreateReader: () => {\n\t\treadEntries: (success: (entries: FileSystemEntryLike[]) => void, error?: (error: DOMException) => void) => void\n\t}\n}\n\ntype DataTransferItemWithEntry = {\n\twebkitGetAsEntry?: () => FileSystemEntryLike | null\n}\n\nexport async function collectUploadCandidatesFromDataTransfer(\n\tdataTransfer: DataTransfer\n): Promise<FileBrowserUploadCandidate[]> {\n\tconst entries = Array.from(dataTransfer.items)\n\t\t.map((item) => (item as unknown as DataTransferItemWithEntry).webkitGetAsEntry?.())\n\t\t.filter((entry): entry is FileSystemEntryLike => Boolean(entry))\n\n\tif (entries.length === 0) {\n\t\treturn getFileBrowserUploadCandidates(dataTransfer.files)\n\t}\n\n\tconst candidates: FileBrowserUploadCandidate[] = []\n\tfor (const entry of entries) {\n\t\tcandidates.push(...(await collectEntryCandidates(entry)))\n\t}\n\treturn candidates\n}\n\nexport function getFileBrowserUploadCandidates(files: File[] | FileList): FileBrowserUploadCandidate[] {\n\treturn Array.from(files).map((file) => ({\n\t\tfile,\n\t\trelativePath: sanitizeRelativePath(getFileRelativePath(file))\n\t}))\n}\n\nasync function collectEntryCandidates(entry: FileSystemEntryLike, prefix = ''): Promise<FileBrowserUploadCandidate[]> {\n\tif (entry.isFile) {\n\t\tconst file = await readEntryFile(entry)\n\t\treturn [\n\t\t\t{\n\t\t\t\tfile,\n\t\t\t\trelativePath: sanitizeRelativePath(joinRelativePath(prefix, file.name))\n\t\t\t}\n\t\t]\n\t}\n\n\tconst nextPrefix = joinRelativePath(prefix, entry.name)\n\tconst entries = await readAllDirectoryEntries(entry)\n\tconst candidates: FileBrowserUploadCandidate[] = []\n\n\tfor (const child of entries) {\n\t\tcandidates.push(...(await collectEntryCandidates(child, nextPrefix)))\n\t}\n\n\treturn candidates\n}\n\nfunction readEntryFile(entry: FileSystemFileEntryLike): Promise<File> {\n\treturn new Promise((resolve, reject) => {\n\t\tentry.file(resolve, reject)\n\t})\n}\n\nasync function readAllDirectoryEntries(entry: FileSystemDirectoryEntryLike): Promise<FileSystemEntryLike[]> {\n\tconst reader = entry.createReader()\n\tconst entries: FileSystemEntryLike[] = []\n\n\twhile (true) {\n\t\tconst batch = await new Promise<FileSystemEntryLike[]>((resolve, reject) => {\n\t\t\treader.readEntries(resolve, reject)\n\t\t})\n\t\tif (batch.length === 0) {\n\t\t\tbreak\n\t\t}\n\t\tentries.push(...batch)\n\t}\n\n\treturn entries\n}\n\nfunction getFileRelativePath(file: File): string {\n\tconst withRelativePath = file as File & { webkitRelativePath?: string }\n\treturn withRelativePath.webkitRelativePath || file.name\n}\n\nfunction joinRelativePath(...parts: string[]): string {\n\treturn parts.filter(Boolean).join('/')\n}\n\nfunction sanitizeRelativePath(path: string): string {\n\treturn path\n\t\t.replaceAll('\\\\', '/')\n\t\t.split('/')\n\t\t.filter((part) => part && part !== '.' && part !== '..')\n\t\t.join('/')\n}\n","import { zipSync } from 'fflate'\nimport type { Zippable } from 'fflate'\nimport { FileBrowserAdapterError } from '../core/types'\nimport type { FileBrowserAdapter, FileBrowserUploadOptions, FileNode, MultipartUploadPart } from '../core/types'\nimport { getFileBrowserBasename, getFileBrowserDirname, joinFileBrowserPath } from '../core/path'\n\nexport type TransferStatus = 'queued' | 'uploading' | 'paused' | 'failed' | 'completed' | 'cancelled'\n\nexport type UploadTransfer = {\n\tid: string\n\tkind: 'upload'\n\tstatus: TransferStatus\n\tpath: string\n\tname: string\n\tloadedBytes: number\n\ttotalBytes: number\n\tbytesPerSecond?: number\n\tcompletedParts: MultipartUploadPart[]\n\tcreatedAt: string\n\tupdatedAt: string\n\terror?: string\n\tuploadId?: string\n\tpartSize?: number\n\tfile?: File\n\tonConflict?: FileBrowserUploadOptions['onConflict']\n\tadapter?: FileBrowserAdapter\n\tresult?: FileNode\n\tabortController?: AbortController\n\tgroup?: UploadTransferGroup\n}\n\nexport type UploadTransferGroup = {\n\tid: string\n\tname: string\n\ttotalFiles: number\n\tcreatedFolders: number\n}\n\nexport type BulkDownloadJob = {\n\tid: string\n\tkind: 'bulk-download'\n\tstatus: 'preparing' | 'warning' | 'ready' | 'failed'\n\tstrategy: 'single' | 'server' | 'client'\n\tpaths: string[]\n\tselectedBytes: number\n\tcreatedAt: string\n\tupdatedAt: string\n\turl?: string\n\texpiresAt?: string\n\twarning?: 'client_zip_size'\n\terror?: string\n}\n\ntype InternalBulkDownloadJob = BulkDownloadJob & {\n\tadapter?: FileBrowserAdapter\n}\n\nexport type TransferSnapshot = {\n\tuploads: UploadTransfer[]\n\tdownloads: BulkDownloadJob[]\n}\n\nexport type EnqueueUploadInput = {\n\tadapter: FileBrowserAdapter\n\tdestinationPath: string\n\tfile: File\n\tonConflict?: FileBrowserUploadOptions['onConflict']\n\tgroup?: UploadTransferGroup\n}\n\nexport type ResumeRestoredUploadInput = {\n\tid: string\n\tadapter: FileBrowserAdapter\n\tfile: File\n\tonConflict?: FileBrowserUploadOptions['onConflict']\n}\n\nexport type PrepareBulkDownloadInput = {\n\tadapter: FileBrowserAdapter\n\tpaths: string[]\n\tselectedBytes: number\n\twarnZipSizeBytes?: number\n\tallowClientZipFallback?: boolean\n}\n\nexport type PrepareSingleDownloadInput = {\n\tadapter: FileBrowserAdapter\n\tpath: string\n\tselectedBytes?: number\n}\n\nexport type TransferManagerOptions = {\n\tstorage?: Storage | null\n\tstorageKey?: string\n\tidFactory?: () => string\n\tnow?: () => Date\n\tmaxConcurrentUploads?: number\n}\n\ntype PersistedUploadTransfer = Pick<\n\tUploadTransfer,\n\t| 'id'\n\t| 'kind'\n\t| 'status'\n\t| 'path'\n\t| 'name'\n\t| 'loadedBytes'\n\t| 'totalBytes'\n\t| 'bytesPerSecond'\n\t| 'completedParts'\n\t| 'createdAt'\n\t| 'updatedAt'\n\t| 'error'\n\t| 'uploadId'\n\t| 'partSize'\n\t| 'onConflict'\n\t| 'group'\n>\n\ntype PersistedTransferSnapshot = {\n\tuploads: PersistedUploadTransfer[]\n\tdownloads: BulkDownloadJob[]\n}\n\ntype UploadSpeedSample = {\n\tloadedBytes: number\n\ttimeMs: number\n}\n\nconst DEFAULT_STORAGE_KEY = 'react-file-browser-transfers'\nconst DOWNLOAD_RETENTION_MS = 24 * 60 * 60 * 1000\n\nexport class TransferManager {\n\tprivate readonly uploads = new Map<string, UploadTransfer>()\n\tprivate readonly downloads = new Map<string, InternalBulkDownloadJob>()\n\tprivate readonly uploadSpeedSamples = new Map<string, UploadSpeedSample>()\n\tprivate readonly subscribers = new Set<() => void>()\n\tprivate readonly activeTasks = new Set<Promise<void>>()\n\tprivate readonly runningUploadIds = new Set<string>()\n\tprivate readonly storage?: Storage\n\tprivate readonly storageKey: string\n\tprivate readonly idFactory: () => string\n\tprivate readonly now: () => Date\n\tprivate readonly maxConcurrentUploads: number\n\tprivate snapshotCache: TransferSnapshot | undefined\n\n\tconstructor(options: TransferManagerOptions = {}) {\n\t\tthis.storage = options.storage ?? undefined\n\t\tthis.storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY\n\t\tthis.idFactory = options.idFactory ?? createId\n\t\tthis.now = options.now ?? (() => new Date())\n\t\tthis.maxConcurrentUploads = validateMaxConcurrentUploads(options.maxConcurrentUploads)\n\t\tthis.restorePersisted()\n\t\tif (this.downloads.size > 0) {\n\t\t\tthis.pruneExpiredDownloads()\n\t\t}\n\t}\n\n\tsubscribe(listener: () => void): () => void {\n\t\tthis.subscribers.add(listener)\n\t\treturn () => {\n\t\t\tthis.subscribers.delete(listener)\n\t\t}\n\t}\n\n\tgetSnapshot(): TransferSnapshot {\n\t\tthis.snapshotCache ??= {\n\t\t\tuploads: Array.from(this.uploads.values()).map(cloneUpload),\n\t\t\tdownloads: Array.from(this.downloads.values()).map((download) => ({\n\t\t\t\t...cloneDownload(download)\n\t\t\t}))\n\t\t}\n\t\treturn this.snapshotCache\n\t}\n\n\tgetUpload(id: string): UploadTransfer | undefined {\n\t\tconst upload = this.uploads.get(id)\n\t\treturn upload ? cloneUpload(upload) : undefined\n\t}\n\n\tgetRestorableUploads(): UploadTransfer[] {\n\t\treturn Array.from(this.uploads.values())\n\t\t\t.filter((upload) => ['queued', 'uploading', 'paused', 'failed'].includes(upload.status))\n\t\t\t.filter((upload) => !upload.file || !upload.adapter)\n\t\t\t.map(cloneUpload)\n\t}\n\n\tdismissRestoredUploads(ids: string[]): void {\n\t\tfor (const id of ids) {\n\t\t\tconst upload = this.uploads.get(id)\n\t\t\tif (!upload) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tupload.status = 'cancelled'\n\t\t\tthis.uploadSpeedSamples.delete(id)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t}\n\t\tthis.persistAndNotify()\n\t}\n\n\tdismissDownload(id: string): void {\n\t\tconst download = this.downloads.get(id)\n\t\tif (!download) {\n\t\t\treturn\n\t\t}\n\n\t\trevokeDownloadUrl(download.url)\n\t\tthis.downloads.delete(id)\n\t\tthis.persistAndNotify()\n\t}\n\n\thasActiveTransfers(): boolean {\n\t\tconst snapshot = this.getSnapshot()\n\t\treturn (\n\t\t\tsnapshot.uploads.some((upload) => ['queued', 'uploading'].includes(upload.status)) ||\n\t\t\tsnapshot.downloads.some((download) => download.status === 'preparing')\n\t\t)\n\t}\n\n\tenqueueUpload({ adapter, destinationPath, file, group, onConflict }: EnqueueUploadInput): string {\n\t\tconst id = this.idFactory()\n\t\tconst timestamp = this.timestamp()\n\t\tconst upload: UploadTransfer = {\n\t\t\tid,\n\t\t\tkind: 'upload',\n\t\t\tstatus: 'queued',\n\t\t\tpath: destinationPath,\n\t\t\tname: file.name,\n\t\t\tloadedBytes: 0,\n\t\t\ttotalBytes: file.size,\n\t\t\tcompletedParts: [],\n\t\t\tcreatedAt: timestamp,\n\t\t\tupdatedAt: timestamp,\n\t\t\tadapter,\n\t\t\tfile,\n\t\t\tgroup,\n\t\t\tonConflict,\n\t\t\tabortController: new AbortController()\n\t\t}\n\t\tthis.uploads.set(id, upload)\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\treturn id\n\t}\n\n\tresumeUpload(id: string): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload || !upload.adapter || !upload.file || this.runningUploadIds.has(id)) {\n\t\t\treturn Promise.resolve()\n\t\t}\n\n\t\tupload.status = 'queued'\n\t\tupload.error = undefined\n\t\tupload.bytesPerSecond = undefined\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.abortController = new AbortController()\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\treturn Promise.resolve()\n\t}\n\n\tresumeRestoredUpload({ adapter, file, id, onConflict }: ResumeRestoredUploadInput): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload) {\n\t\t\treturn Promise.resolve()\n\t\t}\n\n\t\tupload.adapter = adapter\n\t\tupload.file = file\n\t\tupload.name = file.name\n\t\tupload.totalBytes = file.size\n\t\tupload.onConflict = onConflict ?? upload.onConflict\n\t\tupload.status = 'queued'\n\t\tupload.error = undefined\n\t\tupload.bytesPerSecond = undefined\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.abortController = new AbortController()\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\treturn Promise.resolve()\n\t}\n\n\tpauseUpload(id: string): void {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload) {\n\t\t\treturn\n\t\t}\n\t\tupload.status = 'paused'\n\t\tupload.abortController?.abort()\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t}\n\n\tasync cancelUpload(id: string): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload) {\n\t\t\treturn\n\t\t}\n\n\t\tupload.status = 'cancelled'\n\t\tupload.abortController?.abort()\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\tif (upload.uploadId && upload.adapter?.abortMultipartUpload) {\n\t\t\tawait upload.adapter.abortMultipartUpload(upload.uploadId)\n\t\t}\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\twhile (this.activeTasks.size > 0) {\n\t\t\tawait Promise.allSettled(Array.from(this.activeTasks))\n\t\t}\n\t}\n\n\tasync prepareBulkDownload({\n\t\tadapter,\n\t\tpaths,\n\t\tselectedBytes,\n\t\twarnZipSizeBytes = Number.POSITIVE_INFINITY,\n\t\tallowClientZipFallback = true\n\t}: PrepareBulkDownloadInput): Promise<BulkDownloadJob> {\n\t\tconst id = this.idFactory()\n\t\tconst timestamp = this.timestamp()\n\t\tconst job: InternalBulkDownloadJob = {\n\t\t\tid,\n\t\t\tkind: 'bulk-download',\n\t\t\tstatus: 'preparing',\n\t\t\tstrategy: adapter.bulkDownloadUrl ? 'server' : 'client',\n\t\t\tadapter,\n\t\t\tpaths: [...paths],\n\t\t\tselectedBytes,\n\t\t\tcreatedAt: timestamp,\n\t\t\tupdatedAt: timestamp\n\t\t}\n\t\tthis.downloads.set(id, job)\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tif (adapter.bulkDownloadUrl) {\n\t\t\t\tconst result = await adapter.bulkDownloadUrl(paths)\n\t\t\t\tjob.status = 'ready'\n\t\t\t\tjob.url = result.url\n\t\t\t\tjob.expiresAt = result.expiresAt\n\t\t\t} else if (!allowClientZipFallback) {\n\t\t\t\tthrow new Error('Client-side ZIP fallback is disabled.')\n\t\t\t} else if (selectedBytes > warnZipSizeBytes) {\n\t\t\t\tjob.status = 'warning'\n\t\t\t\tjob.warning = 'client_zip_size'\n\t\t\t} else {\n\t\t\t\tjob.url = await createClientZipUrl(adapter, paths)\n\t\t\t\tjob.status = 'ready'\n\t\t\t}\n\t\t} catch (caught) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = toErrorMessage(caught)\n\t\t}\n\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\treturn cloneDownload(job)\n\t}\n\n\tasync prepareSingleDownload({\n\t\tadapter,\n\t\tpath,\n\t\tselectedBytes = 0\n\t}: PrepareSingleDownloadInput): Promise<BulkDownloadJob> {\n\t\tconst id = this.idFactory()\n\t\tconst timestamp = this.timestamp()\n\t\tconst job: InternalBulkDownloadJob = {\n\t\t\tid,\n\t\t\tkind: 'bulk-download',\n\t\t\tstatus: 'preparing',\n\t\t\tstrategy: 'single',\n\t\t\tadapter,\n\t\t\tpaths: [path],\n\t\t\tselectedBytes,\n\t\t\tcreatedAt: timestamp,\n\t\t\tupdatedAt: timestamp\n\t\t}\n\t\tthis.downloads.set(id, job)\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tjob.url = await adapter.signedUrl(path)\n\t\t\tjob.status = 'ready'\n\t\t} catch (caught) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = toErrorMessage(caught)\n\t\t}\n\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\treturn cloneDownload(job)\n\t}\n\n\tasync confirmBulkDownload(id: string): Promise<BulkDownloadJob | undefined> {\n\t\tconst job = this.downloads.get(id)\n\t\tif (!job) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tif (job.status !== 'warning') {\n\t\t\treturn cloneDownload(job)\n\t\t}\n\n\t\tif (!job.adapter) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = 'This download can no longer continue in the current session.'\n\t\t\tjob.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t\treturn cloneDownload(job)\n\t\t}\n\n\t\tjob.status = 'preparing'\n\t\tjob.warning = undefined\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tjob.url = await createClientZipUrl(job.adapter, job.paths)\n\t\t\tjob.status = 'ready'\n\t\t} catch (caught) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = toErrorMessage(caught)\n\t\t}\n\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\treturn cloneDownload(job)\n\t}\n\n\tprivate async runUpload(id: string): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload?.adapter || !upload.file || upload.status !== 'queued') {\n\t\t\treturn\n\t\t}\n\n\t\tupload.status = 'uploading'\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tconst result = hasMultipart(upload.adapter)\n\t\t\t\t? await this.runMultipartUpload(upload)\n\t\t\t\t: await this.runSimpleUpload(upload)\n\t\t\tif (['paused', 'cancelled'].includes(upload.status)) {\n\t\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\t\tthis.persistAndNotify()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tupload.status = 'completed'\n\t\t\tupload.loadedBytes = upload.totalBytes\n\t\t\tupload.result = result\n\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t} catch (caught) {\n\t\t\tif (['paused', 'cancelled'].includes(upload.status)) {\n\t\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\t\tthis.persistAndNotify()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tupload.status = 'failed'\n\t\t\tupload.error = toErrorMessage(caught)\n\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t}\n\t}\n\n\tprivate async runSimpleUpload(upload: UploadTransfer): Promise<FileNode> {\n\t\tif (!upload.adapter || !upload.file) {\n\t\t\tthrow new Error('Upload is missing adapter or file')\n\t\t}\n\n\t\treturn upload.adapter.upload(upload.path, upload.file, {\n\t\t\tonConflict: upload.onConflict,\n\t\t\tsignal: upload.abortController?.signal,\n\t\t\tonProgress: (loaded, total) => {\n\t\t\t\tthis.updateUploadProgress(upload, loaded, total)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate async runMultipartUpload(upload: UploadTransfer): Promise<FileNode> {\n\t\tconst adapter = upload.adapter\n\t\tconst file = upload.file\n\t\tif (!adapter || !file || !hasMultipart(adapter)) {\n\t\t\tthrow new Error('Multipart upload is not available')\n\t\t}\n\n\t\tif (!upload.uploadId || !upload.partSize) {\n\t\t\tawait prepareMultipartDestination(upload)\n\t\t\tconst created = await adapter.createMultipartUpload(upload.path, file.size)\n\t\t\tupload.uploadId = created.uploadId\n\t\t\tupload.partSize = created.partSize\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t}\n\n\t\tconst partSize = upload.partSize\n\t\tconst partCount = Math.ceil(file.size / partSize)\n\t\tfor (let partNumber = 1; partNumber <= partCount; partNumber += 1) {\n\t\t\tif (upload.completedParts.some((part) => part.partNumber === partNumber)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst start = (partNumber - 1) * partSize\n\t\t\tconst end = Math.min(start + partSize, file.size)\n\t\t\tconst chunk = file.slice(start, end)\n\t\t\tconst completedBeforePart = completedBytes(upload)\n\t\t\tconst result = await adapter.uploadPart({\n\t\t\t\tuploadId: upload.uploadId,\n\t\t\t\tpartNumber,\n\t\t\t\tchunk,\n\t\t\t\tsignal: upload.abortController?.signal,\n\t\t\t\tonProgress: (loaded) => {\n\t\t\t\t\tthis.updateUploadProgress(upload, completedBeforePart + loaded, upload.totalBytes)\n\t\t\t\t}\n\t\t\t})\n\t\t\tupload.completedParts = [...upload.completedParts, { partNumber, etag: result.etag }].sort(\n\t\t\t\t(left, right) => left.partNumber - right.partNumber\n\t\t\t)\n\t\t\tupload.loadedBytes = completedBytes(upload)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t}\n\n\t\treturn adapter.completeMultipartUpload({\n\t\t\tuploadId: upload.uploadId,\n\t\t\tparts: upload.completedParts\n\t\t})\n\t}\n\n\tprivate updateUploadProgress(upload: UploadTransfer, loadedBytes: number, totalBytes: number): void {\n\t\tconst sampledAt = this.now()\n\t\tconst timeMs = sampledAt.getTime()\n\t\tconst previous = this.uploadSpeedSamples.get(upload.id)\n\n\t\tupload.loadedBytes = loadedBytes\n\t\tupload.totalBytes = totalBytes\n\t\tif (previous && loadedBytes > previous.loadedBytes && timeMs > previous.timeMs) {\n\t\t\tupload.bytesPerSecond = ((loadedBytes - previous.loadedBytes) / (timeMs - previous.timeMs)) * 1000\n\t\t}\n\t\tthis.uploadSpeedSamples.set(upload.id, { loadedBytes, timeMs })\n\t\tupload.updatedAt = sampledAt.toISOString()\n\t\tthis.persistAndNotify()\n\t}\n\n\tprivate pumpUploadQueue(): void {\n\t\twhile (this.runningUploadIds.size < this.maxConcurrentUploads) {\n\t\t\tconst upload = Array.from(this.uploads.values()).find(\n\t\t\t\t(candidate) =>\n\t\t\t\t\tcandidate.status === 'queued' &&\n\t\t\t\t\tBoolean(candidate.adapter) &&\n\t\t\t\t\tBoolean(candidate.file) &&\n\t\t\t\t\t!this.runningUploadIds.has(candidate.id)\n\t\t\t)\n\t\t\tif (!upload) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.runningUploadIds.add(upload.id)\n\t\t\tconst task = this.runUpload(upload.id)\n\t\t\tthis.activeTasks.add(task)\n\t\t\tconst release = () => {\n\t\t\t\tthis.activeTasks.delete(task)\n\t\t\t\tthis.runningUploadIds.delete(upload.id)\n\t\t\t\tthis.pumpUploadQueue()\n\t\t\t}\n\t\t\tvoid task.then(release, release)\n\t\t}\n\t}\n\n\tprivate persistAndNotify(): void {\n\t\tthis.snapshotCache = undefined\n\t\tthis.persist()\n\t\tfor (const subscriber of this.subscribers) {\n\t\t\tsubscriber()\n\t\t}\n\t}\n\n\tprivate persist(): void {\n\t\tif (!this.storage) {\n\t\t\treturn\n\t\t}\n\n\t\tconst payload: PersistedTransferSnapshot = {\n\t\t\tuploads: Array.from(this.uploads.values()).map(toPersistedUpload),\n\t\t\tdownloads: Array.from(this.downloads.values()).map(toPersistedDownload)\n\t\t}\n\t\tthis.storage.setItem(this.storageKey, JSON.stringify(payload))\n\t}\n\n\tprivate restorePersisted(): void {\n\t\tif (!this.storage) {\n\t\t\treturn\n\t\t}\n\n\t\tconst raw = this.storage.getItem(this.storageKey)\n\t\tif (!raw) {\n\t\t\treturn\n\t\t}\n\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(raw) as Partial<PersistedTransferSnapshot>\n\t\t\tfor (const upload of parsed.uploads ?? []) {\n\t\t\t\tconst restored = restorePersistedUpload(upload)\n\t\t\t\tthis.uploads.set(restored.id, restored)\n\t\t\t}\n\t\t\tfor (const download of parsed.downloads ?? []) {\n\t\t\t\tconst restored = restorePersistedDownload(download)\n\t\t\t\tthis.downloads.set(restored.id, restored)\n\t\t\t}\n\t\t} catch {\n\t\t\tthis.storage.removeItem(this.storageKey)\n\t\t}\n\t}\n\n\tprivate timestamp(): string {\n\t\treturn this.now().toISOString()\n\t}\n\n\tprivate pruneExpiredDownloads(): void {\n\t\tconst nowMs = this.now().getTime()\n\t\tlet changed = false\n\n\t\tfor (const [id, download] of this.downloads) {\n\t\t\tif (!isExpiredOrStaleDownload(download, nowMs)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\trevokeDownloadUrl(download.url)\n\t\t\tthis.downloads.delete(id)\n\t\t\tchanged = true\n\t\t}\n\n\t\tif (!changed) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.snapshotCache = undefined\n\t\tthis.persist()\n\t}\n}\n\nfunction hasMultipart(\n\tadapter: FileBrowserAdapter\n): adapter is FileBrowserAdapter &\n\tRequired<Pick<FileBrowserAdapter, 'createMultipartUpload' | 'uploadPart' | 'completeMultipartUpload'>> {\n\treturn (\n\t\ttypeof adapter.createMultipartUpload === 'function' &&\n\t\ttypeof adapter.uploadPart === 'function' &&\n\t\ttypeof adapter.completeMultipartUpload === 'function'\n\t)\n}\n\nfunction completedBytes(upload: UploadTransfer): number {\n\tconst partSize = upload.partSize ?? upload.totalBytes\n\treturn upload.completedParts.reduce((total, part) => {\n\t\tconst start = (part.partNumber - 1) * partSize\n\t\treturn total + Math.min(partSize, upload.totalBytes - start)\n\t}, 0)\n}\n\nasync function prepareMultipartDestination(upload: UploadTransfer): Promise<void> {\n\tconst adapter = upload.adapter\n\tif (!adapter?.exists) {\n\t\treturn\n\t}\n\tconst exists: NonNullable<FileBrowserAdapter['exists']> = (paths) => adapter.exists?.(paths) ?? Promise.resolve({})\n\n\tconst current = await exists([upload.path])\n\tif (!current[upload.path]) {\n\t\treturn\n\t}\n\n\tif (upload.onConflict === 'keep-both') {\n\t\tupload.path = await nextAvailableUploadPath(exists, upload.path)\n\t\treturn\n\t}\n\n\tif (upload.onConflict !== 'replace') {\n\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${upload.path}`)\n\t}\n}\n\nasync function nextAvailableUploadPath(\n\texists: NonNullable<FileBrowserAdapter['exists']>,\n\tpath: string\n): Promise<string> {\n\tconst dir = getFileBrowserDirname(path)\n\tconst basename = getFileBrowserBasename(path)\n\tconst dotIndex = basename.lastIndexOf('.')\n\tconst hasExtension = dotIndex > 0\n\tconst stem = hasExtension ? basename.slice(0, dotIndex) : basename\n\tconst extension = hasExtension ? basename.slice(dotIndex) : ''\n\n\tfor (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n\t\tconst candidate = joinFileBrowserPath(dir, `${stem} (${index})${extension}`)\n\t\tconst result = await exists([candidate])\n\t\tif (!result[candidate]) {\n\t\t\treturn candidate\n\t\t}\n\t}\n\n\tthrow new FileBrowserAdapterError('conflict', `Could not allocate a unique file browser path for ${path}`)\n}\n\nfunction cloneUpload(upload: UploadTransfer): UploadTransfer {\n\treturn {\n\t\t...upload,\n\t\tgroup: upload.group ? { ...upload.group } : undefined,\n\t\tcompletedParts: upload.completedParts.map((part) => ({ ...part }))\n\t}\n}\n\nfunction cloneDownload(download: InternalBulkDownloadJob): BulkDownloadJob {\n\tconst { adapter: _adapter, ...snapshot } = download\n\tvoid _adapter\n\treturn {\n\t\t...snapshot,\n\t\tpaths: [...download.paths]\n\t}\n}\n\nfunction toPersistedUpload(upload: UploadTransfer): PersistedUploadTransfer {\n\treturn {\n\t\tid: upload.id,\n\t\tkind: upload.kind,\n\t\tstatus: upload.status,\n\t\tpath: upload.path,\n\t\tname: upload.name,\n\t\tloadedBytes: upload.loadedBytes,\n\t\ttotalBytes: upload.totalBytes,\n\t\tbytesPerSecond: upload.bytesPerSecond,\n\t\tcompletedParts: upload.completedParts.map((part) => ({ ...part })),\n\t\tcreatedAt: upload.createdAt,\n\t\tupdatedAt: upload.updatedAt,\n\t\terror: upload.error,\n\t\tuploadId: upload.uploadId,\n\t\tpartSize: upload.partSize,\n\t\tonConflict: upload.onConflict,\n\t\tgroup: upload.group ? { ...upload.group } : undefined\n\t}\n}\n\nfunction restorePersistedUpload(upload: PersistedUploadTransfer): UploadTransfer {\n\treturn {\n\t\tid: upload.id,\n\t\tkind: 'upload',\n\t\tstatus: upload.status,\n\t\tpath: upload.path,\n\t\tname: upload.name,\n\t\tloadedBytes: upload.loadedBytes,\n\t\ttotalBytes: upload.totalBytes,\n\t\tbytesPerSecond: upload.bytesPerSecond,\n\t\tcompletedParts: upload.completedParts.map((part) => ({ ...part })),\n\t\tcreatedAt: upload.createdAt,\n\t\tupdatedAt: upload.updatedAt,\n\t\terror: upload.error,\n\t\tuploadId: upload.uploadId,\n\t\tpartSize: upload.partSize,\n\t\tonConflict: upload.onConflict,\n\t\tgroup: upload.group ? { ...upload.group } : undefined\n\t}\n}\n\nfunction toPersistedDownload(download: InternalBulkDownloadJob): BulkDownloadJob {\n\treturn {\n\t\tid: download.id,\n\t\tkind: download.kind,\n\t\tstatus: download.status,\n\t\tstrategy: download.strategy,\n\t\tpaths: [...download.paths],\n\t\tselectedBytes: download.selectedBytes,\n\t\tcreatedAt: download.createdAt,\n\t\tupdatedAt: download.updatedAt,\n\t\turl: download.url,\n\t\texpiresAt: download.expiresAt,\n\t\twarning: download.warning,\n\t\terror: download.error\n\t}\n}\n\nfunction restorePersistedDownload(download: BulkDownloadJob): InternalBulkDownloadJob {\n\treturn toPersistedDownload(download)\n}\n\nfunction validateMaxConcurrentUploads(value: number | undefined): number {\n\tif (value === undefined) {\n\t\treturn Number.POSITIVE_INFINITY\n\t}\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new RangeError('maxConcurrentUploads must be a positive integer')\n\t}\n\treturn value\n}\n\nfunction isExpiredOrStaleDownload(download: InternalBulkDownloadJob, nowMs: number): boolean {\n\tif (download.status === 'preparing') {\n\t\treturn false\n\t}\n\n\tif (download.expiresAt) {\n\t\tconst expiresAtMs = Date.parse(download.expiresAt)\n\t\tif (Number.isFinite(expiresAtMs) && expiresAtMs <= nowMs) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\tconst updatedAtMs = Date.parse(download.updatedAt)\n\treturn Number.isFinite(updatedAtMs) && nowMs - updatedAtMs > DOWNLOAD_RETENTION_MS\n}\n\nfunction revokeDownloadUrl(url: string | undefined): void {\n\tif (!url?.startsWith('blob:') || typeof URL === 'undefined' || typeof URL.revokeObjectURL !== 'function') {\n\t\treturn\n\t}\n\n\tURL.revokeObjectURL(url)\n}\n\nfunction createId(): string {\n\treturn `transfer-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`\n}\n\nfunction toErrorMessage(caught: unknown): string {\n\treturn caught instanceof Error ? caught.message : String(caught)\n}\n\ntype ClientZipEntry = {\n\tpath: string\n\tarchivePath: string\n}\n\nasync function createClientZipUrl(adapter: FileBrowserAdapter, paths: string[]): Promise<string> {\n\tconst entries = await collectClientZipEntries(adapter, paths)\n\tconst zippable: Zippable = {}\n\n\tfor (const entry of entries) {\n\t\tconst url = await adapter.signedUrl(entry.path)\n\t\tconst response = await fetch(url)\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Could not fetch ${entry.path} for the client zip`)\n\t\t}\n\t\tzippable[entry.archivePath] = new Uint8Array(await response.arrayBuffer())\n\t}\n\n\tconst zip = zipSync(zippable)\n\treturn URL.createObjectURL(new Blob([zip], { type: 'application/zip' }))\n}\n\nasync function collectClientZipEntries(adapter: FileBrowserAdapter, paths: string[]): Promise<ClientZipEntry[]> {\n\tconst entries: ClientZipEntry[] = []\n\tconst seen = new Set<string>()\n\n\tfor (const path of paths) {\n\t\tawait collectClientZipPath(adapter, path, entries, seen)\n\t}\n\n\treturn entries\n}\n\nasync function collectClientZipPath(\n\tadapter: FileBrowserAdapter,\n\tpath: string,\n\tentries: ClientZipEntry[],\n\tseen: Set<string>\n): Promise<void> {\n\tif (seen.has(path)) {\n\t\treturn\n\t}\n\tseen.add(path)\n\n\tconst node = await tryStat(adapter, path)\n\tif (node?.kind === 'file') {\n\t\tentries.push({ path, archivePath: toArchivePath(path) })\n\t\treturn\n\t}\n\n\tif (node?.kind === 'folder') {\n\t\tawait collectClientZipFolder(adapter, path, entries, seen)\n\t\treturn\n\t}\n\n\tconst listed = await tryListFolder(adapter, path)\n\tif (listed) {\n\t\tfor (const item of listed) {\n\t\t\tawait collectClientZipPath(adapter, item.path, entries, seen)\n\t\t}\n\t\treturn\n\t}\n\n\tentries.push({ path, archivePath: toArchivePath(path) })\n}\n\nasync function collectClientZipFolder(\n\tadapter: FileBrowserAdapter,\n\tpath: string,\n\tentries: ClientZipEntry[],\n\tseen: Set<string>\n): Promise<void> {\n\tlet cursor: string | undefined\n\tdo {\n\t\tconst result = await adapter.list(path, { cursor })\n\t\tfor (const item of result.items) {\n\t\t\tawait collectClientZipPath(adapter, item.path, entries, seen)\n\t\t}\n\t\tcursor = result.cursor\n\t} while (cursor)\n}\n\nasync function tryStat(adapter: FileBrowserAdapter, path: string): Promise<FileNode | undefined> {\n\tif (!adapter.stat) {\n\t\treturn undefined\n\t}\n\n\ttry {\n\t\treturn await adapter.stat(path)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nasync function tryListFolder(adapter: FileBrowserAdapter, path: string): Promise<FileNode[] | undefined> {\n\ttry {\n\t\tlet cursor: string | undefined\n\t\tconst items: FileNode[] = []\n\t\tdo {\n\t\t\tconst result = await adapter.list(path, { cursor })\n\t\t\titems.push(...result.items)\n\t\t\tcursor = result.cursor\n\t\t} while (cursor)\n\t\treturn items\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nfunction toArchivePath(path: string): string {\n\treturn path.replace(/^\\/+/, '') || 'download'\n}\n","import { useEffect, useRef, useState } from 'react'\nimport type { MouseEvent, ReactNode, RefObject, TouchEvent } from 'react'\n\nexport function useNarrowViewport() {\n\tconst [narrow, setNarrow] = useState(false)\n\tuseEffect(() => {\n\t\tconst query = window.matchMedia?.('(max-width: 39.999rem)')\n\t\tif (!query) return\n\t\tconst update = () => setNarrow(query.matches)\n\t\tupdate()\n\t\tquery.addEventListener('change', update)\n\t\treturn () => query.removeEventListener('change', update)\n\t}, [])\n\treturn narrow\n}\n\nexport function useBrowserLayout(ref: RefObject<HTMLElement | null>) {\n\tconst [width, setWidth] = useState<number | null>(null)\n\tconst [rem, setRem] = useState(16)\n\n\tuseEffect(() => {\n\t\tconst element = ref.current\n\t\tif (!element) return\n\n\t\tconst measure = (nextWidth = element.clientWidth) => {\n\t\t\tsetRem(Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16)\n\t\t\tif (nextWidth > 0) setWidth(nextWidth)\n\t\t}\n\t\tmeasure()\n\t\tconst observer =\n\t\t\ttypeof ResizeObserver === 'undefined'\n\t\t\t\t? undefined\n\t\t\t\t: new ResizeObserver(([entry]) => measure(entry.contentRect.width))\n\t\tobserver?.observe(element)\n\t\tconst onResize = () => measure()\n\t\twindow.addEventListener('resize', onResize)\n\t\treturn () => {\n\t\t\tobserver?.disconnect()\n\t\t\twindow.removeEventListener('resize', onResize)\n\t\t}\n\t}, [ref])\n\n\treturn {\n\t\tisNarrow: width !== null && width < 40 * rem,\n\t\thasSidebar: width === null || width >= 64 * rem\n\t}\n}\n\nexport function useLongPress(onLongPress: () => void) {\n\tconst timer = useRef<ReturnType<typeof setTimeout> | null>(null)\n\tconst pressed = useRef(false)\n\tconst callback = useRef(onLongPress)\n\tcallback.current = onLongPress\n\n\tfunction cancel() {\n\t\tif (timer.current !== null) clearTimeout(timer.current)\n\t\ttimer.current = null\n\t}\n\n\tuseEffect(() => cancel, [])\n\n\treturn {\n\t\tonTouchStart(event: TouchEvent) {\n\t\t\tcancel()\n\t\t\tpressed.current = false\n\t\t\tif (event.touches?.length > 1 || (event.target as Element).closest('input, [data-fb-touch-control]')) return\n\t\t\ttimer.current = setTimeout(() => {\n\t\t\t\ttimer.current = null\n\t\t\t\tpressed.current = true\n\t\t\t\tcallback.current()\n\t\t\t}, 500)\n\t\t},\n\t\tonTouchMove: cancel,\n\t\tonTouchCancel() {\n\t\t\tcancel()\n\t\t\tpressed.current = false\n\t\t},\n\t\tonTouchEnd() {\n\t\t\tcancel()\n\t\t\tif (pressed.current) {\n\t\t\t\ttimer.current = setTimeout(() => {\n\t\t\t\t\ttimer.current = null\n\t\t\t\t\tpressed.current = false\n\t\t\t\t}, 350)\n\t\t\t}\n\t\t},\n\t\tonClickCapture(event: MouseEvent) {\n\t\t\tif (!pressed.current) return\n\t\t\tcancel()\n\t\t\tpressed.current = false\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t},\n\t\tonContextMenuCapture(event: MouseEvent) {\n\t\t\tif (pressed.current) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tevent.stopPropagation()\n\t\t\t}\n\t\t}\n\t}\n}\n\nconst FOCUSABLE =\n\t'button:not(:disabled), a[href], input:not(:disabled):not([type=\"hidden\"]), select:not(:disabled), textarea:not(:disabled), [tabindex=\"0\"]'\n\nexport function ResponsiveDialog({\n\tchildren,\n\tlabel,\n\tnarrow = false,\n\tonClose\n}: {\n\tchildren: ReactNode\n\tlabel: string\n\tnarrow?: boolean\n\tonClose: () => void\n}) {\n\tconst ref = useRef<HTMLDivElement>(null)\n\tconst closeRef = useRef(onClose)\n\tcloseRef.current = onClose\n\n\tuseEffect(() => {\n\t\tconst previousFocus = document.activeElement\n\t\tconst dialog = ref.current\n\t\tif (!dialog?.contains(document.activeElement)) {\n\t\t\tconst input = dialog?.querySelector<HTMLElement>('input:not([type=\"hidden\"]):not([type=\"checkbox\"])')\n\t\t\t;(input ?? dialog)?.focus({ preventScroll: true })\n\t\t}\n\t\treturn () => {\n\t\t\tif (previousFocus instanceof HTMLElement && previousFocus.isConnected) {\n\t\t\t\tpreviousFocus.focus({ preventScroll: true })\n\t\t\t}\n\t\t}\n\t}, [])\n\n\treturn (\n\t\t// oxlint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- A dialog owns focus trapping and backdrop dismissal.\n\t\t<div\n\t\t\taria-label={label}\n\t\t\taria-modal=\"true\"\n\t\t\tclassName={`fixed inset-0 z-[60] flex min-w-0 justify-center overflow-y-auto overscroll-contain bg-[color-mix(in_oklch,var(--fb-text)_20%,transparent)] p-[calc(var(--fb-gap)*3)] text-[var(--fb-text)] outline-none [overflow-wrap:anywhere] ${\n\t\t\t\tnarrow ? 'items-end' : 'items-center'\n\t\t\t}`}\n\t\t\tdata-fb-dialog={narrow ? 'sheet' : 'modal'}\n\t\t\tonClick={(event) => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tif (event.target === event.currentTarget) closeRef.current()\n\t\t\t}}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tcloseRef.current()\n\t\t\t\t}\n\t\t\t\tif (event.key !== 'Tab') return\n\t\t\t\tconst targets = Array.from(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? []).filter(\n\t\t\t\t\t(element) => !element.closest('[hidden]') && getComputedStyle(element).display !== 'none'\n\t\t\t\t)\n\t\t\t\tconst first = targets[0]\n\t\t\t\tconst last = targets.at(-1)\n\t\t\t\tif (!first) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tref.current?.focus()\n\t\t\t\t} else if (event.shiftKey && (document.activeElement === first || document.activeElement === ref.current)) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tlast?.focus()\n\t\t\t\t} else if (!event.shiftKey && document.activeElement === last) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirst.focus()\n\t\t\t\t}\n\t\t\t}}\n\t\t\tref={ref}\n\t\t\trole=\"dialog\"\n\t\t\tstyle={{\n\t\t\t\tpaddingBottom: 'max(calc(var(--fb-gap) * 3), env(safe-area-inset-bottom))',\n\t\t\t\tpaddingTop: 'max(calc(var(--fb-gap) * 3), env(safe-area-inset-top))'\n\t\t\t}}\n\t\t\ttabIndex={-1}\n\t\t>\n\t\t\t<div className=\"flex max-h-[calc(100dvh-max(calc(var(--fb-gap)*6),env(safe-area-inset-bottom)+env(safe-area-inset-top)))] w-full min-w-0 max-w-[calc(var(--fb-gap)*180)] flex-col items-center overflow-y-auto overscroll-contain [scrollbar-gutter:stable] [&>*]:shrink-0\">\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport function ActionSheet({ children, label, onClose }: { children: ReactNode; label: string; onClose: () => void }) {\n\treturn (\n\t\t<ResponsiveDialog label={label} narrow onClose={onClose}>\n\t\t\t<section className=\"w-full min-w-0 max-w-[calc(var(--fb-gap)*120)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-[calc(var(--fb-gap)*4)]\">\n\t\t\t\t<header className=\"mb-[calc(var(--fb-gap)*3)] flex items-center justify-between gap-[calc(var(--fb-gap)*2)]\">\n\t\t\t\t\t<h2 className=\"min-w-0 font-semibold\">{label}</h2>\n\t\t\t\t\t<button\n\t\t\t\t\t\taria-label={`Close ${label}`}\n\t\t\t\t\t\tclassName=\"min-h-[calc(var(--fb-gap)*11)] shrink-0 rounded-[var(--fb-radius)] px-[calc(var(--fb-gap)*3)] text-[var(--fb-accent)] focus-visible:outline-2 focus-visible:outline-[var(--fb-accent)]\"\n\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\tClose\n\t\t\t\t\t</button>\n\t\t\t\t</header>\n\t\t\t\t{children}\n\t\t\t</section>\n\t\t</ResponsiveDialog>\n\t)\n}\n","import { ChevronDown, ChevronUp, Download, Pause, Play, X } from 'lucide-react'\nimport { createContext, useContext, useEffect, useState, useSyncExternalStore } from 'react'\nimport type { PropsWithChildren } from 'react'\nimport { createPortal } from 'react-dom'\nimport { TransferManager } from './transfer-manager'\nimport { ResponsiveDialog, useNarrowViewport } from '../components/responsive'\nimport type {\n\tBulkDownloadJob,\n\tResumeRestoredUploadInput,\n\tTransferManagerOptions,\n\tTransferSnapshot,\n\tUploadTransfer,\n\tUploadTransferGroup\n} from './transfer-manager'\n\nconst TransferContext = createContext<TransferManager | null>(null)\nconst WIDGET_CONTROL_MOTION =\n\t'transition-[background-color,border-color,color,box-shadow,opacity] duration-150 ease-out motion-reduce:transition-none'\nconst WIDGET_SURFACE_MOTION =\n\t'transition-[background-color,border-color,box-shadow,opacity] duration-200 ease-out motion-reduce:transition-none'\nconst WIDGET_TOUCH_CONTROL =\n\t'min-h-[calc(var(--fb-gap)*11)] min-w-[calc(var(--fb-gap)*11)] shrink-0 whitespace-nowrap sm:min-h-7 sm:min-w-7 [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:min-w-[calc(var(--fb-gap)*11)]'\n\nexport type FileBrowserProviderProps = PropsWithChildren<{\n\tmanager?: TransferManager\n\toptions?: TransferManagerOptions\n\tresolveRestoredUpload?: (\n\t\tupload: UploadTransfer\n\t) => Omit<ResumeRestoredUploadInput, 'id'> | Promise<Omit<ResumeRestoredUploadInput, 'id'> | undefined> | undefined\n\tshowFloatingWidget?: boolean\n}>\n\nexport function FileBrowserProvider({\n\tchildren,\n\tmanager,\n\toptions,\n\tresolveRestoredUpload,\n\tshowFloatingWidget = true\n}: FileBrowserProviderProps) {\n\tconst [providerManager] = useState(() => manager ?? new TransferManager(withDefaultStorage(options)))\n\tconst transferManager = manager ?? providerManager\n\tconst snapshot = useTransfersSnapshot(transferManager)\n\tconst [resumePromptDismissed, setResumePromptDismissed] = useState(false)\n\tconst restorableUploads = transferManager.getRestorableUploads()\n\n\tuseBeforeUnloadGuard(transferManager)\n\n\tasync function resumeRestoredUploads(uploads: UploadTransfer[]) {\n\t\tfor (const upload of uploads) {\n\t\t\tif (upload.adapter && upload.file) {\n\t\t\t\tawait transferManager.resumeUpload(upload.id)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst resolved = await resolveRestoredUpload?.(upload)\n\t\t\tif (resolved) {\n\t\t\t\tawait transferManager.resumeRestoredUpload({\n\t\t\t\t\tid: upload.id,\n\t\t\t\t\t...resolved\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tsetResumePromptDismissed(true)\n\t}\n\n\treturn (\n\t\t<TransferContext.Provider value={transferManager}>\n\t\t\t{children}\n\t\t\t{showFloatingWidget ? <FloatingTransferWidget manager={transferManager} snapshot={snapshot} /> : null}\n\t\t\t{!resumePromptDismissed && restorableUploads.length > 0 ? (\n\t\t\t\t<ResumeUploadsPrompt\n\t\t\t\t\tcount={restorableUploads.length}\n\t\t\t\t\tonDismiss={() => {\n\t\t\t\t\t\ttransferManager.dismissRestoredUploads(restorableUploads.map((upload) => upload.id))\n\t\t\t\t\t\tsetResumePromptDismissed(true)\n\t\t\t\t\t}}\n\t\t\t\t\tonResume={() => {\n\t\t\t\t\t\tvoid resumeRestoredUploads(restorableUploads)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</TransferContext.Provider>\n\t)\n}\n\nexport function useTransfers(): TransferManager {\n\tconst manager = useContext(TransferContext)\n\treturn manager ?? fallbackTransferManager\n}\n\nexport function useTransferSnapshot(): TransferSnapshot {\n\treturn useTransfersSnapshot(useTransfers())\n}\n\nfunction useTransfersSnapshot(manager: TransferManager): TransferSnapshot {\n\treturn useSyncExternalStore(\n\t\t(listener) => manager.subscribe(listener),\n\t\t() => manager.getSnapshot(),\n\t\t() => ({ uploads: [], downloads: [] })\n\t)\n}\n\nfunction useBeforeUnloadGuard(manager: TransferManager): void {\n\tuseEffect(() => {\n\t\tconst listener = (event: BeforeUnloadEvent) => {\n\t\t\tif (!manager.hasActiveTransfers()) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tevent.preventDefault()\n\t\t\tevent.returnValue = ''\n\t\t}\n\t\twindow.addEventListener('beforeunload', listener)\n\t\treturn () => window.removeEventListener('beforeunload', listener)\n\t}, [manager])\n}\n\nfunction withDefaultStorage(options: TransferManagerOptions | undefined): TransferManagerOptions {\n\tif (options?.storage !== undefined) {\n\t\treturn options\n\t}\n\n\tconst storage = typeof window === 'undefined' ? undefined : window.localStorage\n\tif (!storage) {\n\t\treturn options ?? {}\n\t}\n\n\treturn {\n\t\t...options,\n\t\tstorage\n\t}\n}\n\nfunction FloatingTransferWidget({ manager, snapshot }: { manager: TransferManager; snapshot: TransferSnapshot }) {\n\tconst narrow = useNarrowViewport()\n\tconst [expanded, setExpanded] = useState<boolean | null>(null)\n\tconst isExpanded = expanded ?? !narrow\n\tconst activeUploads = snapshot.uploads.filter(isVisibleUpload)\n\tconst uploadGroups = getActiveUploadGroups(snapshot.uploads)\n\tconst groupedUploadIds = new Set(uploadGroups.flatMap((group) => group.activeUploads.map((upload) => upload.id)))\n\tconst standaloneUploads = activeUploads.filter((upload) => !groupedUploadIds.has(upload.id))\n\tconst downloads = snapshot.downloads.filter((download) =>\n\t\t['preparing', 'warning', 'ready', 'failed'].includes(download.status)\n\t)\n\n\tif (activeUploads.length === 0 && downloads.length === 0) {\n\t\treturn null\n\t}\n\n\tconst content = (\n\t\t<aside\n\t\t\taria-label=\"Transfers\"\n\t\t\tclassName={`fixed bottom-[calc(env(safe-area-inset-bottom)+var(--fb-gap)*28)] right-[max(calc(var(--fb-gap)*3),env(safe-area-inset-right))] z-50 flex max-h-[50dvh] max-w-[calc(100%-var(--fb-gap)*6)] flex-col rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-[calc(var(--fb-gap)*3)] text-[12px] text-[var(--fb-text)] shadow-[0_16px_44px_color-mix(in_oklch,var(--fb-text)_16%,transparent)] sm:bottom-[calc(env(safe-area-inset-bottom)+var(--fb-gap)*4)] ${isExpanded ? 'w-[calc(var(--fb-gap)*90)]' : 'w-auto'} ${WIDGET_SURFACE_MOTION}`}\n\t\t>\n\t\t\t<div className=\"flex shrink-0 items-center justify-between gap-2\">\n\t\t\t\t<div className=\"font-semibold\">Transfers</div>\n\t\t\t\t<div className=\"text-[11px] text-[var(--fb-muted)]\">{activeUploads.length + downloads.length} active</div>\n\t\t\t\t<button\n\t\t\t\t\taria-expanded={isExpanded}\n\t\t\t\t\taria-label={isExpanded ? 'Collapse transfers' : 'Expand transfers'}\n\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\tonClick={() => setExpanded(!isExpanded)}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t{isExpanded ? (\n\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<ChevronUp aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t{isExpanded ? (\n\t\t\t\t<div className=\"mt-2 flex min-h-0 min-w-0 flex-col gap-2 overflow-y-auto overscroll-contain [overflow-wrap:anywhere]\">\n\t\t\t\t\t{uploadGroups.map((group) => (\n\t\t\t\t\t\t<UploadGroupCard group={group} key={group.group.id} manager={manager} />\n\t\t\t\t\t))}\n\t\t\t\t\t{standaloneUploads.map((upload) => (\n\t\t\t\t\t\t<UploadTransferRow key={upload.id} manager={manager} upload={upload} />\n\t\t\t\t\t))}\n\t\t\t\t\t{downloads.map((download) => (\n\t\t\t\t\t\t<div className=\"text-[11px] text-[var(--fb-muted)]\" key={download.id}>\n\t\t\t\t\t\t\t{download.status === 'ready' && download.url ? (\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-between gap-2\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\taria-label=\"Open prepared download\"\n\t\t\t\t\t\t\t\t\t\tclassName={`inline-flex min-h-[calc(var(--fb-gap)*11)] min-w-0 items-center gap-1 rounded-[calc(var(--fb-radius)-4px)] px-1.5 py-1 font-medium text-[var(--fb-accent)] hover:bg-[var(--fb-accent-soft)] sm:min-h-7 [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] ${WIDGET_CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\t\tdownload\n\t\t\t\t\t\t\t\t\t\thref={download.url}\n\t\t\t\t\t\t\t\t\t\tonClick={() => manager.dismissDownload(download.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Download aria-hidden=\"true\" className=\"size-3.5 shrink-0\" />\n\t\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{formatDownloadReadyLabel(download)}</span>\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\taria-label=\"Dismiss download\"\n\t\t\t\t\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\t\t\t\t\tonClick={() => manager.dismissDownload(download.id)}\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{download.status === 'warning' ? (\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-between gap-2\">\n\t\t\t\t\t\t\t\t\t<span>Large client zip</span>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\tclassName={widgetTextButton()}\n\t\t\t\t\t\t\t\t\t\tonClick={() => void manager.confirmBulkDownload(download.id)}\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{download.status === 'preparing' ? <span>Preparing zip</span> : null}\n\t\t\t\t\t\t\t{download.status === 'failed' ? (\n\t\t\t\t\t\t\t\t<span className=\"text-[var(--fb-danger)]\">{download.error ?? 'Download failed'}</span>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</aside>\n\t)\n\n\treturn createPortal(content, document.body)\n}\n\ntype ActiveUploadGroup = {\n\tgroup: UploadTransferGroup\n\tuploads: UploadTransfer[]\n\tactiveUploads: UploadTransfer[]\n\tcompletedCount: number\n}\n\nfunction UploadGroupCard({ group, manager }: { group: ActiveUploadGroup; manager: TransferManager }) {\n\treturn (\n\t\t<div className={WIDGET_SURFACE_MOTION}>\n\t\t\t<div className=\"flex items-center justify-between gap-2\">\n\t\t\t\t<div className=\"min-w-0\">\n\t\t\t\t\t<div className=\"truncate font-semibold\">Uploading {group.group.name}</div>\n\t\t\t\t\t<div className=\"text-[11px] text-[var(--fb-muted)]\">{formatUploadGroupSummary(group)}</div>\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\taria-label={`Cancel upload group ${group.group.name}`}\n\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tfor (const upload of group.activeUploads) {\n\t\t\t\t\t\t\tvoid manager.cancelUpload(upload.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t\ttitle=\"Cancel\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<X aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div className={`mt-2 flex flex-col gap-1.5 border-l border-[var(--fb-border)] pl-3 ${WIDGET_SURFACE_MOTION}`}>\n\t\t\t\t{group.activeUploads.map((upload) => (\n\t\t\t\t\t<UploadTransferRow compact key={upload.id} manager={manager} upload={upload} />\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction UploadTransferRow({\n\tcompact = false,\n\tmanager,\n\tupload\n}: {\n\tcompact?: boolean\n\tmanager: TransferManager\n\tupload: UploadTransfer\n}) {\n\treturn (\n\t\t<div className={WIDGET_SURFACE_MOTION}>\n\t\t\t<div className=\"flex items-center justify-between gap-2\">\n\t\t\t\t<div className=\"min-w-0\">\n\t\t\t\t\t<span className=\"block truncate font-medium\">{upload.name}</span>\n\t\t\t\t\t<span className=\"text-[11px] text-[var(--fb-muted)]\">{formatUploadStatus(upload)}</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"flex shrink-0 items-center gap-1\">\n\t\t\t\t\t{['queued', 'uploading'].includes(upload.status) ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label={`Pause upload ${upload.name}`}\n\t\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\t\tonClick={() => manager.pauseUpload(upload.id)}\n\t\t\t\t\t\t\ttitle=\"Pause\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Pause aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{['failed', 'paused'].includes(upload.status) ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label={`Resume upload ${upload.name}`}\n\t\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\t\tonClick={() => void manager.resumeUpload(upload.id)}\n\t\t\t\t\t\t\ttitle=\"Resume\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Play aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<button\n\t\t\t\t\t\taria-label={`Cancel upload ${upload.name}`}\n\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\tonClick={() => void manager.cancelUpload(upload.id)}\n\t\t\t\t\t\ttitle=\"Cancel\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<X aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclassName={`h-1.5 overflow-hidden rounded-full bg-[var(--fb-surface-2)] ${WIDGET_SURFACE_MOTION} ${\n\t\t\t\t\tcompact ? 'mt-1' : 'mt-1.5'\n\t\t\t\t}`}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"h-full rounded-full bg-[var(--fb-accent)] transition-[width] duration-300 ease-out motion-reduce:transition-none\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: `${Math.min(100, upload.totalBytes ? (upload.loadedBytes / upload.totalBytes) * 100 : 0)}%`\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction ResumeUploadsPrompt({\n\tcount,\n\tonDismiss,\n\tonResume\n}: {\n\tcount: number\n\tonDismiss: () => void\n\tonResume: () => void\n}) {\n\tconst narrow = useNarrowViewport()\n\treturn createPortal(\n\t\t<ResponsiveDialog label=\"Resume uploads\" narrow={narrow} onClose={onDismiss}>\n\t\t\t<div\n\t\t\t\tclassName={`w-[min(380px,100%)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 shadow-[0_18px_50px_color-mix(in_oklch,var(--fb-text)_18%,transparent)] ${WIDGET_SURFACE_MOTION}`}\n\t\t\t>\n\t\t\t\t<h2 className=\"m-0 text-[14px] font-semibold\">Resume uploads</h2>\n\t\t\t\t<p className=\"mt-2 text-[12px] text-[var(--fb-muted)]\">\n\t\t\t\t\tResume {count} upload{count === 1 ? '?' : 's?'}\n\t\t\t\t</p>\n\t\t\t\t<div className=\"mt-4 flex flex-wrap justify-end gap-2\">\n\t\t\t\t\t<button className={widgetTextButton()} onClick={onDismiss} type=\"button\">\n\t\t\t\t\t\tDismiss\n\t\t\t\t\t</button>\n\t\t\t\t\t<button className={widgetPrimaryButton()} onClick={onResume} type=\"button\">\n\t\t\t\t\t\tResume uploads\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</ResponsiveDialog>,\n\t\tdocument.body\n\t)\n}\n\nconst fallbackTransferManager = new TransferManager()\n\nfunction widgetIconButton() {\n\treturn `grid size-7 place-items-center rounded-[calc(var(--fb-radius)-4px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] text-[var(--fb-muted)] outline-none hover:bg-[var(--fb-bg)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${WIDGET_TOUCH_CONTROL} ${WIDGET_CONTROL_MOTION}`\n}\n\nfunction widgetTextButton() {\n\treturn `inline-flex h-7 items-center justify-center rounded-[calc(var(--fb-radius)-4px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] px-2 text-[11px] font-medium text-[var(--fb-text)] outline-none hover:bg-[var(--fb-bg)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${WIDGET_TOUCH_CONTROL} ${WIDGET_CONTROL_MOTION}`\n}\n\nfunction widgetPrimaryButton() {\n\treturn `inline-flex h-7 items-center justify-center rounded-[calc(var(--fb-radius)-4px)] border border-[var(--fb-accent)] bg-[var(--fb-accent)] px-2 text-[11px] font-semibold text-[var(--fb-surface)] outline-none hover:opacity-90 focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${WIDGET_TOUCH_CONTROL} ${WIDGET_CONTROL_MOTION}`\n}\n\nfunction isVisibleUpload(upload: UploadTransfer): boolean {\n\treturn ['queued', 'uploading', 'failed', 'paused'].includes(upload.status)\n}\n\nfunction getActiveUploadGroups(uploads: UploadTransfer[]): ActiveUploadGroup[] {\n\tconst groups = new Map<string, ActiveUploadGroup>()\n\n\tfor (const upload of uploads) {\n\t\tif (!upload.group) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst existing = groups.get(upload.group.id) ?? {\n\t\t\tgroup: upload.group,\n\t\t\tuploads: [],\n\t\t\tactiveUploads: [],\n\t\t\tcompletedCount: 0\n\t\t}\n\t\texisting.uploads.push(upload)\n\t\tif (upload.status === 'completed') {\n\t\t\texisting.completedCount += 1\n\t\t}\n\t\tif (isVisibleUpload(upload)) {\n\t\t\texisting.activeUploads.push(upload)\n\t\t}\n\t\tgroups.set(upload.group.id, existing)\n\t}\n\n\treturn Array.from(groups.values()).filter((group) => group.activeUploads.length > 0)\n}\n\nfunction formatUploadGroupSummary(group: ActiveUploadGroup): string {\n\tconst folders = group.group.createdFolders\n\tconst files = `${group.completedCount} of ${group.group.totalFiles} files`\n\tif (folders <= 0) {\n\t\treturn files\n\t}\n\n\treturn `${files}, ${folders} folder${folders === 1 ? '' : 's'} created`\n}\n\nfunction formatUploadStatus(upload: UploadTransfer): string {\n\tif (\n\t\tupload.status !== 'uploading' ||\n\t\ttypeof upload.bytesPerSecond !== 'number' ||\n\t\t!Number.isFinite(upload.bytesPerSecond) ||\n\t\tupload.bytesPerSecond <= 0\n\t) {\n\t\treturn upload.status\n\t}\n\n\treturn `${upload.status}, ${formatTransferBytes(upload.bytesPerSecond)}/s`\n}\n\nfunction formatTransferBytes(bytes: number): string {\n\tconst units = ['B', 'KB', 'MB', 'GB', 'TB']\n\tlet value = Math.max(0, bytes)\n\tlet unitIndex = 0\n\n\twhile (value >= 1024 && unitIndex < units.length - 1) {\n\t\tvalue /= 1024\n\t\tunitIndex += 1\n\t}\n\n\tconst formatted = unitIndex === 0 || value >= 10 ? Math.round(value).toString() : value.toFixed(1)\n\treturn `${formatted} ${units[unitIndex]}`\n}\n\nfunction formatDownloadReadyLabel(download: BulkDownloadJob): string {\n\tconst expiresIn = download.expiresAt ? formatExpiresIn(download.expiresAt) : undefined\n\n\treturn expiresIn ? `Download ready, expires in ${expiresIn}` : 'Download ready'\n}\n\nfunction formatExpiresIn(expiresAt: string): string | undefined {\n\tconst remainingMs = Date.parse(expiresAt) - Date.now()\n\tif (!Number.isFinite(remainingMs) || remainingMs <= 0) {\n\t\treturn undefined\n\t}\n\n\tif (remainingMs < 60 * 60 * 1000) {\n\t\treturn `${Math.ceil(remainingMs / (60 * 1000))}m`\n\t}\n\n\tif (remainingMs < 24 * 60 * 60 * 1000) {\n\t\treturn `${Math.ceil(remainingMs / (60 * 60 * 1000))}h`\n\t}\n\n\treturn `${Math.ceil(remainingMs / (24 * 60 * 60 * 1000))}d`\n}\n","import {\n\tCheckSquare,\n\tChevronLeft,\n\tChevronRight,\n\tCopy as CopyIcon,\n\tDownload,\n\tFile,\n\tFolder,\n\tFolderInput,\n\tGrid2X2,\n\tInfo,\n\tList,\n\tMoreHorizontal,\n\tPencil,\n\tScissors,\n\tSearch,\n\tSquare,\n\tTrash2,\n\tUpload,\n\tX as XIcon\n} from 'lucide-react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { CSSProperties, DragEvent, KeyboardEvent, MouseEvent, ReactNode } from 'react'\nimport Selecto from 'react-selecto'\nimport type { OnSelect } from 'react-selecto'\nimport type { FileBrowserDensity } from '../theme'\nimport { useFileBrowser } from '../core/use-file-browser'\nimport type {\n\tFileBrowserPathChangeContext,\n\tFileBrowserUploadConflictResolution,\n\tFileBrowserView,\n\tUseFileBrowserResult\n} from '../core/use-file-browser'\nimport { getFileBrowserDirname, joinFileBrowserPath, normalizeFileBrowserPath } from '../core/path'\nimport { FileBrowserAdapterError, FileBrowserBulkActionError } from '../core/types'\nimport type { FileBrowserAdapter, FileNode } from '../core/types'\nimport { collectUploadCandidatesFromDataTransfer, getFileBrowserUploadCandidates } from '../core/upload-drop'\nimport type { FileBrowserUploadCandidate } from '../core/upload-drop'\nimport { useTransferSnapshot, useTransfers } from '../transfers/file-browser-provider'\nimport type { UploadTransferGroup } from '../transfers/transfer-manager'\nimport { ActionSheet, ResponsiveDialog, useBrowserLayout, useLongPress } from './responsive'\n\nexport type FileBrowserProps<TMetadata = unknown> = {\n\tadapter: FileBrowserAdapter<TMetadata>\n\tclassName?: string\n\temptyState?: {\n\t\ttitle: ReactNode\n\t\tdescription?: ReactNode\n\t}\n\tinitialPath?: string\n\tpath?: string\n\tonPathChange?: (path: string, context: FileBrowserPathChangeContext<TMetadata>) => void\n\trootLabel?: string\n\tsearchQuery?: string\n\tinitialSearchQuery?: string\n\tonSearchQueryChange?: (query: string) => void\n\tdensity?: FileBrowserDensity\n\treadOnly?: boolean\n\tshowDetailsPanel?: boolean\n\tuploadPolicy?: FileBrowserUploadPolicy\n\tuploadConflictResolutions?: readonly FileBrowserUploadConflictResolution[]\n\tallowClientZipFallback?: boolean\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\trenderDetailsContent?: (item: FileNode<TMetadata>, defaultContent: ReactNode) => ReactNode\n\twarnZipSizeBytes?: number\n}\n\nexport type FileBrowserUploadPolicy = {\n\tallowedMimeTypes?: string[]\n\tmaxFilesPerBatch?: number\n\tmaxFileSizeBytes?: number\n\tremainingQuotaBytes?: number\n\tvalidate?: (\n\t\tcandidate: FileBrowserUploadCandidate,\n\t\tcontext: {\n\t\t\tacceptedBytes: number\n\t\t\tcurrentPath: string\n\t\t}\n\t) => string | string[] | null | undefined\n}\n\nexport type FileBrowserUploadRejection = {\n\tfileName: string\n\trelativePath: string\n\treasons: string[]\n}\n\ntype ContextMenuState<TMetadata = unknown> =\n\t| {\n\t\t\ttarget: 'item'\n\t\t\titem: FileNode<TMetadata>\n\t\t\tx: number\n\t\t\ty: number\n\t\t\tmode?: 'context' | 'sheet'\n\t }\n\t| {\n\t\t\ttarget: 'empty'\n\t\t\tx: number\n\t\t\ty: number\n\t\t\tmode?: 'context' | 'sheet'\n\t }\n\ntype UploadConflictQueue = {\n\tcandidates: FileBrowserUploadCandidate[]\n\tconflictPaths: string[]\n\tgroup?: UploadTransferGroup\n\tindex: number\n}\n\ntype MoveDestination = {\n\tpath: string\n\tname: string\n\tdepth: number\n}\n\ntype MoveDestinationStatus = 'idle' | 'loading' | 'ready' | 'error'\n\ntype PreviewState<TMetadata = unknown> = {\n\titem: FileNode<TMetadata>\n\tstatus: 'loading' | 'ready' | 'error'\n\turl?: string\n\terror?: string\n}\n\nconst FILE_BROWSER_DRAG_MIME = 'application/x.react-file-browser.paths'\nconst SELECTED_ITEM_DOUBLE_CLICK_WINDOW_MS = 220\nconst CLIPBOARD_NOTICE_DURATION_MS = 5000\nconst CONTROL_MOTION =\n\t'transition-[background-color,border-color,color,box-shadow,opacity] duration-150 ease-out motion-reduce:transition-none'\nconst TOUCH_CONTROL =\n\t'shrink-0 whitespace-nowrap [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:min-w-[calc(var(--fb-gap)*11)]'\nconst SURFACE_MOTION =\n\t'transition-[background-color,border-color,box-shadow,opacity] duration-200 ease-out motion-reduce:transition-none'\nconst DEFAULT_UPLOAD_CONFLICT_RESOLUTIONS = [\n\t'skip',\n\t'replace',\n\t'keep-both'\n] as const satisfies readonly FileBrowserUploadConflictResolution[]\n\n// Density drives layout scale through CSS variables set inline on the root, so the effect works for\n// every consumer without shipping global CSS. Classes below reference these vars (e.g. h-[var(--fb-control-h)]).\nconst DENSITY_STYLES: Record<FileBrowserDensity, CSSProperties> = {\n\tcomfortable: {\n\t\t'--fb-font': '13px',\n\t\t'--fb-control-h': '32px',\n\t\t'--fb-cell-x': '12px',\n\t\t'--fb-cell-y': '8px',\n\t\t'--fb-pad': '12px',\n\t\t'--fb-card-min': '150px',\n\t\t'--fb-card-minh': '132px',\n\t\t'--fb-card-pad': '8px',\n\t\t'--fb-thumb-h': '64px',\n\t\t'--fb-grid-gap': '12px',\n\t\t'--fb-panel-w': '18rem',\n\t\t'--fb-panel-pad': '16px'\n\t} as CSSProperties,\n\tcompact: {\n\t\t'--fb-font': '12px',\n\t\t'--fb-control-h': '28px',\n\t\t'--fb-cell-x': '10px',\n\t\t'--fb-cell-y': '6px',\n\t\t'--fb-pad': '8px',\n\t\t'--fb-card-min': '124px',\n\t\t'--fb-card-minh': '108px',\n\t\t'--fb-card-pad': '6px',\n\t\t'--fb-thumb-h': '48px',\n\t\t'--fb-grid-gap': '8px',\n\t\t'--fb-panel-w': '15rem',\n\t\t'--fb-panel-pad': '12px'\n\t} as CSSProperties\n}\n\nexport function FileBrowser<TMetadata = unknown>({\n\tadapter,\n\tclassName,\n\temptyState,\n\tinitialPath = '/',\n\tpath,\n\tonPathChange,\n\trootLabel = 'Files',\n\tsearchQuery,\n\tinitialSearchQuery,\n\tonSearchQueryChange,\n\tdensity = 'comfortable',\n\treadOnly = false,\n\tshowDetailsPanel = true,\n\tuploadPolicy,\n\tuploadConflictResolutions,\n\tallowClientZipFallback = true,\n\trenderItemMeta,\n\trenderDetailsContent,\n\twarnZipSizeBytes\n}: FileBrowserProps<TMetadata>) {\n\tconst browser = useFileBrowser<TMetadata>({\n\t\tadapter,\n\t\tinitialPath,\n\t\tpath,\n\t\tonPathChange,\n\t\tsearchQuery,\n\t\tinitialSearchQuery,\n\t\tonSearchQueryChange\n\t})\n\tconst transfers = useTransfers()\n\tconst transferSnapshot = useTransferSnapshot()\n\tconst [newFolderOpen, setNewFolderOpen] = useState(false)\n\tconst [newFolderName, setNewFolderName] = useState('')\n\tconst [newFolderError, setNewFolderError] = useState<string | null>(null)\n\tconst [renameItem, setRenameItem] = useState<FileNode<TMetadata> | null>(null)\n\tconst [renameValue, setRenameValue] = useState('')\n\tconst [renameError, setRenameError] = useState<string | null>(null)\n\tconst [inlineRenameItem, setInlineRenameItem] = useState<FileNode<TMetadata> | null>(null)\n\tconst [inlineRenameValue, setInlineRenameValue] = useState('')\n\tconst [inlineRenameError, setInlineRenameError] = useState<string | null>(null)\n\tconst [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false)\n\tconst [moveDialogOpen, setMoveDialogOpen] = useState(false)\n\tconst [bulkFailure, setBulkFailure] = useState<FileBrowserBulkActionError | null>(null)\n\tconst [moveDestination, setMoveDestination] = useState(path ?? initialPath)\n\tconst [moveDestinations, setMoveDestinations] = useState<MoveDestination[]>([])\n\tconst [moveDestinationStatus, setMoveDestinationStatus] = useState<MoveDestinationStatus>('idle')\n\tconst [moveDestinationError, setMoveDestinationError] = useState<string | null>(null)\n\tconst [contextMenu, setContextMenu] = useState<ContextMenuState<TMetadata> | null>(null)\n\tconst [uploadConflictQueue, setUploadConflictQueue] = useState<UploadConflictQueue | null>(null)\n\tconst [uploadRejections, setUploadRejections] = useState<FileBrowserUploadRejection[]>([])\n\tconst [applyUploadResolution, setApplyUploadResolution] = useState(false)\n\tconst [clipboardNotice, setClipboardNotice] = useState<string | null>(null)\n\tconst [dropActive, setDropActive] = useState(false)\n\tconst [folderDropTargetPath, setFolderDropTargetPath] = useState<string | null>(null)\n\tconst [preview, setPreview] = useState<PreviewState<TMetadata> | null>(null)\n\tconst rootRef = useRef<HTMLElement | null>(null)\n\tconst { isNarrow, hasSidebar } = useBrowserLayout(rootRef)\n\tconst [mobileSelectionPath, setMobileSelectionPath] = useState<string | null>(null)\n\tconst [toolbarOpen, setToolbarOpen] = useState(false)\n\tconst [detailsOpen, setDetailsOpen] = useState(false)\n\tconst [selectionActionsOpen, setSelectionActionsOpen] = useState(false)\n\tconst mobileSelection = isNarrow && mobileSelectionPath === browser.currentPath\n\tuseEffect(() => {\n\t\tsetMobileSelectionPath(null)\n\t\tsetSelectionActionsOpen(false)\n\t\tsetDetailsOpen(false)\n\t\tsetToolbarOpen(false)\n\t}, [browser.currentPath, isNarrow])\n\tconst uploadInputRef = useRef<HTMLInputElement | null>(null)\n\tconst draggedItemPathsRef = useRef<string[]>([])\n\tconst pendingSelectedItemUnselectRef = useRef<{\n\t\tpath: string\n\t\ttimeoutId: ReturnType<typeof setTimeout>\n\t} | null>(null)\n\tconst lastItemClickRef = useRef<{ path: string; timeMs: number } | null>(null)\n\tconst doubleClickOpenPathRef = useRef<string | null>(null)\n\tconst refreshedUploadIdsRef = useRef<Set<string>>(new Set())\n\tconst selected = browser.selectedItems.at(0) ?? null\n\tconst allowedUploadConflictResolutions = useMemo(\n\t\t() => normalizeUploadConflictResolutions(uploadConflictResolutions ?? DEFAULT_UPLOAD_CONFLICT_RESOLUTIONS),\n\t\t[uploadConflictResolutions]\n\t)\n\tconst supportsBulkDownload = browser.capabilities.bulkDownload || allowClientZipFallback\n\tconst canDownloadSelection = canDownloadItems(browser.selectedItems, supportsBulkDownload)\n\tconst previewFiles = useMemo(\n\t\t() => browser.filteredItems.filter((item) => item.kind === 'file'),\n\t\t[browser.filteredItems]\n\t)\n\tconst openPreview = useCallback(\n\t\tasync (item: FileNode<TMetadata>) => {\n\t\t\tsetPreview({ item, status: 'loading' })\n\t\t\ttry {\n\t\t\t\tconst url = await adapter.signedUrl(item.path)\n\t\t\t\tsetPreview((current) => (current?.item.path === item.path ? { item, status: 'ready', url } : current))\n\t\t\t} catch (error) {\n\t\t\t\tsetPreview((current) =>\n\t\t\t\t\tcurrent?.item.path === item.path ? { item, status: 'error', error: toErrorMessage(error) } : current\n\t\t\t\t)\n\t\t\t}\n\t\t},\n\t\t[adapter]\n\t)\n\tconst cancelPendingSelectedItemUnselect = useCallback(() => {\n\t\tif (!pendingSelectedItemUnselectRef.current) {\n\t\t\treturn\n\t\t}\n\n\t\tclearTimeout(pendingSelectedItemUnselectRef.current.timeoutId)\n\t\tpendingSelectedItemUnselectRef.current = null\n\t}, [])\n\tconst scheduleSelectedItemUnselect = useCallback(\n\t\t(path: string) => {\n\t\t\tcancelPendingSelectedItemUnselect()\n\t\t\tpendingSelectedItemUnselectRef.current = {\n\t\t\t\tpath,\n\t\t\t\ttimeoutId: setTimeout(() => {\n\t\t\t\t\tif (pendingSelectedItemUnselectRef.current?.path !== path) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tpendingSelectedItemUnselectRef.current = null\n\t\t\t\t\tbrowser.clearSelection()\n\t\t\t\t}, SELECTED_ITEM_DOUBLE_CLICK_WINDOW_MS)\n\t\t\t}\n\t\t},\n\t\t[browser, cancelPendingSelectedItemUnselect]\n\t)\n\tconst selectItemWithEvent = useCallback(\n\t\t(path: string, event: MouseEvent | KeyboardEvent) => {\n\t\t\tif (isNarrow) {\n\t\t\t\tif (mobileSelection) {\n\t\t\t\t\tbrowser.toggleSelection(path)\n\t\t\t\t} else {\n\t\t\t\t\tconst item = browser.filteredItems.find((candidate) => candidate.path === path)\n\t\t\t\t\tif (item?.kind === 'folder') void browser.open(item)\n\t\t\t\t\telse if (item) void openPreview(item)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst clickedAt = Date.now()\n\t\t\tconst previousClick = lastItemClickRef.current\n\t\t\tconst isFastRepeatClick =\n\t\t\t\tpreviousClick?.path === path && clickedAt - previousClick.timeMs <= SELECTED_ITEM_DOUBLE_CLICK_WINDOW_MS\n\n\t\t\tif ('detail' in event && event.detail > 1) {\n\t\t\t\tif (isFastRepeatClick) {\n\t\t\t\t\tcancelPendingSelectedItemUnselect()\n\t\t\t\t\tdoubleClickOpenPathRef.current = path\n\t\t\t\t}\n\t\t\t\tlastItemClickRef.current = { path, timeMs: clickedAt }\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdoubleClickOpenPathRef.current = null\n\t\t\tlastItemClickRef.current = { path, timeMs: clickedAt }\n\t\t\tselectWithEvent(browser, path, event, {\n\t\t\t\tcancelPendingSelectedItemUnselect,\n\t\t\t\tscheduleSelectedItemUnselect\n\t\t\t})\n\t\t},\n\t\t[browser, cancelPendingSelectedItemUnselect, isNarrow, mobileSelection, openPreview, scheduleSelectedItemUnselect]\n\t)\n\tconst openItemFromDoubleClick = useCallback(\n\t\t(item: FileNode<TMetadata>) => {\n\t\t\tif (isNarrow) return\n\t\t\tif (doubleClickOpenPathRef.current !== item.path) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdoubleClickOpenPathRef.current = null\n\t\t\tcancelPendingSelectedItemUnselect()\n\t\t\tif (item.kind === 'folder') {\n\t\t\t\tvoid browser.open(item)\n\t\t\t} else {\n\t\t\t\tvoid openPreview(item)\n\t\t\t}\n\t\t},\n\t\t[browser, cancelPendingSelectedItemUnselect, isNarrow, openPreview]\n\t)\n\tuseEffect(\n\t\t() => () => {\n\t\t\tcancelPendingSelectedItemUnselect()\n\t\t},\n\t\t[cancelPendingSelectedItemUnselect]\n\t)\n\tconst totalSelectedBytes = useMemo(\n\t\t() => browser.selectedItems.reduce((total, item) => total + (item.size ?? 0), 0),\n\t\t[browser.selectedItems]\n\t)\n\tconst moveKeyboardSelection = useCallback(\n\t\t(key: string, extendSelection: boolean) => {\n\t\t\tconst visibleItems = browser.filteredItems\n\t\t\tif (visibleItems.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst currentPath = browser.focusedPath ?? browser.selectedPaths.at(-1)\n\t\t\tconst currentIndex = visibleItems.findIndex((item) => item.path === currentPath)\n\t\t\tconst fallbackIndex = key === 'ArrowUp' || key === 'ArrowLeft' || key === 'End' ? visibleItems.length - 1 : 0\n\t\t\tconst nextIndex =\n\t\t\t\tcurrentIndex === -1 ? fallbackIndex : getNextKeyboardIndex(key, currentIndex, visibleItems.length)\n\t\t\tconst next = visibleItems[nextIndex]\n\n\t\t\tif (extendSelection) {\n\t\t\t\tbrowser.selectRange(next.path)\n\t\t\t} else {\n\t\t\t\tbrowser.selectOnly(next.path)\n\t\t\t}\n\t\t},\n\t\t[browser]\n\t)\n\tconst copySelectedItems = useCallback(\n\t\t(paths = browser.selectedPaths) => {\n\t\t\tif (paths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbrowser.copySelection(paths)\n\t\t\tsetClipboardNotice(`Copied ${formatItemCount(paths.length)}`)\n\t\t},\n\t\t[browser]\n\t)\n\tconst cutSelectedItems = useCallback(\n\t\t(paths = browser.selectedPaths) => {\n\t\t\tif (paths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbrowser.cutSelection(paths)\n\t\t\tsetClipboardNotice(`Cut ${formatItemCount(paths.length)}`)\n\t\t},\n\t\t[browser]\n\t)\n\tconst copyItemPaths = useCallback(async (paths: string[]) => {\n\t\tif (paths.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tawait navigator.clipboard.writeText(paths.join(', '))\n\t\tsetClipboardNotice(paths.length === 1 ? 'Copied path' : `Copied ${paths.length} paths`)\n\t}, [])\n\tconst pasteClipboardInto = useCallback(\n\t\tasync (toDir: string) => {\n\t\t\tconst pastedCount = browser.clipboard?.paths.length ?? 0\n\t\t\tawait browser.pasteInto(toDir)\n\t\t\tif (pastedCount > 0) {\n\t\t\t\tsetClipboardNotice(`Pasted ${formatItemCount(pastedCount)}`)\n\t\t\t}\n\t\t},\n\t\t[browser]\n\t)\n\n\tuseEffect(() => {\n\t\tconst listener = (event: globalThis.KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\tevent.defaultPrevented ||\n\t\t\t\t(event.target instanceof Element && event.target.closest('[role=\"dialog\"], [role=\"menu\"]'))\n\t\t\t)\n\t\t\t\treturn\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tbrowser.clearSelection()\n\t\t\t\tsetMobileSelectionPath(null)\n\t\t\t\tsetToolbarOpen(false)\n\t\t\t\tsetDetailsOpen(false)\n\t\t\t\tsetSelectionActionsOpen(false)\n\t\t\t\tsetInlineRenameItem(null)\n\t\t\t\tsetInlineRenameValue('')\n\t\t\t\tsetInlineRenameError(null)\n\t\t\t\tsetRenameItem(null)\n\t\t\t\tsetRenameError(null)\n\t\t\t\tsetNewFolderError(null)\n\t\t\t\tsetDeleteConfirmOpen(false)\n\t\t\t\tsetMoveDialogOpen(false)\n\t\t\t\tsetBulkFailure(null)\n\t\t\t\tsetContextMenu(null)\n\t\t\t\tsetUploadConflictQueue(null)\n\t\t\t\tsetPreview(null)\n\t\t\t}\n\t\t\tif (\n\t\t\t\tisEditableEventTarget(event.target) ||\n\t\t\t\t(event.target instanceof Element &&\n\t\t\t\t\t(event.target.closest('[data-fb-touch-control]') ||\n\t\t\t\t\t\t(event.key === 'Enter' && event.target.closest('button, a') && !event.target.closest('[data-fb-path]'))))\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (event.key === 'Enter' && isNarrow && mobileSelection) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tconst path =\n\t\t\t\t\tevent.target instanceof Element ? event.target.closest('[data-fb-path]')?.getAttribute('data-fb-path') : null\n\t\t\t\tif (path) browser.toggleSelection(path)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (isKeyboardNavigationKey(event.key)) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tmoveKeyboardSelection(event.key, event.shiftKey)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!readOnly && event.key === 'F2' && browser.capabilities.rename && browser.selectedItems.length === 1) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tconst item = browser.selectedItems[0]\n\t\t\t\tsetRenameItem(null)\n\t\t\t\tsetRenameError(null)\n\t\t\t\tsetInlineRenameItem(item)\n\t\t\t\tsetInlineRenameValue(item.name)\n\t\t\t\tsetInlineRenameError(null)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!readOnly && (event.key === 'Delete' || event.key === 'Backspace') && browser.selectedPaths.length > 0) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetDeleteConfirmOpen(true)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif ((event.metaKey || event.ctrlKey) && !readOnly) {\n\t\t\t\tconst key = event.key.toLowerCase()\n\t\t\t\tif (key === 'c' && browser.capabilities.copy && browser.selectedPaths.length > 0) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tcopySelectedItems()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (key === 'x' && browser.capabilities.move && browser.selectedPaths.length > 0) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tcutSelectedItems()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (key === 'v' && browser.clipboard) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tvoid pasteClipboardInto(browser.currentPath)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (event.key === 'Enter' && browser.selectedItems.length === 1) {\n\t\t\t\tconst item = browser.selectedItems[0]\n\t\t\t\tif (item.kind === 'folder') {\n\t\t\t\t\tvoid browser.open(item)\n\t\t\t\t} else {\n\t\t\t\t\tvoid openPreview(item)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'a') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tbrowser.selectAllLoaded()\n\t\t\t}\n\t\t}\n\t\tdocument.addEventListener('keydown', listener)\n\t\treturn () => document.removeEventListener('keydown', listener)\n\t}, [\n\t\tbrowser,\n\t\tcopySelectedItems,\n\t\tcutSelectedItems,\n\t\tisNarrow,\n\t\tmobileSelection,\n\t\tmoveKeyboardSelection,\n\t\topenPreview,\n\t\tpasteClipboardInto,\n\t\treadOnly\n\t])\n\n\tuseEffect(() => {\n\t\tif (!browser.focusedPath || rootRef.current?.querySelector('[role=\"dialog\"], [role=\"menu\"]')) {\n\t\t\treturn\n\t\t}\n\n\t\tconst item = rootRef.current?.querySelector<HTMLElement>(\n\t\t\t`[data-fb-path=\"${escapeAttributeSelector(browser.focusedPath)}\"]`\n\t\t)\n\t\titem?.focus()\n\t}, [browser.focusedPath, browser.filteredItems, browser.view])\n\n\tuseEffect(() => {\n\t\tif (!contextMenu) {\n\t\t\treturn\n\t\t}\n\t\tconst close = () => setContextMenu(null)\n\t\tdocument.addEventListener('click', close)\n\t\treturn () => document.removeEventListener('click', close)\n\t}, [contextMenu])\n\n\tuseEffect(() => {\n\t\tif (!clipboardNotice) {\n\t\t\treturn\n\t\t}\n\t\tconst timer = setTimeout(() => setClipboardNotice(null), CLIPBOARD_NOTICE_DURATION_MS)\n\t\treturn () => clearTimeout(timer)\n\t}, [clipboardNotice])\n\n\tuseEffect(() => {\n\t\tfor (const upload of transferSnapshot.uploads) {\n\t\t\tif (upload.status !== 'completed' || !upload.result || refreshedUploadIdsRef.current.has(upload.id)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\trefreshedUploadIdsRef.current.add(upload.id)\n\t\t\tif (getFileBrowserDirname(upload.result.path) === browser.currentPath) {\n\t\t\t\tvoid browser.refresh()\n\t\t\t}\n\t\t}\n\t}, [browser, transferSnapshot.uploads])\n\n\tuseEffect(() => {\n\t\tif (!moveDialogOpen) {\n\t\t\treturn\n\t\t}\n\n\t\tlet cancelled = false\n\n\t\tvoid Promise.resolve()\n\t\t\t.then(async () => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tsetMoveDestinationStatus('loading')\n\t\t\t\tsetMoveDestinationError(null)\n\t\t\t\treturn collectMoveDestinations(adapter, browser.selectedPaths)\n\t\t\t})\n\t\t\t.then((destinations) => {\n\t\t\t\tif (cancelled || destinations.length === 0) {\n\t\t\t\t\tif (!cancelled && destinations.length === 0) {\n\t\t\t\t\t\tsetMoveDestinations([])\n\t\t\t\t\t\tsetMoveDestinationStatus('ready')\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetMoveDestinations(destinations)\n\t\t\t\tsetMoveDestinationStatus('ready')\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetMoveDestinations([])\n\t\t\t\tsetMoveDestinationStatus('error')\n\t\t\t\tsetMoveDestinationError(toErrorMessage(error))\n\t\t\t})\n\n\t\treturn () => {\n\t\t\tcancelled = true\n\t\t}\n\t}, [adapter, browser.selectedPaths, moveDialogOpen])\n\n\tasync function createFolder() {\n\t\tif (!newFolderName.trim()) {\n\t\t\treturn\n\t\t}\n\t\tsetNewFolderError(null)\n\t\ttry {\n\t\t\tawait browser.createFolder(newFolderName)\n\t\t\tsetNewFolderName('')\n\t\t\tsetNewFolderOpen(false)\n\t\t} catch (error) {\n\t\t\tsetNewFolderError(toErrorMessage(error))\n\t\t}\n\t}\n\n\tfunction openRenameDialog(item = browser.selectedItems.at(0)) {\n\t\tif (!item) {\n\t\t\treturn\n\t\t}\n\t\tsetInlineRenameItem(null)\n\t\tsetInlineRenameValue('')\n\t\tsetInlineRenameError(null)\n\t\tsetRenameItem(item)\n\t\tsetRenameValue(item.name)\n\t\tsetRenameError(null)\n\t}\n\n\tasync function renameSelectedItem() {\n\t\tconst nextName = renameValue.trim()\n\t\tif (!renameItem || !nextName) {\n\t\t\treturn\n\t\t}\n\t\tsetRenameError(null)\n\t\ttry {\n\t\t\tawait browser.rename(renameItem.path, nextName)\n\t\t\tsetRenameItem(null)\n\t\t\tsetRenameValue('')\n\t\t} catch (error) {\n\t\t\tsetRenameError(toErrorMessage(error))\n\t\t}\n\t}\n\n\tasync function commitInlineRename() {\n\t\tconst item = inlineRenameItem\n\t\tconst nextName = inlineRenameValue.trim()\n\t\tsetInlineRenameError(null)\n\t\tif (!item || !nextName || nextName === item.name) {\n\t\t\tsetInlineRenameItem(null)\n\t\t\tsetInlineRenameValue('')\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tawait browser.rename(item.path, nextName)\n\t\t\tsetInlineRenameItem(null)\n\t\t\tsetInlineRenameValue('')\n\t\t} catch (error) {\n\t\t\tsetInlineRenameItem(item)\n\t\t\tsetInlineRenameValue(nextName)\n\t\t\tsetInlineRenameError(toErrorMessage(error))\n\t\t}\n\t}\n\n\tfunction cancelInlineRename() {\n\t\tsetInlineRenameItem(null)\n\t\tsetInlineRenameValue('')\n\t\tsetInlineRenameError(null)\n\t}\n\n\tasync function deleteSelectedItems() {\n\t\tsetDeleteConfirmOpen(false)\n\t\ttry {\n\t\t\tawait browser.deleteSelected()\n\t\t} catch (error) {\n\t\t\tif (error instanceof FileBrowserBulkActionError) {\n\t\t\t\tsetBulkFailure(error)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetDeleteConfirmOpen(true)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tfunction openMoveDialog() {\n\t\tif (browser.selectedPaths.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tsetMoveDestination(browser.currentPath)\n\t\tsetMoveDialogOpen(true)\n\t}\n\n\tasync function moveSelectedItems() {\n\t\ttry {\n\t\t\tawait browser.moveSelectedTo(moveDestination)\n\t\t\tsetMoveDialogOpen(false)\n\t\t} catch (error) {\n\t\t\tif (error instanceof FileBrowserBulkActionError) {\n\t\t\t\tsetMoveDialogOpen(false)\n\t\t\t\tsetBulkFailure(error)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tfunction startItemDrag(item: FileNode<TMetadata>, event: DragEvent) {\n\t\tif (readOnly || !browser.capabilities.move) {\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = browser.selectedPaths.includes(item.path) ? browser.selectedPaths : [item.path]\n\t\tdraggedItemPathsRef.current = paths\n\t\tsetDropActive(false)\n\t\tsetFolderDropTargetPath(null)\n\t\tbrowser.setSelection(paths)\n\t\tevent.dataTransfer.effectAllowed = 'move'\n\t\tevent.dataTransfer.setData(FILE_BROWSER_DRAG_MIME, JSON.stringify(paths))\n\t}\n\n\tfunction endItemDrag() {\n\t\tdraggedItemPathsRef.current = []\n\t\tsetDropActive(false)\n\t\tsetFolderDropTargetPath(null)\n\t}\n\n\tfunction getActiveDraggedPaths(dataTransfer: DataTransfer) {\n\t\tconst transferredPaths = getDraggedPaths(dataTransfer)\n\t\treturn transferredPaths.length > 0 ? transferredPaths : draggedItemPathsRef.current\n\t}\n\n\tfunction allowFolderDrop(item: FileNode<TMetadata>, event: DragEvent) {\n\t\tif (readOnly || !browser.capabilities.move || item.kind !== 'folder') {\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = getActiveDraggedPaths(event.dataTransfer)\n\t\tif (paths.length === 0 || paths.some((path) => item.path === path || item.path.startsWith(`${path}/`))) {\n\t\t\treturn\n\t\t}\n\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tevent.dataTransfer.dropEffect = 'move'\n\t\tsetDropActive(false)\n\t\tsetFolderDropTargetPath(item.path)\n\t}\n\n\tasync function moveDraggedItemsToFolder(item: FileNode<TMetadata>, event: DragEvent) {\n\t\tif (readOnly || !browser.capabilities.move || item.kind !== 'folder') {\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = getActiveDraggedPaths(event.dataTransfer)\n\t\tif (paths.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tendItemDrag()\n\t\ttry {\n\t\t\tawait browser.movePathsTo(paths, item.path)\n\t\t} catch (error) {\n\t\t\tif (error instanceof FileBrowserBulkActionError) {\n\t\t\t\tsetBulkFailure(error)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tfunction openItemContextMenu(item: FileNode<TMetadata>, event: MouseEvent) {\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tif (!browser.selectedPaths.includes(item.path)) {\n\t\t\tbrowser.selectOnly(item.path)\n\t\t}\n\t\tsetContextMenu({\n\t\t\ttarget: 'item',\n\t\t\titem,\n\t\t\tx: event.clientX,\n\t\t\ty: event.clientY,\n\t\t\tmode: isNarrow ? 'sheet' : 'context'\n\t\t})\n\t}\n\n\tfunction openItemTouchMenu(item: FileNode<TMetadata>) {\n\t\tif (!browser.selectedPaths.includes(item.path)) {\n\t\t\tbrowser.selectOnly(item.path)\n\t\t}\n\t\tif (isNarrow) {\n\t\t\tsetMobileSelectionPath(browser.currentPath)\n\t\t\treturn\n\t\t}\n\t\tsetContextMenu({\n\t\t\ttarget: 'item',\n\t\t\titem,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tmode: 'sheet'\n\t\t})\n\t}\n\n\tfunction openEmptyContextMenu(event: MouseEvent) {\n\t\tevent.preventDefault()\n\t\tbrowser.clearSelection()\n\t\tsetContextMenu({\n\t\t\ttarget: 'empty',\n\t\t\tx: event.clientX,\n\t\t\ty: event.clientY,\n\t\t\tmode: isNarrow ? 'sheet' : 'context'\n\t\t})\n\t}\n\n\tfunction clearSelectionFromEmptySurface(event: MouseEvent<HTMLElement>) {\n\t\tif (mobileSelection) return\n\t\tif (event.target !== event.currentTarget || hasSelectionModifier(event)) {\n\t\t\treturn\n\t\t}\n\t\tbrowser.clearSelection()\n\t}\n\n\tfunction showAdjacentPreview(direction: -1 | 1) {\n\t\tif (!preview || previewFiles.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst currentIndex = previewFiles.findIndex((item) => item.path === preview.item.path)\n\t\tconst safeIndex = currentIndex >= 0 ? currentIndex : 0\n\t\tconst nextIndex = (safeIndex + direction + previewFiles.length) % previewFiles.length\n\t\tconst next = previewFiles[nextIndex]\n\t\tvoid openPreview(next)\n\t\tbrowser.selectOnly(next.path)\n\t}\n\n\tasync function downloadSelection() {\n\t\tif (!canDownloadSelection) {\n\t\t\treturn\n\t\t}\n\n\t\tif (browser.selectedItems.length === 1 && browser.selectedItems[0].kind === 'file') {\n\t\t\tawait downloadItem(browser.selectedItems[0])\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = browser.selectedPaths\n\t\tawait downloadPaths(paths, totalSelectedBytes)\n\t}\n\n\tasync function downloadItem(item: FileNode<TMetadata>) {\n\t\tif (item.kind === 'file') {\n\t\t\tawait transfers.prepareSingleDownload({\n\t\t\t\tadapter,\n\t\t\t\tpath: item.path,\n\t\t\t\tselectedBytes: item.size ?? 0\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tif (supportsBulkDownload) {\n\t\t\tawait downloadPaths([item.path], item.size ?? 0)\n\t\t}\n\t}\n\n\tasync function downloadPaths(paths: string[], selectedBytes: number) {\n\t\tif (paths.length === 0 || !supportsBulkDownload) {\n\t\t\treturn\n\t\t}\n\n\t\tawait transfers.prepareBulkDownload({\n\t\t\tallowClientZipFallback,\n\t\t\tadapter,\n\t\t\tpaths,\n\t\t\tselectedBytes,\n\t\t\twarnZipSizeBytes\n\t\t})\n\t}\n\n\tasync function uploadInputFiles(files: FileList | null) {\n\t\tif (!files || files.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tawait beginUploadFiles(files)\n\t\tif (uploadInputRef.current) {\n\t\t\tuploadInputRef.current.value = ''\n\t\t}\n\t}\n\n\tasync function beginUploadFiles(files: File[] | FileList) {\n\t\tconst candidates = getFileBrowserUploadCandidates(files)\n\t\tawait beginUploadCandidates(candidates)\n\t}\n\n\tasync function beginUploadDrop(dataTransfer: DataTransfer) {\n\t\tconst candidates = await collectUploadCandidatesFromDataTransfer(dataTransfer)\n\t\tawait beginUploadCandidates(candidates)\n\t}\n\n\tasync function beginUploadCandidates(candidates: FileBrowserUploadCandidate[]) {\n\t\tif (candidates.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tif (uploadPolicy?.maxFilesPerBatch !== undefined && candidates.length > uploadPolicy.maxFilesPerBatch) {\n\t\t\tsetUploadRejections(\n\t\t\t\tcandidates.map((candidate) => ({\n\t\t\t\t\tfileName: candidate.file.name,\n\t\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\t\treasons: [`Batch contains ${candidates.length} files; maximum is ${uploadPolicy.maxFilesPerBatch}`]\n\t\t\t\t}))\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\tconst { acceptedCandidates, rejectedCandidates } = applyUploadPolicy(candidates, uploadPolicy, browser.currentPath)\n\t\tif (rejectedCandidates.length > 0) {\n\t\t\tsetUploadRejections(rejectedCandidates)\n\t\t}\n\t\tif (acceptedCandidates.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst supportedCandidates = rejectUnsupportedFolderUploads(acceptedCandidates)\n\t\tif (supportedCandidates.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst createdFolders = await ensureUploadFolders(supportedCandidates)\n\t\tconst conflictPaths = await findUploadConflictPaths(supportedCandidates)\n\t\tif (conflictPaths.length > 0 && allowedUploadConflictResolutions.length === 0) {\n\t\t\tconst conflicts = new Set(conflictPaths)\n\t\t\tconst nonConflictingCandidates = supportedCandidates.filter(\n\t\t\t\t(candidate) => !conflicts.has(joinUploadRelativePath(browser.currentPath, candidate.relativePath))\n\t\t\t)\n\t\t\tconst conflictingCandidates = supportedCandidates.filter((candidate) =>\n\t\t\t\tconflicts.has(joinUploadRelativePath(browser.currentPath, candidate.relativePath))\n\t\t\t)\n\t\t\tsetUploadRejections((current) => [\n\t\t\t\t...current,\n\t\t\t\t...conflictingCandidates.map((candidate) => ({\n\t\t\t\t\tfileName: candidate.file.name,\n\t\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\t\treasons: ['No upload conflict resolutions are enabled']\n\t\t\t\t}))\n\t\t\t])\n\t\t\tif (nonConflictingCandidates.length > 0) {\n\t\t\t\tconst group = getUploadTransferGroup(browser.currentPath, nonConflictingCandidates, createdFolders)\n\t\t\t\tprocessUploadQueue(nonConflictingCandidates, [], 0, undefined, group)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst group = getUploadTransferGroup(browser.currentPath, supportedCandidates, createdFolders)\n\t\tprocessUploadQueue(supportedCandidates, conflictPaths, 0, undefined, group)\n\t}\n\n\tfunction rejectUnsupportedFolderUploads(candidates: FileBrowserUploadCandidate[]) {\n\t\tif (browser.capabilities.createFolder) {\n\t\t\treturn candidates\n\t\t}\n\n\t\tconst [folderCandidates, flatCandidates] = partitionUploadCandidates(candidates, (candidate) =>\n\t\t\tcandidate.relativePath.includes('/')\n\t\t)\n\t\tif (folderCandidates.length > 0) {\n\t\t\tsetUploadRejections((current) => [\n\t\t\t\t...current,\n\t\t\t\t...folderCandidates.map((candidate) => ({\n\t\t\t\t\tfileName: candidate.file.name,\n\t\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\t\treasons: ['Folder uploads require folder creation support']\n\t\t\t\t}))\n\t\t\t])\n\t\t}\n\t\treturn flatCandidates\n\t}\n\n\tasync function ensureUploadFolders(candidates: FileBrowserUploadCandidate[]) {\n\t\tconst folders = getUploadFolderPaths(candidates)\n\t\tlet createdFolders = 0\n\n\t\tif (!adapter.createFolder) {\n\t\t\tif (folders.length > 0) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Folder uploads require folder creation support')\n\t\t\t}\n\t\t\treturn 0\n\t\t}\n\n\t\tfor (const folder of folders) {\n\t\t\ttry {\n\t\t\t\tawait adapter.createFolder(joinUploadRelativePath(browser.currentPath, folder))\n\t\t\t\tcreatedFolders += 1\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof FileBrowserAdapterError && error.code === 'conflict') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\n\t\tif (createdFolders > 0) {\n\t\t\tawait browser.refresh()\n\t\t}\n\t\treturn createdFolders\n\t}\n\n\tasync function findUploadConflictPaths(candidates: FileBrowserUploadCandidate[]) {\n\t\tconst paths = candidates.map((candidate) => joinUploadRelativePath(browser.currentPath, candidate.relativePath))\n\n\t\tif (adapter.exists) {\n\t\t\ttry {\n\t\t\t\tconst result = await adapter.exists(paths)\n\t\t\t\treturn paths.filter((path) => result[path])\n\t\t\t} catch {\n\t\t\t\t// Fall back to list lookups below.\n\t\t\t}\n\t\t}\n\n\t\tconst existingPaths = new Set(browser.items.map((item) => item.path))\n\t\tconst conflicts: string[] = []\n\t\tfor (const path of paths) {\n\t\t\tif (existingPaths.has(path) || (await uploadPathExistsByListing(path))) {\n\t\t\t\tconflicts.push(path)\n\t\t\t}\n\t\t}\n\t\treturn conflicts\n\t}\n\n\tasync function uploadPathExistsByListing(path: string): Promise<boolean> {\n\t\tconst parentPath = getFileBrowserDirname(path)\n\t\tlet cursor: string | undefined\n\n\t\tdo {\n\t\t\tconst result = await adapter.list(parentPath, { cursor })\n\t\t\tif (result.items.some((item) => item.path === path)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcursor = result.cursor\n\t\t} while (cursor)\n\n\t\treturn false\n\t}\n\n\tfunction processUploadQueue(\n\t\tcandidates: FileBrowserUploadCandidate[],\n\t\tconflictPaths: string[],\n\t\tstartIndex: number,\n\t\tresolution?: FileBrowserUploadConflictResolution,\n\t\tgroup?: UploadTransferGroup\n\t) {\n\t\tconst conflicts = new Set(conflictPaths)\n\n\t\tfor (let index = startIndex; index < candidates.length; index += 1) {\n\t\t\tconst candidate = candidates[index]\n\t\t\tconst path = joinUploadRelativePath(browser.currentPath, candidate.relativePath)\n\n\t\t\tif (conflicts.has(path)) {\n\t\t\t\tif (!resolution) {\n\t\t\t\t\tsetUploadConflictQueue({ candidates, conflictPaths, group, index })\n\t\t\t\t\tsetApplyUploadResolution(false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (resolution !== 'skip') {\n\t\t\t\t\tenqueueUploadTransfer(candidate, resolution, group)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tenqueueUploadTransfer(candidate, undefined, group)\n\t\t\t}\n\t\t}\n\n\t\tsetUploadConflictQueue(null)\n\t\tsetApplyUploadResolution(false)\n\t}\n\n\tfunction resolveUploadConflict(resolution: FileBrowserUploadConflictResolution) {\n\t\tif (!uploadConflictQueue || !allowedUploadConflictResolutions.includes(resolution)) {\n\t\t\treturn\n\t\t}\n\n\t\tconst { candidates, conflictPaths, group, index } = uploadConflictQueue\n\t\tif (applyUploadResolution) {\n\t\t\tprocessUploadQueue(candidates, conflictPaths, index, resolution, group)\n\t\t\treturn\n\t\t}\n\n\t\tconst candidate = candidates[index]\n\t\tif (resolution !== 'skip') {\n\t\t\tenqueueUploadTransfer(candidate, resolution, group)\n\t\t}\n\t\tprocessUploadQueue(candidates, conflictPaths, index + 1, undefined, group)\n\t}\n\n\tfunction enqueueUploadTransfer(\n\t\tcandidate: FileBrowserUploadCandidate,\n\t\tresolution?: FileBrowserUploadConflictResolution,\n\t\tgroup?: UploadTransferGroup\n\t) {\n\t\ttransfers.enqueueUpload({\n\t\t\tadapter,\n\t\t\tdestinationPath: joinUploadRelativePath(browser.currentPath, candidate.relativePath),\n\t\t\tfile: candidate.file,\n\t\t\tgroup,\n\t\t\tonConflict: resolution === 'skip' ? undefined : resolution\n\t\t})\n\t}\n\n\tfunction exitMobileSelection() {\n\t\tbrowser.clearSelection()\n\t\tsetMobileSelectionPath(null)\n\t\tsetSelectionActionsOpen(false)\n\t}\n\n\tconst secondaryControls = (\n\t\t<div className=\"flex min-w-0 flex-wrap items-center gap-[calc(var(--fb-gap)*2)]\">\n\t\t\t<select\n\t\t\t\taria-label=\"Filter files\"\n\t\t\t\tclassName={selectInput()}\n\t\t\t\tonChange={(event) => browser.setFilterKind(event.target.value as 'all' | 'files' | 'folders')}\n\t\t\t\tvalue={browser.filterKind}\n\t\t\t>\n\t\t\t\t<option value=\"all\">All</option>\n\t\t\t\t<option value=\"folders\">Folders</option>\n\t\t\t\t<option value=\"files\">Files</option>\n\t\t\t</select>\n\t\t\t<select\n\t\t\t\taria-label=\"Sort files\"\n\t\t\t\tclassName={selectInput()}\n\t\t\t\tonChange={(event) => browser.setSortBy(event.target.value as 'name' | 'modifiedAt' | 'size')}\n\t\t\t\tvalue={browser.sortBy}\n\t\t\t>\n\t\t\t\t<option value=\"name\">Name</option>\n\t\t\t\t<option value=\"modifiedAt\">Modified</option>\n\t\t\t\t<option value=\"size\">Size</option>\n\t\t\t</select>\n\t\t\t<button\n\t\t\t\taria-label=\"Toggle sort direction\"\n\t\t\t\tclassName={toolButton(false)}\n\t\t\t\tonClick={() => browser.setSortDirection((current) => (current === 'asc' ? 'desc' : 'asc'))}\n\t\t\t\ttype=\"button\"\n\t\t\t>\n\t\t\t\t{browser.sortDirection === 'asc' ? 'Asc' : 'Desc'}\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\taria-label=\"Grid view\"\n\t\t\t\tclassName={toolButton(browser.view === 'grid')}\n\t\t\t\tonClick={() => browser.setView('grid')}\n\t\t\t\ttype=\"button\"\n\t\t\t>\n\t\t\t\t<Grid2X2 aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\taria-label=\"List view\"\n\t\t\t\tclassName={toolButton(browser.view === 'list')}\n\t\t\t\tonClick={() => browser.setView('list')}\n\t\t\t\ttype=\"button\"\n\t\t\t>\n\t\t\t\t<List aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t</button>\n\t\t\t{!readOnly && browser.capabilities.createFolder ? (\n\t\t\t\t<button\n\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetToolbarOpen(false)\n\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\tsetNewFolderOpen(true)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<Folder aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\tNew folder\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{isNarrow ? (\n\t\t\t\t<button\n\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\tdisabled={browser.filteredItems.length === 0}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetToolbarOpen(false)\n\t\t\t\t\t\tsetMobileSelectionPath(browser.currentPath)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\tSelect items\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{isNarrow && !readOnly && browser.clipboard ? (\n\t\t\t\t<button\n\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetToolbarOpen(false)\n\t\t\t\t\t\tvoid pasteClipboardInto(browser.currentPath)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\tPaste here\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t</div>\n\t)\n\n\tconst selectionActions = (\n\t\t<ActionBar\n\t\t\tcanCopy={!readOnly && browser.capabilities.copy}\n\t\t\tcanCut={!readOnly && browser.capabilities.move}\n\t\t\tcanDelete={!readOnly}\n\t\t\tcanMove={!readOnly && browser.capabilities.move}\n\t\t\tcanRename={!readOnly && browser.capabilities.rename}\n\t\t\tcanDownload={canDownloadSelection}\n\t\t\titemCount={browser.filteredItems.length}\n\t\t\tonCopy={() => copySelectedItems()}\n\t\t\tonCut={() => cutSelectedItems()}\n\t\t\tonDelete={() => setDeleteConfirmOpen(true)}\n\t\t\tonDownload={() => void downloadSelection()}\n\t\t\tonMove={openMoveDialog}\n\t\t\tonRename={openRenameDialog}\n\t\t\tonSelectAll={browser.selectAllLoaded}\n\t\t\tonSelectNone={browser.clearSelection}\n\t\t\tselectedCount={browser.selectedPaths.length}\n\t\t/>\n\t)\n\n\tconst detailsContent = (\n\t\t<DetailsPanel\n\t\t\tcanDownload={canDownloadSelection}\n\t\t\titem={selected}\n\t\t\tonCopyPath={() => void copyItemPaths(browser.selectedPaths)}\n\t\t\tonDownload={() => void downloadSelection()}\n\t\t\trenderDetailsContent={renderDetailsContent}\n\t\t\tselectedCount={browser.selectedItems.length}\n\t\t\ttotalBytes={totalSelectedBytes}\n\t\t\tsheet={!hasSidebar}\n\t\t/>\n\t)\n\n\treturn (\n\t\t<section\n\t\t\tclassName={`@container/fb relative flex min-h-[min(520px,100svh)] w-full min-w-0 max-w-full rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] font-[inherit] text-[length:var(--fb-font)] text-[var(--fb-text)] ${SURFACE_MOTION}${className ? ` ${className}` : ''}`}\n\t\t\tdata-fb-density={density}\n\t\t\tdata-fb-layout={isNarrow ? 'narrow' : hasSidebar ? 'wide' : 'medium'}\n\t\t\tref={rootRef}\n\t\t\tstyle={\n\t\t\t\t{\n\t\t\t\t\t...DENSITY_STYLES[density],\n\t\t\t\t\t...(isNarrow ? { '--fb-control-h': 'calc(var(--fb-gap) * 11)' } : {})\n\t\t\t\t} as CSSProperties\n\t\t\t}\n\t\t\tonDragEnter={(event) => {\n\t\t\t\tif (getActiveDraggedPaths(event.dataTransfer).length > 0) {\n\t\t\t\t\tsetDropActive(false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tevent.preventDefault()\n\t\t\t\tif (!readOnly) {\n\t\t\t\t\tsetDropActive(true)\n\t\t\t\t}\n\t\t\t}}\n\t\t\tonDragLeave={(event) => {\n\t\t\t\tif (event.currentTarget === event.target) {\n\t\t\t\t\tsetDropActive(false)\n\t\t\t\t\tsetFolderDropTargetPath(null)\n\t\t\t\t}\n\t\t\t}}\n\t\t\tonDragOver={(event) => {\n\t\t\t\tif (getActiveDraggedPaths(event.dataTransfer).length > 0) {\n\t\t\t\t\tsetDropActive(false)\n\t\t\t\t\tsetFolderDropTargetPath(null)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tevent.preventDefault()\n\t\t\t}}\n\t\t\tonDrop={(event) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tif (getActiveDraggedPaths(event.dataTransfer).length > 0) {\n\t\t\t\t\tendItemDrag()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetDropActive(false)\n\t\t\t\tif (readOnly) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tvoid beginUploadDrop(event.dataTransfer)\n\t\t\t}}\n\t\t\tonPaste={(event) => {\n\t\t\t\tif (readOnly) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst files = Array.from(event.clipboardData.files).filter((file) => file.type.startsWith('image/'))\n\t\t\t\tif (files.length > 0) {\n\t\t\t\t\tvoid beginUploadFiles(files)\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<div aria-atomic=\"true\" aria-live=\"polite\" className=\"sr-only\" role=\"status\">\n\t\t\t\t{formatScreenReaderStatus({\n\t\t\t\t\tcurrentPath: browser.currentPath,\n\t\t\t\t\titemCount: browser.filteredItems.length,\n\t\t\t\t\trootLabel,\n\t\t\t\t\tselectedCount: browser.selectedPaths.length,\n\t\t\t\t\tstatus: browser.status\n\t\t\t\t})}\n\t\t\t</div>\n\t\t\t<div className=\"flex min-w-0 flex-1 flex-col\">\n\t\t\t\t<input\n\t\t\t\t\taccept={uploadPolicy?.allowedMimeTypes?.length ? uploadPolicy.allowedMimeTypes.join(',') : undefined}\n\t\t\t\t\taria-label=\"Upload files\"\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={(event) => void uploadInputFiles(event.target.files)}\n\t\t\t\t\tref={uploadInputRef}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\tclassName=\"hidden\"\n\t\t\t\t/>\n\t\t\t\t<header\n\t\t\t\t\tclassName={`flex min-w-0 flex-wrap items-center gap-[calc(var(--fb-gap)*2)] rounded-t-[var(--fb-radius)] border-b border-[var(--fb-border)] bg-[var(--fb-surface)] px-[var(--fb-pad)] py-[var(--fb-cell-y)] ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\t{mobileSelection ? (\n\t\t\t\t\t\t<div className=\"flex w-full min-w-0 items-center gap-[calc(var(--fb-gap)*2)]\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\taria-label=\"Exit selection\"\n\t\t\t\t\t\t\t\tclassName={toolButton(false)}\n\t\t\t\t\t\t\t\tonClick={exitMobileSelection}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<XIcon aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<span className=\"mr-auto whitespace-nowrap font-semibold\">{browser.selectedPaths.length} selected</span>\n\t\t\t\t\t\t\t<button className={commandButton(false)} onClick={browser.selectAllLoaded} type=\"button\">\n\t\t\t\t\t\t\t\tSelect all\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<div className={isNarrow ? 'min-w-0 flex-1' : 'min-w-0 max-w-full'}>\n\t\t\t\t\t\t\t\t<Breadcrumbs\n\t\t\t\t\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\t\t\t\t\tonNavigate={(nextPath) => browser.navigate(nextPath, { source: 'breadcrumb' })}\n\t\t\t\t\t\t\t\t\tpath={browser.currentPath}\n\t\t\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{isNarrow ? (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\taria-label=\"Browser options\"\n\t\t\t\t\t\t\t\t\taria-expanded={toolbarOpen}\n\t\t\t\t\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t\t\t\t\t\tclassName={toolButton(false)}\n\t\t\t\t\t\t\t\t\tonClick={() => setToolbarOpen(true)}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<MoreHorizontal aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t\t{clipboardNotice ? (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\taria-label=\"Clipboard status\"\n\t\t\t\t\t\t\tclassName={`rounded-[calc(var(--fb-radius)-4px)] bg-[var(--fb-accent-soft)] px-2 py-1 text-[12px] font-medium text-[var(--fb-accent)] ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\trole=\"status\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{clipboardNotice}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{!mobileSelection ? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`flex min-w-0 flex-wrap items-center gap-[calc(var(--fb-gap)*2)] ${isNarrow ? 'w-full' : 'ml-auto max-w-full'}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<label className={`relative block min-w-0 ${isNarrow ? 'w-full' : 'w-[calc(var(--fb-gap)*44)] flex-1'}`}>\n\t\t\t\t\t\t\t\t<Search\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\tclassName=\"pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-[var(--fb-muted)]\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\taria-label=\"Search files\"\n\t\t\t\t\t\t\t\t\tclassName={`h-[var(--fb-control-h)] min-h-[var(--fb-control-h)] w-full min-w-0 rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] pl-7 pr-2 text-[16px] text-[var(--fb-text)] outline-none focus:border-[var(--fb-accent)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] @min-[40rem]/fb:text-[12px] [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:text-[16px] ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\tonChange={(event) => browser.setSearchQuery(event.target.value)}\n\t\t\t\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\t\t\t\tvalue={browser.searchQuery}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t{!isNarrow ? secondaryControls : null}\n\t\t\t\t\t\t\t{!isNarrow && !readOnly ? (\n\t\t\t\t\t\t\t\t<button className={primaryButton()} onClick={() => uploadInputRef.current?.click()} type=\"button\">\n\t\t\t\t\t\t\t\t\t<Upload aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t\tUpload\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</header>\n\n\t\t\t\t{!isNarrow ? selectionActions : null}\n\t\t\t\t{!hasSidebar && !isNarrow && showDetailsPanel ? (\n\t\t\t\t\t<div className=\"flex justify-end border-b border-[var(--fb-border)] px-[var(--fb-pad)] py-[var(--fb-cell-y)]\">\n\t\t\t\t\t\t<button className={commandButton(false)} onClick={() => setDetailsOpen(true)} type=\"button\">\n\t\t\t\t\t\t\t<Info aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\tDetails\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\n\t\t\t\t{uploadRejections.length > 0 ? (\n\t\t\t\t\t<UploadRejectionAlert onDismiss={() => setUploadRejections([])} rejections={uploadRejections} />\n\t\t\t\t) : null}\n\n\t\t\t\t<div\n\t\t\t\t\tclassName={`relative min-h-0 min-w-0 flex-1 overflow-auto bg-[var(--fb-bg)] p-[var(--fb-pad)] ${isNarrow && !readOnly && !mobileSelection ? 'pb-[calc(var(--fb-gap)*20)]' : ''} ${SURFACE_MOTION}`}\n\t\t\t\t\tonClick={clearSelectionFromEmptySurface}\n\t\t\t\t\tonContextMenu={openEmptyContextMenu}\n\t\t\t\t>\n\t\t\t\t\t{browser.status === 'loading' && browser.items.length === 0 ? (\n\t\t\t\t\t\t<SkeletonGrid rootLabel={rootLabel} />\n\t\t\t\t\t) : browser.status === 'error' ? (\n\t\t\t\t\t\t<StateMessage\n\t\t\t\t\t\t\ttitle={getErrorState(browser.error).title}\n\t\t\t\t\t\t\ttone=\"danger\"\n\t\t\t\t\t\t\tvalue={getErrorState(browser.error).value}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : browser.filteredItems.length === 0 ? (\n\t\t\t\t\t\t<StateMessage\n\t\t\t\t\t\t\ttitle={emptyState ? emptyState.title : 'This folder is empty'}\n\t\t\t\t\t\t\tvalue={emptyState ? emptyState.description : 'Create a folder or upload files to start.'}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : browser.view === 'grid' ? (\n\t\t\t\t\t\t<FileGrid\n\t\t\t\t\t\t\tbrowser={browser}\n\t\t\t\t\t\t\tcanMove={!readOnly && browser.capabilities.move}\n\t\t\t\t\t\t\tfolderDropTargetPath={folderDropTargetPath}\n\t\t\t\t\t\t\tinlineRenameError={inlineRenameError}\n\t\t\t\t\t\t\tinlineRenameLabel={inlineRenameItem?.name ?? ''}\n\t\t\t\t\t\t\tinlineRenameItem={inlineRenameItem}\n\t\t\t\t\t\t\tinlineRenameValue={inlineRenameValue}\n\t\t\t\t\t\t\tonDragStart={startItemDrag}\n\t\t\t\t\t\t\tonDragEnd={endItemDrag}\n\t\t\t\t\t\t\tonFolderDragOver={allowFolderDrop}\n\t\t\t\t\t\t\tonFolderDrop={(item, event) => void moveDraggedItemsToFolder(item, event)}\n\t\t\t\t\t\t\tonEmptyClick={() => browser.clearSelection()}\n\t\t\t\t\t\t\tonInlineRenameCancel={cancelInlineRename}\n\t\t\t\t\t\t\tonInlineRenameChange={(value) => {\n\t\t\t\t\t\t\t\tsetInlineRenameValue(value)\n\t\t\t\t\t\t\t\tsetInlineRenameError(null)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonInlineRenameCommit={() => void commitInlineRename()}\n\t\t\t\t\t\t\tonContextMenu={openItemContextMenu}\n\t\t\t\t\t\t\tonOpenItem={openItemFromDoubleClick}\n\t\t\t\t\t\t\tonSelectItem={selectItemWithEvent}\n\t\t\t\t\t\t\tonTouchMenu={openItemTouchMenu}\n\t\t\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\t\t\tselectionMode={mobileSelection}\n\t\t\t\t\t\t\tonToggleItem={browser.toggleSelection}\n\t\t\t\t\t\t\trenderItemMeta={renderItemMeta}\n\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\tselectedPaths={browser.selectedPaths}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<FileTable\n\t\t\t\t\t\t\tbrowser={browser}\n\t\t\t\t\t\t\tcanMove={!readOnly && browser.capabilities.move}\n\t\t\t\t\t\t\tfolderDropTargetPath={folderDropTargetPath}\n\t\t\t\t\t\t\tinlineRenameError={inlineRenameError}\n\t\t\t\t\t\t\tinlineRenameLabel={inlineRenameItem?.name ?? ''}\n\t\t\t\t\t\t\tinlineRenameItem={inlineRenameItem}\n\t\t\t\t\t\t\tinlineRenameValue={inlineRenameValue}\n\t\t\t\t\t\t\tonDragStart={startItemDrag}\n\t\t\t\t\t\t\tonDragEnd={endItemDrag}\n\t\t\t\t\t\t\tonFolderDragOver={allowFolderDrop}\n\t\t\t\t\t\t\tonFolderDrop={(item, event) => void moveDraggedItemsToFolder(item, event)}\n\t\t\t\t\t\t\tonInlineRenameCancel={cancelInlineRename}\n\t\t\t\t\t\t\tonInlineRenameChange={(value) => {\n\t\t\t\t\t\t\t\tsetInlineRenameValue(value)\n\t\t\t\t\t\t\t\tsetInlineRenameError(null)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonInlineRenameCommit={() => void commitInlineRename()}\n\t\t\t\t\t\t\tonContextMenu={openItemContextMenu}\n\t\t\t\t\t\t\tonOpenItem={openItemFromDoubleClick}\n\t\t\t\t\t\t\tonSelectItem={selectItemWithEvent}\n\t\t\t\t\t\t\tonTouchMenu={openItemTouchMenu}\n\t\t\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\t\t\tselectionMode={mobileSelection}\n\t\t\t\t\t\t\tonToggleItem={browser.toggleSelection}\n\t\t\t\t\t\t\trenderItemMeta={renderItemMeta}\n\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\tselectedPaths={browser.selectedPaths}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{dropActive ? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`pointer-events-none absolute inset-3 z-10 grid place-items-center rounded-[var(--fb-radius)] border-2 border-dashed border-[var(--fb-accent)] bg-[var(--fb-accent-soft)] text-[13px] font-semibold text-[var(--fb-accent)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDrop files to upload\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\n\t\t\t\t<footer\n\t\t\t\t\tclassName={`sticky bottom-0 flex min-h-[calc(var(--fb-gap)*11)] min-w-0 flex-wrap items-center justify-between gap-[var(--fb-gap)] rounded-b-[var(--fb-radius)] border-t border-[var(--fb-border)] bg-[var(--fb-surface)] px-[var(--fb-pad)] py-[var(--fb-gap)] text-[11px] text-[var(--fb-muted)] ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\t{mobileSelection ? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\taria-label=\"Selection actions\"\n\t\t\t\t\t\t\tclassName=\"flex w-full flex-wrap items-center gap-[calc(var(--fb-gap)*2)]\"\n\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\tdisabled={!selected}\n\t\t\t\t\t\t\t\tonClick={() => setSelectionActionsOpen(true)}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MoreHorizontal aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\tActions\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t{showDetailsPanel ? (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\t\tdisabled={!selected}\n\t\t\t\t\t\t\t\t\tonClick={() => setDetailsOpen(true)}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Info aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t\tDetails\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<span>\n\t\t\t\t\t\t{browser.filteredItems.length} items\n\t\t\t\t\t\t{browser.selectedPaths.length ? ` · ${browser.selectedPaths.length} selected` : ''}\n\t\t\t\t\t</span>\n\t\t\t\t\t{isNarrow && !readOnly && !mobileSelection ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label=\"Upload\"\n\t\t\t\t\t\t\tclassName={`${primaryButton()} absolute bottom-[calc(var(--fb-gap)*14)] right-[var(--fb-pad)] shadow-lg`}\n\t\t\t\t\t\t\tonClick={() => uploadInputRef.current?.click()}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Upload aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\tUpload\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{browser.hasMore ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tclassName={`min-h-[var(--fb-control-h)] rounded-[calc(var(--fb-radius)-4px)] px-2 py-1 font-medium text-[var(--fb-accent)] hover:bg-[var(--fb-accent-soft)] ${TOUCH_CONTROL} ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\tonClick={() => void browser.loadMore()}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tLoad more\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span />\n\t\t\t\t\t)}\n\t\t\t\t</footer>\n\t\t\t</div>\n\n\t\t\t{showDetailsPanel && hasSidebar ? detailsContent : null}\n\t\t\t{showDetailsPanel && !hasSidebar && detailsOpen ? (\n\t\t\t\t<ActionSheet label=\"Details\" onClose={() => setDetailsOpen(false)}>\n\t\t\t\t\t{detailsContent}\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\t\t\t{isNarrow && toolbarOpen ? (\n\t\t\t\t<ActionSheet label=\"Browser options\" onClose={() => setToolbarOpen(false)}>\n\t\t\t\t\t{secondaryControls}\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\t\t\t{mobileSelection && selectionActionsOpen ? (\n\t\t\t\t<ActionSheet label=\"Selected item actions\" onClose={() => setSelectionActionsOpen(false)}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tif ((event.target as Element).closest('button:not(:disabled)')) setSelectionActionsOpen(false)\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{selectionActions}\n\t\t\t\t\t</div>\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\n\t\t\t{contextMenu ? (\n\t\t\t\t<ContextMenu\n\t\t\t\t\tbrowser={browser}\n\t\t\t\t\tcanDownload={canDownloadSelection}\n\t\t\t\t\tmenu={contextMenu}\n\t\t\t\t\tonClose={() => setContextMenu(null)}\n\t\t\t\t\tonDelete={() => setDeleteConfirmOpen(true)}\n\t\t\t\t\tonDownload={() => void downloadSelection()}\n\t\t\t\t\tonMove={openMoveDialog}\n\t\t\t\t\tonNewFolder={() => {\n\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\tsetNewFolderOpen(true)\n\t\t\t\t\t}}\n\t\t\t\t\tonCopy={() => copySelectedItems()}\n\t\t\t\t\tonCopyPath={(item) =>\n\t\t\t\t\t\tvoid copyItemPaths(browser.selectedPaths.includes(item.path) ? browser.selectedPaths : [item.path])\n\t\t\t\t\t}\n\t\t\t\t\tonCut={() => cutSelectedItems()}\n\t\t\t\t\tonPaste={() => void pasteClipboardInto(browser.currentPath)}\n\t\t\t\t\tonRename={openRenameDialog}\n\t\t\t\t\tonUpload={() => uploadInputRef.current?.click()}\n\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t/>\n\t\t\t) : null}\n\n\t\t\t{newFolderOpen ? (\n\t\t\t\t<ResponsiveDialog label=\"New folder\" narrow={isNarrow} onClose={() => setNewFolderOpen(false)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`w-[min(360px,100%)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 shadow-[0_18px_50px_color-mix(in_oklch,var(--fb-text)_18%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid createFolder()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<h2 className=\"m-0 text-[14px] font-semibold\">New folder</h2>\n\t\t\t\t\t\t<label className=\"mt-3 block text-[12px] font-medium text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\tFolder name\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\taria-label=\"Folder name\"\n\t\t\t\t\t\t\t\tclassName={`mt-1 h-[max(var(--fb-control-h),calc(var(--fb-gap)*9))] w-full min-w-0 rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] px-2 text-[16px] text-[var(--fb-text)] outline-none focus:border-[var(--fb-accent)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\tsetNewFolderName(event.target.value)\n\t\t\t\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tvalue={newFolderName}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t{newFolderError ? (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName={`mt-3 rounded-[calc(var(--fb-radius)-4px)] border border-[var(--fb-danger)] bg-[var(--fb-danger-soft)] px-2 py-1.5 text-[12px] text-[var(--fb-danger)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t\t\trole=\"alert\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{newFolderError}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className=\"mt-4 flex flex-wrap justify-end gap-2\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\t\t\t\tsetNewFolderOpen(false)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={primaryButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tCreate folder\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{renameItem ? (\n\t\t\t\t<ResponsiveDialog label=\"Rename item\" narrow={isNarrow} onClose={() => setRenameItem(null)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`w-[min(360px,100%)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 shadow-[0_18px_50px_color-mix(in_oklch,var(--fb-text)_18%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid renameSelectedItem()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<h2 className=\"m-0 text-[14px] font-semibold\">Rename</h2>\n\t\t\t\t\t\t<label className=\"mt-3 block text-[12px] font-medium text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\tNew name\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\taria-label=\"New name\"\n\t\t\t\t\t\t\t\tclassName={`mt-1 h-[max(var(--fb-control-h),calc(var(--fb-gap)*9))] w-full min-w-0 rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] px-2 text-[16px] text-[var(--fb-text)] outline-none focus:border-[var(--fb-accent)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\tsetRenameValue(event.target.value)\n\t\t\t\t\t\t\t\t\tsetRenameError(null)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tvalue={renameValue}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t{renameError ? (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName={`mt-3 rounded-[calc(var(--fb-radius)-4px)] border border-[var(--fb-danger)] bg-[var(--fb-danger-soft)] px-2 py-1.5 text-[12px] text-[var(--fb-danger)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t\t\trole=\"alert\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{renameError}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className=\"mt-4 flex flex-wrap justify-end gap-2\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetRenameItem(null)\n\t\t\t\t\t\t\t\t\tsetRenameValue('')\n\t\t\t\t\t\t\t\t\tsetRenameError(null)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={primaryButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tRename item\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{deleteConfirmOpen ? (\n\t\t\t\t<ResponsiveDialog label=\"Delete selected items\" narrow={isNarrow} onClose={() => setDeleteConfirmOpen(false)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`w-[min(400px,100%)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 shadow-[0_18px_50px_color-mix(in_oklch,var(--fb-text)_18%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid deleteSelectedItems()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<h2 className=\"m-0 text-[14px] font-semibold\">Delete selected items</h2>\n\t\t\t\t\t\t<p className=\"mt-2 text-[12px] text-[var(--fb-muted)]\">This removes the selected entries from storage.</p>\n\t\t\t\t\t\t<ul\n\t\t\t\t\t\t\tclassName={`mt-3 max-h-32 overflow-auto rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-bg)] p-2 text-[12px] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{browser.selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t<li className=\"truncate py-1\" key={item.path}>\n\t\t\t\t\t\t\t\t\t{item.name}\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t<div className=\"mt-4 flex flex-wrap justify-end gap-2\">\n\t\t\t\t\t\t\t<button className={commandButton(false)} onClick={() => setDeleteConfirmOpen(false)} type=\"button\">\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={dangerButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tDelete selected\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{moveDialogOpen ? (\n\t\t\t\t<ResponsiveDialog label=\"Move selected items\" narrow={isNarrow} onClose={() => setMoveDialogOpen(false)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`w-[min(420px,100%)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 shadow-[0_18px_50px_color-mix(in_oklch,var(--fb-text)_18%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid moveSelectedItems()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<h2 className=\"m-0 text-[14px] font-semibold\">Move selected items</h2>\n\t\t\t\t\t\t<p className=\"mt-2 text-[12px] text-[var(--fb-muted)]\">Choose a destination folder from the folder tree.</p>\n\t\t\t\t\t\t<MoveDestinationPicker\n\t\t\t\t\t\t\tcurrentPath={browser.currentPath}\n\t\t\t\t\t\t\tdestinations={moveDestinations}\n\t\t\t\t\t\t\terror={moveDestinationError}\n\t\t\t\t\t\t\tonSelect={setMoveDestination}\n\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\tselectedPath={moveDestination}\n\t\t\t\t\t\t\tstatus={moveDestinationStatus}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<div className=\"mt-3 truncate text-[11px] text-[var(--fb-muted)]\">Destination: {moveDestination}</div>\n\t\t\t\t\t\t<div className=\"mt-4 flex flex-wrap justify-end gap-2\">\n\t\t\t\t\t\t\t<button className={commandButton(false)} onClick={() => setMoveDialogOpen(false)} type=\"button\">\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={primaryButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tMove here\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{bulkFailure ? (\n\t\t\t\t<BulkFailureDialog error={bulkFailure} narrow={isNarrow} onClose={() => setBulkFailure(null)} />\n\t\t\t) : null}\n\n\t\t\t{uploadConflictQueue ? (\n\t\t\t\t<UploadConflictDialog\n\t\t\t\t\tapplyToAll={applyUploadResolution}\n\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\tcurrentPath={browser.currentPath}\n\t\t\t\t\tonApplyToAllChange={setApplyUploadResolution}\n\t\t\t\t\tonCancel={() => {\n\t\t\t\t\t\tsetUploadConflictQueue(null)\n\t\t\t\t\t\tsetApplyUploadResolution(false)\n\t\t\t\t\t}}\n\t\t\t\t\tonResolve={(resolution) => resolveUploadConflict(resolution)}\n\t\t\t\t\tqueue={uploadConflictQueue}\n\t\t\t\t\tresolutions={allowedUploadConflictResolutions}\n\t\t\t\t/>\n\t\t\t) : null}\n\n\t\t\t{preview ? (\n\t\t\t\t<ResponsiveDialog label={`Preview ${preview.item.name}`} narrow={isNarrow} onClose={() => setPreview(null)}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={`w-[min(720px,100%)] overflow-hidden rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] shadow-[0_22px_70px_color-mix(in_oklch,var(--fb-text)_24%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`flex min-h-[calc(var(--fb-gap)*12)] min-w-0 flex-wrap items-center justify-between gap-[calc(var(--fb-gap)*2)] border-b border-[var(--fb-border)] p-[calc(var(--fb-gap)*3)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"min-w-0 max-w-full flex-1 basis-[calc(var(--fb-gap)*40)] truncate font-semibold\">\n\t\t\t\t\t\t\t\tPreview {preview.item.name}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"flex shrink-0 items-center gap-1\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\taria-label=\"Previous file\"\n\t\t\t\t\t\t\t\t\tclassName={toolButton(false)}\n\t\t\t\t\t\t\t\t\tdisabled={previewFiles.length <= 1}\n\t\t\t\t\t\t\t\t\tonClick={() => showAdjacentPreview(-1)}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ChevronLeft aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\taria-label=\"Next file\"\n\t\t\t\t\t\t\t\t\tclassName={toolButton(false)}\n\t\t\t\t\t\t\t\t\tdisabled={previewFiles.length <= 1}\n\t\t\t\t\t\t\t\t\tonClick={() => showAdjacentPreview(1)}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ChevronRight aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button className={toolButton(false)} onClick={() => setPreview(null)} type=\"button\">\n\t\t\t\t\t\t\t\t\tClose\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`grid min-h-[min(260px,40dvh)] min-w-0 place-items-center bg-[var(--fb-bg)] p-[var(--fb-pad)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{(preview.item.mimeType?.startsWith('image/') && preview.url) || preview.item.thumbnailUrl ? (\n\t\t\t\t\t\t\t\t<div className=\"min-w-0 max-w-full text-center\">\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\talt={preview.item.name}\n\t\t\t\t\t\t\t\t\t\tclassName={`max-h-[min(420px,55dvh)] max-w-full rounded-[calc(var(--fb-radius)-2px)] object-contain ${SURFACE_MOTION}`}\n\t\t\t\t\t\t\t\t\t\tsrc={preview.url ?? preview.item.thumbnailUrl}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<PreviewOriginalLink preview={preview} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<div className=\"min-w-0 max-w-full text-center\">\n\t\t\t\t\t\t\t\t\t<File className=\"mx-auto size-12 text-[var(--fb-muted)]\" />\n\t\t\t\t\t\t\t\t\t<div className=\"mt-3 font-semibold\">{preview.item.name}</div>\n\t\t\t\t\t\t\t\t\t<div className=\"mt-1 text-[12px] text-[var(--fb-muted)]\">{preview.item.mimeType ?? 'File'}</div>\n\t\t\t\t\t\t\t\t\t{preview.status === 'loading' ? (\n\t\t\t\t\t\t\t\t\t\t<div className=\"mt-3 text-[12px] text-[var(--fb-muted)]\">Loading preview</div>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t{preview.status === 'error' ? (\n\t\t\t\t\t\t\t\t\t\t<div className=\"mt-3 text-[12px] text-[var(--fb-danger)]\">\n\t\t\t\t\t\t\t\t\t\t\t{preview.error ?? 'Could not load preview'}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t<PreviewOriginalLink preview={preview} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\n\ntype BrowserLike<TMetadata = unknown> = UseFileBrowserResult<TMetadata>\n\nfunction joinUploadRelativePath(currentPath: string, relativePath: string) {\n\treturn relativePath\n\t\t.split('/')\n\t\t.filter(Boolean)\n\t\t.reduce((path, part) => joinFileBrowserPath(path, part), currentPath)\n}\n\nfunction getUploadFolderPaths(candidates: FileBrowserUploadCandidate[]) {\n\tconst folders = new Set<string>()\n\n\tfor (const { relativePath } of candidates) {\n\t\tconst parts = relativePath.split('/').filter(Boolean)\n\t\tfor (let index = 1; index < parts.length; index += 1) {\n\t\t\tfolders.add(parts.slice(0, index).join('/'))\n\t\t}\n\t}\n\n\treturn Array.from(folders).sort((a, b) => a.split('/').length - b.split('/').length || a.localeCompare(b))\n}\n\nfunction partitionUploadCandidates(\n\tcandidates: FileBrowserUploadCandidate[],\n\tpredicate: (candidate: FileBrowserUploadCandidate) => boolean\n): [FileBrowserUploadCandidate[], FileBrowserUploadCandidate[]] {\n\tconst matched: FileBrowserUploadCandidate[] = []\n\tconst unmatched: FileBrowserUploadCandidate[] = []\n\n\tfor (const candidate of candidates) {\n\t\tif (predicate(candidate)) {\n\t\t\tmatched.push(candidate)\n\t\t} else {\n\t\t\tunmatched.push(candidate)\n\t\t}\n\t}\n\n\treturn [matched, unmatched]\n}\n\nfunction getUploadTransferGroup(\n\tcurrentPath: string,\n\tcandidates: FileBrowserUploadCandidate[],\n\tcreatedFolders = 0\n): UploadTransferGroup | undefined {\n\tif (getUploadFolderPaths(candidates).length === 0) {\n\t\treturn undefined\n\t}\n\n\tconst topLevelFolders = candidates\n\t\t.map((candidate) => candidate.relativePath.split('/').filter(Boolean)[0])\n\t\t.filter((folder): folder is string => Boolean(folder))\n\tconst uniqueTopLevelFolders = Array.from(new Set(topLevelFolders))\n\tconst name = uniqueTopLevelFolders.length === 1 ? uniqueTopLevelFolders[0] : 'Folder upload'\n\tconst id =\n\t\tuniqueTopLevelFolders.length === 1\n\t\t\t? joinUploadRelativePath(currentPath, name)\n\t\t\t: `${normalizeFileBrowserPath(currentPath)}#folder-upload`\n\n\treturn {\n\t\tid,\n\t\tname,\n\t\ttotalFiles: candidates.length,\n\t\tcreatedFolders\n\t}\n}\n\nasync function collectMoveDestinations<TMetadata>(\n\tadapter: FileBrowserAdapter<TMetadata>,\n\texcludedPaths: string[]\n): Promise<MoveDestination[]> {\n\tconst destinations: MoveDestination[] = []\n\tconst excluded = excludedPaths.map(normalizeFileBrowserPath)\n\n\tasync function collect(path: string, depth: number): Promise<void> {\n\t\tlet cursor: string | undefined\n\t\tdo {\n\t\t\tconst result = await adapter.list(path, { cursor })\n\t\t\tconst folders = result.items\n\t\t\t\t.filter((item) => item.kind === 'folder')\n\t\t\t\t.sort((left, right) =>\n\t\t\t\t\tleft.name.localeCompare(right.name, undefined, {\n\t\t\t\t\t\tnumeric: true,\n\t\t\t\t\t\tsensitivity: 'base'\n\t\t\t\t\t})\n\t\t\t\t)\n\n\t\t\tfor (const folder of folders) {\n\t\t\t\tif (isExcludedDestination(folder.path, excluded)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tdestinations.push({\n\t\t\t\t\tpath: folder.path,\n\t\t\t\t\tname: folder.name,\n\t\t\t\t\tdepth\n\t\t\t\t})\n\t\t\t\tawait collect(folder.path, depth + 1)\n\t\t\t}\n\n\t\t\tcursor = result.cursor\n\t\t} while (cursor)\n\t}\n\n\tawait collect('/', 0)\n\treturn destinations\n}\n\nfunction isExcludedDestination(path: string, excludedPaths: string[]) {\n\tconst normalized = normalizeFileBrowserPath(path)\n\treturn excludedPaths.some((excluded) => normalized === excluded || normalized.startsWith(`${excluded}/`))\n}\n\nfunction applyUploadPolicy(\n\tcandidates: FileBrowserUploadCandidate[],\n\tpolicy: FileBrowserUploadPolicy | undefined,\n\tcurrentPath: string\n) {\n\tif (!policy) {\n\t\treturn { acceptedCandidates: candidates, rejectedCandidates: [] }\n\t}\n\n\tconst acceptedCandidates: FileBrowserUploadCandidate[] = []\n\tconst rejectedCandidates: FileBrowserUploadRejection[] = []\n\tlet acceptedBytes = 0\n\n\tfor (const candidate of candidates) {\n\t\tconst reasons: string[] = []\n\n\t\tif (policy.maxFileSizeBytes !== undefined && candidate.file.size > policy.maxFileSizeBytes) {\n\t\t\treasons.push(`File is larger than ${formatBytes(policy.maxFileSizeBytes)}`)\n\t\t}\n\n\t\tif (policy.allowedMimeTypes?.length && !isAllowedUploadType(candidate.file, policy.allowedMimeTypes)) {\n\t\t\treasons.push(`File type ${candidate.file.type || 'unknown'} is not allowed`)\n\t\t}\n\n\t\tif (policy.remainingQuotaBytes !== undefined && acceptedBytes + candidate.file.size > policy.remainingQuotaBytes) {\n\t\t\treasons.push(`Upload exceeds remaining quota of ${formatBytes(policy.remainingQuotaBytes)}`)\n\t\t}\n\n\t\tconst customReason = policy.validate?.(candidate, {\n\t\t\tacceptedBytes,\n\t\t\tcurrentPath\n\t\t})\n\t\tif (Array.isArray(customReason)) {\n\t\t\treasons.push(...customReason.filter(Boolean))\n\t\t} else if (customReason) {\n\t\t\treasons.push(customReason)\n\t\t}\n\n\t\tif (reasons.length > 0) {\n\t\t\trejectedCandidates.push({\n\t\t\t\tfileName: candidate.file.name,\n\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\treasons\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tacceptedBytes += candidate.file.size\n\t\tacceptedCandidates.push(candidate)\n\t}\n\n\treturn { acceptedCandidates, rejectedCandidates }\n}\n\nfunction isAllowedUploadType(file: File, allowedMimeTypes: string[]) {\n\treturn allowedMimeTypes.some((allowed) => {\n\t\tif (allowed.endsWith('/*')) {\n\t\t\treturn file.type.startsWith(allowed.slice(0, -1))\n\t\t}\n\t\tif (allowed.startsWith('.')) {\n\t\t\treturn file.name.toLowerCase().endsWith(allowed.toLowerCase())\n\t\t}\n\t\treturn file.type === allowed\n\t})\n}\n\nfunction FileGrid<TMetadata>({\n\tbrowser,\n\tcanMove,\n\tfolderDropTargetPath,\n\tinlineRenameError,\n\tinlineRenameLabel,\n\tinlineRenameItem,\n\tinlineRenameValue,\n\tselectedPaths,\n\tonContextMenu,\n\tonDragEnd,\n\tonDragStart,\n\tonEmptyClick,\n\tonFolderDragOver,\n\tonFolderDrop,\n\tonInlineRenameCancel,\n\tonInlineRenameChange,\n\tonInlineRenameCommit,\n\tonOpenItem,\n\tonSelectItem,\n\tonTouchMenu,\n\tnarrow,\n\tselectionMode,\n\tonToggleItem,\n\trenderItemMeta,\n\trootLabel\n}: {\n\tbrowser: BrowserLike<TMetadata>\n\tcanMove: boolean\n\tfolderDropTargetPath: string | null\n\tinlineRenameError: string | null\n\tinlineRenameLabel: string\n\tinlineRenameItem: FileNode<TMetadata> | null\n\tinlineRenameValue: string\n\tselectedPaths: string[]\n\tonContextMenu: (item: FileNode<TMetadata>, event: MouseEvent) => void\n\tonDragEnd: () => void\n\tonDragStart: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonEmptyClick: () => void\n\tonFolderDragOver: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonFolderDrop: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonInlineRenameCancel: () => void\n\tonInlineRenameChange: (value: string) => void\n\tonInlineRenameCommit: () => void\n\tonOpenItem: (item: FileNode<TMetadata>) => void\n\tonSelectItem: (path: string, event: MouseEvent) => void\n\tonTouchMenu: (item: FileNode<TMetadata>) => void\n\tnarrow: boolean\n\tselectionMode: boolean\n\tonToggleItem: (path: string) => void\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\trootLabel: string\n}) {\n\tconst [gridElement, setGridElement] = useState<HTMLDivElement | null>(null)\n\n\tfunction handleMarqueeSelect(event: OnSelect) {\n\t\tconst inputEvent = event.inputEvent as MouseEvent | KeyboardEvent | undefined\n\t\tconst paths = event.selected\n\t\t\t.map((element) => element.getAttribute('data-fb-path'))\n\t\t\t.filter((path): path is string => Boolean(path))\n\n\t\tbrowser.setSelection(paths, {\n\t\t\tadditive: Boolean(inputEvent?.shiftKey || inputEvent?.metaKey || inputEvent?.ctrlKey)\n\t\t})\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{gridElement && !narrow ? (\n\t\t\t\t<Selecto\n\t\t\t\t\tclassName=\"[background:var(--fb-accent-soft)!important] [border-color:var(--fb-accent)!important]\"\n\t\t\t\t\tcontainer={gridElement}\n\t\t\t\t\tdragContainer={gridElement}\n\t\t\t\t\thitRate={10}\n\t\t\t\t\tonSelect={handleMarqueeSelect}\n\t\t\t\t\tonDragStart={(event) => {\n\t\t\t\t\t\tif (event.inputEvent?.type?.startsWith('touch')) event.stop()\n\t\t\t\t\t}}\n\t\t\t\t\tpreventClickEventOnDrag\n\t\t\t\t\tselectByClick={false}\n\t\t\t\t\tselectableTargets={[\n\t\t\t\t\t\t() => Array.from(gridElement.querySelectorAll<HTMLElement | SVGElement>(\"[data-fb-selectable='true']\"))\n\t\t\t\t\t]}\n\t\t\t\t\tselectFromInside={false}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<div\n\t\t\t\taria-label={rootLabel}\n\t\t\t\tclassName=\"relative grid min-h-full min-w-0 touch-pan-y content-start grid-cols-[repeat(2,minmax(0,1fr))] gap-[var(--fb-grid-gap)] @min-[40rem]/fb:grid-cols-[repeat(auto-fill,minmax(min(100%,var(--fb-card-min)),1fr))]\"\n\t\t\t\tonClick={(event) => {\n\t\t\t\t\tif (!selectionMode && event.target === event.currentTarget && !hasSelectionModifier(event)) {\n\t\t\t\t\t\tonEmptyClick()\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\tref={setGridElement}\n\t\t\t\trole=\"grid\"\n\t\t\t>\n\t\t\t\t{browser.filteredItems.map((item) => (\n\t\t\t\t\t<FileCard\n\t\t\t\t\t\tcanMove={canMove}\n\t\t\t\t\t\tdropTarget={folderDropTargetPath === item.path}\n\t\t\t\t\t\titem={item}\n\t\t\t\t\t\tkey={item.path}\n\t\t\t\t\t\tonOpen={() => onOpenItem(item)}\n\t\t\t\t\t\tonContextMenu={(event) => onContextMenu(item, event)}\n\t\t\t\t\t\tonDragEnd={onDragEnd}\n\t\t\t\t\t\tonDragStart={(event) => onDragStart(item, event)}\n\t\t\t\t\t\tonFolderDragOver={(event) => onFolderDragOver(item, event)}\n\t\t\t\t\t\tonFolderDrop={(event) => onFolderDrop(item, event)}\n\t\t\t\t\t\tinlineRenameError={inlineRenameError}\n\t\t\t\t\t\tinlineRenameLabel={inlineRenameLabel}\n\t\t\t\t\t\tinlineRenameValue={inlineRenameValue}\n\t\t\t\t\t\tisRenaming={inlineRenameItem?.path === item.path}\n\t\t\t\t\t\tonInlineRenameCancel={onInlineRenameCancel}\n\t\t\t\t\t\tonInlineRenameChange={onInlineRenameChange}\n\t\t\t\t\t\tonInlineRenameCommit={onInlineRenameCommit}\n\t\t\t\t\t\tonSelect={(event) => onSelectItem(item.path, event)}\n\t\t\t\t\t\tonTouchMenu={() => onTouchMenu(item)}\n\t\t\t\t\t\tnarrow={narrow}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tonToggle={() => onToggleItem(item.path)}\n\t\t\t\t\t\trenderItemMeta={renderItemMeta}\n\t\t\t\t\t\tselected={selectedPaths.includes(item.path)}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</>\n\t)\n}\n\nfunction FileCard<TMetadata>({\n\tcanMove,\n\tdropTarget,\n\tinlineRenameError,\n\tinlineRenameLabel,\n\tinlineRenameValue,\n\tisRenaming,\n\titem,\n\tselected,\n\tonSelect,\n\tonOpen,\n\tonContextMenu,\n\tonDragEnd,\n\tonDragStart,\n\tonFolderDragOver,\n\tonFolderDrop,\n\tonInlineRenameCancel,\n\tonInlineRenameChange,\n\tonInlineRenameCommit,\n\tonTouchMenu,\n\tnarrow,\n\tselectionMode,\n\tonToggle,\n\trenderItemMeta\n}: {\n\tcanMove: boolean\n\tdropTarget: boolean\n\tinlineRenameError: string | null\n\tinlineRenameLabel: string\n\tinlineRenameValue: string\n\tisRenaming: boolean\n\titem: FileNode<TMetadata>\n\tselected: boolean\n\tonSelect: (event: MouseEvent) => void\n\tonOpen: () => void\n\tonContextMenu: (event: MouseEvent) => void\n\tonDragEnd: () => void\n\tonDragStart: (event: DragEvent) => void\n\tonFolderDragOver: (event: DragEvent) => void\n\tonFolderDrop: (event: DragEvent) => void\n\tonInlineRenameCancel: () => void\n\tonInlineRenameChange: (value: string) => void\n\tonInlineRenameCommit: () => void\n\tonTouchMenu: () => void\n\tnarrow: boolean\n\tselectionMode: boolean\n\tonToggle: () => void\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n}) {\n\tconst longPress = useLongPress(onTouchMenu)\n\n\treturn (\n\t\t<article\n\t\t\taria-selected={selected}\n\t\t\tdata-fb-drop-target={dropTarget ? 'true' : undefined}\n\t\t\tdata-fb-path={item.path}\n\t\t\tdata-fb-selectable=\"true\"\n\t\t\tdraggable={canMove && !narrow}\n\t\t\tclassName={`group relative flex min-h-[var(--fb-card-minh)] min-w-0 cursor-default flex-col rounded-[calc(var(--fb-radius)-1px)] border p-[var(--fb-card-pad)] outline-none hover:shadow-[0_8px_22px_color-mix(in_oklch,var(--fb-text)_8%,transparent)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${SURFACE_MOTION} ${\n\t\t\t\tdropTarget\n\t\t\t\t\t? 'border-[var(--fb-accent)] bg-[var(--fb-accent-soft)] ring-2 ring-[var(--fb-accent)] ring-offset-2 ring-offset-[var(--fb-surface)]'\n\t\t\t\t\t: selected\n\t\t\t\t\t\t? 'border-[var(--fb-accent)] bg-[var(--fb-accent-soft)]'\n\t\t\t\t\t\t: 'border-[var(--fb-border)] bg-[var(--fb-surface)] hover:border-[var(--fb-border-strong)]'\n\t\t\t}`}\n\t\t\tonClick={onSelect}\n\t\t\tonContextMenu={onContextMenu}\n\t\t\tonDoubleClick={onOpen}\n\t\t\tonDragEnd={canMove ? onDragEnd : undefined}\n\t\t\tonDragOver={item.kind === 'folder' ? onFolderDragOver : undefined}\n\t\t\tonDragStart={canMove ? onDragStart : undefined}\n\t\t\tonDrop={item.kind === 'folder' ? onFolderDrop : undefined}\n\t\t\t{...longPress}\n\t\t\trole=\"gridcell\"\n\t\t\ttabIndex={0}\n\t\t>\n\t\t\t{selectionMode ? (\n\t\t\t\t<button\n\t\t\t\t\taria-label={`Select ${item.name}`}\n\t\t\t\t\taria-pressed={selected}\n\t\t\t\t\tclassName=\"absolute right-0 top-0 z-10 grid size-[calc(var(--fb-gap)*11)] place-items-center text-[var(--fb-accent)]\"\n\t\t\t\t\tdata-fb-touch-control\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\tonToggle()\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t{selected ? (\n\t\t\t\t\t\t<CheckSquare aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Square aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t) : (\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName={`absolute right-2 top-2 grid size-4 place-items-center rounded border text-[10px] ${CONTROL_MOTION} ${\n\t\t\t\t\t\tselected\n\t\t\t\t\t\t\t? 'border-[var(--fb-accent)] bg-[var(--fb-accent)] text-[var(--fb-surface)]'\n\t\t\t\t\t\t\t: 'border-[var(--fb-border)] bg-[var(--fb-surface)] opacity-0 group-hover:opacity-100'\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t{selected ? '✓' : ''}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={`grid h-[var(--fb-thumb-h)] place-items-center rounded-[calc(var(--fb-radius)-3px)] bg-[var(--fb-surface-2)] group-hover:bg-[var(--fb-bg)] ${CONTROL_MOTION}`}\n\t\t\t>\n\t\t\t\t{item.kind === 'folder' ? (\n\t\t\t\t\t<Folder aria-hidden=\"true\" className=\"size-9 text-[var(--fb-folder)]\" />\n\t\t\t\t) : (\n\t\t\t\t\t<File aria-hidden=\"true\" className=\"size-9 text-[var(--fb-muted)]\" />\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{isRenaming ? (\n\t\t\t\t<InlineRenameInput\n\t\t\t\t\titem={item}\n\t\t\t\t\terror={inlineRenameError}\n\t\t\t\t\tlabel={inlineRenameLabel}\n\t\t\t\t\tonCancel={onInlineRenameCancel}\n\t\t\t\t\tonChange={onInlineRenameChange}\n\t\t\t\t\tonCommit={onInlineRenameCommit}\n\t\t\t\t\tvalue={inlineRenameValue}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<button\n\t\t\t\t\tclassName={`mt-2 min-w-0 truncate text-left text-[12.5px] font-semibold text-[var(--fb-text)] outline-none [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] ${narrow ? 'min-h-[calc(var(--fb-gap)*11)]' : ''} ${CONTROL_MOTION}`}\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\tonSelect(event)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t{item.name}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t\t<div className=\"mt-1 text-[11px] text-[var(--fb-muted)]\">\n\t\t\t\t{item.kind === 'folder' ? 'Folder' : formatBytes(item.size ?? 0)}\n\t\t\t</div>\n\t\t\t<ItemMeta item={item} renderItemMeta={renderItemMeta} view=\"grid\" />\n\t\t</article>\n\t)\n}\n\nfunction ItemMeta<TMetadata>({\n\titem,\n\trenderItemMeta,\n\tview\n}: {\n\titem: FileNode<TMetadata>\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\tview: FileBrowserView\n}) {\n\tif (!renderItemMeta) {\n\t\treturn null\n\t}\n\n\tconst content = renderItemMeta(item, { view })\n\treturn content === null || content === undefined || content === false ? null : (\n\t\t<div\n\t\t\tclassName=\"mt-1 min-w-0 max-w-full text-[11px] [overflow-wrap:anywhere] [&_*]:max-w-full\"\n\t\t\tdata-fb-item-meta={view}\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t)\n}\n\nfunction InlineRenameInput<TMetadata>({\n\terror,\n\titem,\n\tlabel,\n\tonCancel,\n\tonChange,\n\tonCommit,\n\tvalue\n}: {\n\terror: string | null\n\titem: FileNode<TMetadata>\n\tlabel: string\n\tonCancel: () => void\n\tonChange: (value: string) => void\n\tonCommit: () => void\n\tvalue: string\n}) {\n\treturn (\n\t\t<div className=\"min-w-0\">\n\t\t\t<input\n\t\t\t\taria-label={`Rename ${label || item.name}`}\n\t\t\t\tautoFocus\n\t\t\t\tclassName={`mt-2 w-full min-w-0 rounded-[calc(var(--fb-radius)-4px)] border border-[var(--fb-accent)] bg-[var(--fb-surface)] px-1.5 py-1 text-[12.5px] font-semibold text-[var(--fb-text)] outline-none ring-2 ring-[var(--fb-accent-soft)] [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:text-[16px] ${CONTROL_MOTION}`}\n\t\t\t\tonBlur={onCommit}\n\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\tonClick={(event) => event.stopPropagation()}\n\t\t\t\tonDoubleClick={(event) => event.stopPropagation()}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\tonCommit()\n\t\t\t\t\t}\n\t\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\tonCancel()\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\tvalue={value}\n\t\t\t/>\n\t\t\t{error ? (\n\t\t\t\t<div\n\t\t\t\t\tclassName={`mt-1 rounded-[calc(var(--fb-radius)-5px)] border border-[var(--fb-danger)] bg-[var(--fb-danger-soft)] px-1.5 py-1 text-[11px] text-[var(--fb-danger)] ${SURFACE_MOTION}`}\n\t\t\t\t\trole=\"alert\"\n\t\t\t\t>\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t)\n}\n\nfunction FileTable<TMetadata>({\n\tbrowser,\n\tcanMove,\n\tfolderDropTargetPath,\n\tinlineRenameError,\n\tinlineRenameLabel,\n\tinlineRenameItem,\n\tinlineRenameValue,\n\tselectedPaths,\n\tonContextMenu,\n\tonDragEnd,\n\tonDragStart,\n\tonFolderDragOver,\n\tonFolderDrop,\n\tonInlineRenameCancel,\n\tonInlineRenameChange,\n\tonInlineRenameCommit,\n\tonOpenItem,\n\tonSelectItem,\n\tonTouchMenu,\n\tnarrow,\n\tselectionMode,\n\tonToggleItem,\n\trenderItemMeta,\n\trootLabel\n}: {\n\tbrowser: BrowserLike<TMetadata>\n\tcanMove: boolean\n\tfolderDropTargetPath: string | null\n\tinlineRenameError: string | null\n\tinlineRenameLabel: string\n\tinlineRenameItem: FileNode<TMetadata> | null\n\tinlineRenameValue: string\n\tselectedPaths: string[]\n\tonContextMenu: (item: FileNode<TMetadata>, event: MouseEvent) => void\n\tonDragEnd: () => void\n\tonDragStart: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonFolderDragOver: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonFolderDrop: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonInlineRenameCancel: () => void\n\tonInlineRenameChange: (value: string) => void\n\tonInlineRenameCommit: () => void\n\tonOpenItem: (item: FileNode<TMetadata>) => void\n\tonSelectItem: (path: string, event: MouseEvent) => void\n\tonTouchMenu: (item: FileNode<TMetadata>) => void\n\tnarrow: boolean\n\tselectionMode: boolean\n\tonToggleItem: (path: string) => void\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\trootLabel: string\n}) {\n\treturn (\n\t\t<table\n\t\t\taria-label={rootLabel}\n\t\t\tclassName={`w-full table-fixed border-separate border-spacing-0 overflow-hidden rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] text-left ${SURFACE_MOTION}`}\n\t\t>\n\t\t\t<thead className=\"text-[11px] text-[var(--fb-muted)]\">\n\t\t\t\t<tr>\n\t\t\t\t\t<th className=\"border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] py-[var(--fb-cell-y)] font-medium\">\n\t\t\t\t\t\tName\n\t\t\t\t\t</th>\n\t\t\t\t\t{!narrow ? (\n\t\t\t\t\t\t<th className=\"w-[22%] border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] py-[var(--fb-cell-y)] font-medium\">\n\t\t\t\t\t\t\tSize\n\t\t\t\t\t\t</th>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{!narrow ? (\n\t\t\t\t\t\t<th className=\"w-[26%] border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] py-[var(--fb-cell-y)] font-medium\">\n\t\t\t\t\t\t\tModified\n\t\t\t\t\t\t</th>\n\t\t\t\t\t) : null}\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t{browser.filteredItems.map((item) => (\n\t\t\t\t\t<TouchRow\n\t\t\t\t\t\taria-selected={selectedPaths.includes(item.path)}\n\t\t\t\t\t\tdata-fb-drop-target={folderDropTargetPath === item.path ? 'true' : undefined}\n\t\t\t\t\t\tdata-fb-path={item.path}\n\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\tfolderDropTargetPath === item.path\n\t\t\t\t\t\t\t\t? `bg-[var(--fb-accent-soft)] ring-2 ring-inset ring-[var(--fb-accent)] ${CONTROL_MOTION}`\n\t\t\t\t\t\t\t\t: selectedPaths.includes(item.path)\n\t\t\t\t\t\t\t\t\t? `bg-[var(--fb-accent-soft)] outline-none focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${CONTROL_MOTION}`\n\t\t\t\t\t\t\t\t\t: `outline-none hover:bg-[var(--fb-bg)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${CONTROL_MOTION}`\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdraggable={canMove && !narrow}\n\t\t\t\t\t\tonLongPress={() => onTouchMenu(item)}\n\t\t\t\t\t\tkey={item.path}\n\t\t\t\t\t\tonClick={(event) => onSelectItem(item.path, event)}\n\t\t\t\t\t\tonContextMenu={(event) => onContextMenu(item, event)}\n\t\t\t\t\t\tonDragEnd={onDragEnd}\n\t\t\t\t\t\tonDragOver={(event) => onFolderDragOver(item, event)}\n\t\t\t\t\t\tonDragStart={(event) => onDragStart(item, event)}\n\t\t\t\t\t\tonDrop={(event) => onFolderDrop(item, event)}\n\t\t\t\t\t\tonDoubleClick={() => onOpenItem(item)}\n\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t>\n\t\t\t\t\t\t<td className=\"border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] py-[var(--fb-cell-y)]\">\n\t\t\t\t\t\t\t<div className=\"flex min-w-0 items-start gap-2\">\n\t\t\t\t\t\t\t\t{selectionMode ? (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\taria-label={`Select ${item.name}`}\n\t\t\t\t\t\t\t\t\t\taria-pressed={selectedPaths.includes(item.path)}\n\t\t\t\t\t\t\t\t\t\tclassName=\"grid size-[calc(var(--fb-gap)*11)] shrink-0 place-items-center text-[var(--fb-accent)]\"\n\t\t\t\t\t\t\t\t\t\tdata-fb-touch-control\n\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\tonToggleItem(item.path)\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{selectedPaths.includes(item.path) ? (\n\t\t\t\t\t\t\t\t\t\t\t<CheckSquare aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<Square aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t{item.kind === 'folder' ? (\n\t\t\t\t\t\t\t\t\t<Folder className=\"mt-0.5 size-4 shrink-0 text-[var(--fb-folder)]\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<File className=\"mt-0.5 size-4 shrink-0 text-[var(--fb-muted)]\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t{inlineRenameItem?.path === item.path ? (\n\t\t\t\t\t\t\t\t\t\t<InlineRenameInput\n\t\t\t\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\t\t\t\terror={inlineRenameError}\n\t\t\t\t\t\t\t\t\t\t\tlabel={inlineRenameLabel}\n\t\t\t\t\t\t\t\t\t\t\tonCancel={onInlineRenameCancel}\n\t\t\t\t\t\t\t\t\t\t\tonChange={onInlineRenameChange}\n\t\t\t\t\t\t\t\t\t\t\tonCommit={onInlineRenameCommit}\n\t\t\t\t\t\t\t\t\t\t\tvalue={inlineRenameValue}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\tclassName={`block max-w-full truncate text-left font-medium [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] ${narrow ? 'min-h-[calc(var(--fb-gap)*11)]' : ''} ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\tonSelectItem(item.path, event)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{item.name}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t<ItemMeta item={item} renderItemMeta={renderItemMeta} view=\"list\" />\n\t\t\t\t\t\t\t\t\t{narrow ? (\n\t\t\t\t\t\t\t\t\t\t<div className=\"mt-[var(--fb-gap)] flex flex-wrap gap-x-[calc(var(--fb-gap)*3)] text-[11px] text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\t\t\t\t\t<span>{item.kind === 'folder' ? 'Folder' : formatBytes(item.size ?? 0)}</span>\n\t\t\t\t\t\t\t\t\t\t\t{item.modifiedAt ? <span>{new Date(item.modifiedAt).toLocaleDateString()}</span> : null}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t{!narrow ? (\n\t\t\t\t\t\t\t<td className=\"border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] py-[var(--fb-cell-y)] text-[12px] text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\t\t{item.kind === 'folder' ? 'Folder' : formatBytes(item.size ?? 0)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{!narrow ? (\n\t\t\t\t\t\t\t<td className=\"border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] py-[var(--fb-cell-y)] text-[12px] text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\t\t{item.modifiedAt ? new Date(item.modifiedAt).toLocaleDateString() : '—'}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</TouchRow>\n\t\t\t\t))}\n\t\t\t</tbody>\n\t\t</table>\n\t)\n}\n\nfunction TouchRow({ onLongPress, ...props }: React.ComponentProps<'tr'> & { onLongPress: () => void }) {\n\tconst longPress = useLongPress(onLongPress)\n\treturn <tr {...props} {...longPress} />\n}\n\nfunction ContextMenu<TMetadata>({\n\tbrowser,\n\tcanDownload,\n\tmenu,\n\tonClose,\n\tonDelete,\n\tonDownload,\n\tonCopy,\n\tonCopyPath,\n\tonCut,\n\tonMove,\n\tonNewFolder,\n\tonPaste,\n\tonRename,\n\tonUpload,\n\treadOnly\n}: {\n\tbrowser: BrowserLike<TMetadata>\n\tcanDownload: boolean\n\tmenu: ContextMenuState<TMetadata>\n\tonClose: () => void\n\tonDelete: () => void\n\tonDownload: () => void\n\tonCopy: () => void\n\tonCopyPath: (item: FileNode<TMetadata>) => void\n\tonCut: () => void\n\tonMove: () => void\n\tonNewFolder: () => void\n\tonPaste: () => void\n\tonRename: (item?: FileNode<TMetadata>) => void\n\tonUpload: () => void\n\treadOnly: boolean\n}) {\n\tconst isItemMenu = menu.target === 'item'\n\tconst isSheet = menu.mode === 'sheet'\n\tconst menuRef = useRef<HTMLDivElement>(null)\n\tconst [position, setPosition] = useState({ left: menu.x, top: menu.y })\n\n\tuseEffect(() => {\n\t\tif (isSheet) return\n\t\tconst element = menuRef.current\n\t\tconst previousFocus = document.activeElement\n\t\tconst reposition = () => {\n\t\t\tconst gap = element ? (Number.parseFloat(getComputedStyle(element).paddingLeft) || 0) * 2 : 0\n\t\t\tconst rect = element?.getBoundingClientRect()\n\t\t\tsetPosition({\n\t\t\t\tleft: Math.max(gap, Math.min(menu.x, document.documentElement.clientWidth - (rect?.width ?? 0) - gap)),\n\t\t\t\ttop: Math.max(gap, Math.min(menu.y, window.innerHeight - (rect?.height ?? 0) - gap))\n\t\t\t})\n\t\t}\n\t\treposition()\n\t\telement?.querySelector<HTMLElement>('button')?.focus()\n\t\twindow.addEventListener('resize', reposition)\n\t\treturn () => {\n\t\t\twindow.removeEventListener('resize', reposition)\n\t\t\tif (previousFocus instanceof HTMLElement && previousFocus.isConnected)\n\t\t\t\tpreviousFocus.focus({ preventScroll: true })\n\t\t}\n\t}, [menu.x, menu.y, isSheet])\n\n\tfunction run(action: () => void) {\n\t\taction()\n\t\tonClose()\n\t}\n\n\tconst content = (\n\t\t<div\n\t\t\taria-label={isItemMenu ? 'Item actions' : 'Folder actions'}\n\t\t\tclassName={`rounded-[calc(var(--fb-radius)-2px)] bg-[var(--fb-surface)] p-1 text-[12px] text-[var(--fb-text)] ${SURFACE_MOTION} ${\n\t\t\t\tisSheet\n\t\t\t\t\t? 'w-full'\n\t\t\t\t\t: 'fixed z-[60] max-h-[calc(100dvh-var(--fb-gap)*4)] min-w-40 max-w-[calc(100%-var(--fb-gap)*4)] overflow-y-auto border border-[var(--fb-border)] shadow-[0_16px_44px_color-mix(in_oklch,var(--fb-text)_16%,transparent)]'\n\t\t\t}`}\n\t\t\tdata-fb-menu={isSheet ? 'sheet' : 'context'}\n\t\t\trole=\"menu\"\n\t\t\tref={menuRef}\n\t\t\tstyle={isSheet ? undefined : position}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key === 'Escape' || (event.key === 'Tab' && !isSheet)) {\n\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\tonClose()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return\n\t\t\t\tevent.preventDefault()\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tconst buttons = Array.from(event.currentTarget.querySelectorAll<HTMLButtonElement>('button'))\n\t\t\t\tconst index = buttons.indexOf(document.activeElement as HTMLButtonElement)\n\t\t\t\tconst next =\n\t\t\t\t\tevent.key === 'Home'\n\t\t\t\t\t\t? 0\n\t\t\t\t\t\t: event.key === 'End'\n\t\t\t\t\t\t\t? buttons.length - 1\n\t\t\t\t\t\t\t: (index + (event.key === 'ArrowDown' ? 1 : -1) + buttons.length) % buttons.length\n\t\t\t\tbuttons[next]?.focus()\n\t\t\t}}\n\t\t>\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.rename ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(() => onRename(menu.item))}>Rename</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.move ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(onMove)}>Move</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.copy ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(onCopy)}>Copy</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.move ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(onCut)}>Cut</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu ? (\n\t\t\t\t<>\n\t\t\t\t\t<ContextMenuButton onClick={() => run(() => onCopyPath(menu.item))}>\n\t\t\t\t\t\t{browser.selectedPaths.includes(menu.item.path) && browser.selectedPaths.length > 1\n\t\t\t\t\t\t\t? 'Copy paths'\n\t\t\t\t\t\t\t: 'Copy path'}\n\t\t\t\t\t</ContextMenuButton>\n\t\t\t\t\t{canDownload ? <ContextMenuButton onClick={() => run(onDownload)}>Download</ContextMenuButton> : null}\n\t\t\t\t\t{!readOnly ? (\n\t\t\t\t\t\t<ContextMenuButton\n\t\t\t\t\t\t\tdanger\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tonDelete()\n\t\t\t\t\t\t\t\tonClose()\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t</ContextMenuButton>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t{!readOnly ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{browser.capabilities.createFolder ? (\n\t\t\t\t\t\t\t\t<ContextMenuButton onClick={() => run(onNewFolder)}>New folder</ContextMenuButton>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<ContextMenuButton onClick={() => run(onUpload)}>Upload</ContextMenuButton>\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{!readOnly && browser.clipboard ? (\n\t\t\t\t\t\t<ContextMenuButton onClick={() => run(onPaste)}>Paste here</ContextMenuButton>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t)\n\treturn isSheet ? (\n\t\t<ActionSheet label={isItemMenu ? 'Item actions' : 'Folder actions'} onClose={onClose}>\n\t\t\t{content}\n\t\t</ActionSheet>\n\t) : (\n\t\tcontent\n\t)\n}\n\nfunction ContextMenuButton({ children, danger, onClick }: { children: string; danger?: boolean; onClick: () => void }) {\n\treturn (\n\t\t<button\n\t\t\tclassName={`flex min-h-[var(--fb-control-h)] w-full items-center rounded-[calc(var(--fb-radius)-4px)] px-2 text-left font-medium outline-none hover:bg-[var(--fb-bg)] focus:bg-[var(--fb-bg)] ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\t\t\tdanger ? 'text-[var(--fb-danger)]' : ''\n\t\t\t}`}\n\t\t\tonClick={onClick}\n\t\t\trole=\"menuitem\"\n\t\t\ttype=\"button\"\n\t\t>\n\t\t\t{children}\n\t\t</button>\n\t)\n}\n\nfunction UploadConflictDialog({\n\tapplyToAll,\n\tnarrow,\n\tcurrentPath,\n\tonApplyToAllChange,\n\tonCancel,\n\tonResolve,\n\tqueue,\n\tresolutions\n}: {\n\tapplyToAll: boolean\n\tnarrow: boolean\n\tcurrentPath: string\n\tonApplyToAllChange: (value: boolean) => void\n\tonCancel: () => void\n\tonResolve: (resolution: FileBrowserUploadConflictResolution) => void\n\tqueue: UploadConflictQueue\n\tresolutions: readonly FileBrowserUploadConflictResolution[]\n}) {\n\tconst candidate = queue.candidates[queue.index]\n\tconst path = joinUploadRelativePath(currentPath, candidate.relativePath)\n\tconst conflictIndex = queue.conflictPaths.indexOf(path) + 1\n\n\treturn (\n\t\t<ResponsiveDialog label=\"File conflict\" narrow={narrow} onClose={onCancel}>\n\t\t\t<div\n\t\t\t\tclassName={`w-[min(420px,100%)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 shadow-[0_18px_50px_color-mix(in_oklch,var(--fb-text)_18%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t>\n\t\t\t\t<h2 className=\"m-0 text-[14px] font-semibold\">File conflict</h2>\n\t\t\t\t<p className=\"mt-2 text-[12px] text-[var(--fb-muted)]\">\n\t\t\t\t\t{candidate.relativePath} already exists in this folder.\n\t\t\t\t</p>\n\t\t\t\t<div\n\t\t\t\t\tclassName={`mt-3 rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-bg)] p-2 text-[12px] ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\tConflict {conflictIndex} of {queue.conflictPaths.length}\n\t\t\t\t</div>\n\t\t\t\t<label className=\"mt-3 flex min-h-[calc(var(--fb-gap)*11)] items-center gap-2 text-[12px] font-medium text-[var(--fb-muted)]\">\n\t\t\t\t\t<input checked={applyToAll} onChange={(event) => onApplyToAllChange(event.target.checked)} type=\"checkbox\" />\n\t\t\t\t\tApply to all conflicts\n\t\t\t\t</label>\n\t\t\t\t<div\n\t\t\t\t\tclassName={`mt-4 flex flex-wrap justify-end gap-2 ${narrow ? 'flex-col [&>button]:w-full [&>button]:justify-center' : ''}`}\n\t\t\t\t>\n\t\t\t\t\t<button className={commandButton(false)} onClick={onCancel} type=\"button\">\n\t\t\t\t\t\tCancel\n\t\t\t\t\t</button>\n\t\t\t\t\t{resolutions.map((resolution) => (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tclassName={resolution === 'keep-both' ? primaryButton() : commandButton(false)}\n\t\t\t\t\t\t\tkey={resolution}\n\t\t\t\t\t\t\tonClick={() => onResolve(resolution)}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{formatUploadConflictResolution(resolution)}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</ResponsiveDialog>\n\t)\n}\n\nfunction BulkFailureDialog({\n\terror,\n\tnarrow,\n\tonClose\n}: {\n\terror: FileBrowserBulkActionError\n\tnarrow: boolean\n\tonClose: () => void\n}) {\n\tconst completedCount = error.succeededPaths.length\n\n\treturn (\n\t\t<ResponsiveDialog label=\"Partial bulk failure\" narrow={narrow} onClose={onClose}>\n\t\t\t<div\n\t\t\t\tclassName={`w-[min(440px,100%)] rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 shadow-[0_18px_50px_color-mix(in_oklch,var(--fb-text)_18%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t>\n\t\t\t\t<h2 className=\"m-0 text-[14px] font-semibold\">Partial bulk failure</h2>\n\t\t\t\t<p className=\"mt-2 text-[12px] text-[var(--fb-muted)]\">\n\t\t\t\t\t{completedCount} of {error.totalCount} completed\n\t\t\t\t</p>\n\t\t\t\t<ul\n\t\t\t\t\tclassName={`mt-3 max-h-40 overflow-auto rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-bg)] p-2 text-[12px] ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\t{error.failures.map((failure) => (\n\t\t\t\t\t\t<li className=\"py-1\" key={failure.path}>\n\t\t\t\t\t\t\t<div className=\"truncate font-medium\">\n\t\t\t\t\t\t\t\t{failure.path.split('/').filter(Boolean).at(-1) ?? failure.path}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"text-[var(--fb-danger)]\">{failure.message}</div>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t\t<div className=\"mt-4 flex justify-end\">\n\t\t\t\t\t<button className={primaryButton()} onClick={onClose} type=\"button\">\n\t\t\t\t\t\tOK\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</ResponsiveDialog>\n\t)\n}\n\nfunction MoveDestinationPicker({\n\tcurrentPath,\n\tdestinations,\n\terror,\n\tonSelect,\n\trootLabel,\n\tselectedPath,\n\tstatus\n}: {\n\tcurrentPath: string\n\tdestinations: MoveDestination[]\n\terror: string | null\n\tonSelect: (path: string) => void\n\trootLabel: string\n\tselectedPath: string\n\tstatus: MoveDestinationStatus\n}) {\n\treturn (\n\t\t<div\n\t\t\tclassName={`mt-3 max-h-64 overflow-auto rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-bg)] p-2 ${SURFACE_MOTION}`}\n\t\t>\n\t\t\t<MoveDestinationButton\n\t\t\t\tactive={selectedPath === currentPath}\n\t\t\t\tlabel=\"Current folder\"\n\t\t\t\tonClick={() => onSelect(currentPath)}\n\t\t\t\tpath={currentPath}\n\t\t\t/>\n\t\t\t<MoveDestinationButton active={selectedPath === '/'} label={rootLabel} onClick={() => onSelect('/')} path=\"/\" />\n\t\t\t{status === 'loading' ? (\n\t\t\t\t<div className=\"px-2 py-3 text-[12px] text-[var(--fb-muted)]\">Loading folders</div>\n\t\t\t) : null}\n\t\t\t{status === 'error' ? (\n\t\t\t\t<div className=\"px-2 py-3 text-[12px] text-[var(--fb-danger)]\">{error ?? 'Could not load folders'}</div>\n\t\t\t) : null}\n\t\t\t{status === 'ready' && destinations.length === 0 ? (\n\t\t\t\t<div className=\"px-2 py-3 text-[12px] text-[var(--fb-muted)]\">No folders available.</div>\n\t\t\t) : null}\n\t\t\t{destinations.map((destination) => (\n\t\t\t\t<MoveDestinationButton\n\t\t\t\t\tactive={selectedPath === destination.path}\n\t\t\t\t\tdepth={destination.depth}\n\t\t\t\t\tkey={destination.path}\n\t\t\t\t\tlabel={destination.name}\n\t\t\t\t\tonClick={() => onSelect(destination.path)}\n\t\t\t\t\tpath={destination.path}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t)\n}\n\nfunction MoveDestinationButton({\n\tactive,\n\tdepth = 0,\n\tlabel,\n\tonClick,\n\tpath\n}: {\n\tactive: boolean\n\tdepth?: number\n\tlabel: string\n\tonClick: () => void\n\tpath: string\n}) {\n\treturn (\n\t\t<button\n\t\t\taria-label={`Move destination ${path}`}\n\t\t\tclassName={`mt-1 flex min-h-[var(--fb-control-h)] w-full min-w-0 items-center gap-2 rounded-[calc(var(--fb-radius)-4px)] px-2 text-left text-[12px] font-medium ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\t\t\tactive ? 'bg-[var(--fb-accent-soft)] text-[var(--fb-accent)]' : 'hover:bg-[var(--fb-surface)]'\n\t\t\t}`}\n\t\t\tonClick={onClick}\n\t\t\tstyle={{ paddingLeft: `min(40%, calc((${depth} * 6 + 2) * var(--fb-gap)))` }}\n\t\t\ttype=\"button\"\n\t\t>\n\t\t\t<Folder aria-hidden=\"true\" className=\"size-4 shrink-0\" />\n\t\t\t<span className=\"truncate\">{label}</span>\n\t\t</button>\n\t)\n}\n\nfunction ActionBar({\n\tselectedCount,\n\titemCount,\n\tcanRename,\n\tcanMove,\n\tcanCopy,\n\tcanCut,\n\tcanDelete,\n\tcanDownload,\n\tonRename,\n\tonMove,\n\tonCopy,\n\tonCut,\n\tonDelete,\n\tonDownload,\n\tonSelectAll,\n\tonSelectNone\n}: {\n\tselectedCount: number\n\titemCount: number\n\tcanRename: boolean\n\tcanMove: boolean\n\tcanCopy: boolean\n\tcanCut: boolean\n\tcanDelete: boolean\n\tcanDownload: boolean\n\tonRename: () => void\n\tonMove: () => void\n\tonCopy: () => void\n\tonCut: () => void\n\tonDelete: () => void\n\tonDownload: () => void\n\tonSelectAll: () => void\n\tonSelectNone: () => void\n}) {\n\tconst hasSelection = selectedCount > 0\n\n\treturn (\n\t\t<div\n\t\t\taria-label=\"Selection actions\"\n\t\t\tclassName={`flex min-h-11 flex-wrap items-center gap-2 border-b border-[var(--fb-border)] px-[var(--fb-pad)] py-1.5 ${SURFACE_MOTION} ${\n\t\t\t\thasSelection ? 'bg-[var(--fb-accent-soft)]' : 'bg-[var(--fb-surface)]'\n\t\t\t}`}\n\t\t\trole=\"toolbar\"\n\t\t>\n\t\t\t<span className=\"mr-auto text-[12px] font-semibold\">{selectedCount} selected</span>\n\t\t\t<button className={commandButton(false)} disabled={itemCount === 0} onClick={onSelectAll} type=\"button\">\n\t\t\t\t<CheckSquare className=\"size-4\" />\n\t\t\t\tSelect all\n\t\t\t</button>\n\t\t\t<button className={commandButton(false)} disabled={!hasSelection} onClick={onSelectNone} type=\"button\">\n\t\t\t\t<XIcon className=\"size-4\" />\n\t\t\t\tSelect none\n\t\t\t</button>\n\t\t\t{hasSelection && canRename && selectedCount === 1 ? (\n\t\t\t\t<button className={commandButton(false)} onClick={() => onRename()} type=\"button\">\n\t\t\t\t\t<Pencil className=\"size-4\" />\n\t\t\t\t\tRename\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canMove ? (\n\t\t\t\t<button className={commandButton(false)} onClick={onMove} type=\"button\">\n\t\t\t\t\t<FolderInput className=\"size-4\" />\n\t\t\t\t\tMove\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canCopy ? (\n\t\t\t\t<button className={commandButton(false)} onClick={onCopy} type=\"button\">\n\t\t\t\t\t<CopyIcon className=\"size-4\" />\n\t\t\t\t\tCopy\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canCut ? (\n\t\t\t\t<button className={commandButton(false)} onClick={onCut} type=\"button\">\n\t\t\t\t\t<Scissors className=\"size-4\" />\n\t\t\t\t\tCut\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canDownload ? (\n\t\t\t\t<button className={commandButton(false)} onClick={onDownload} type=\"button\">\n\t\t\t\t\t<Download className=\"size-4\" />\n\t\t\t\t\tDownload\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canDelete ? (\n\t\t\t\t<button className={dangerButton()} onClick={onDelete} type=\"button\">\n\t\t\t\t\t<Trash2 className=\"size-4\" />\n\t\t\t\t\tDelete\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t</div>\n\t)\n}\n\nfunction Breadcrumbs({\n\tpath,\n\tonNavigate,\n\trootLabel,\n\tnarrow\n}: {\n\tpath: string\n\tonNavigate: (path: string) => Promise<void>\n\trootLabel: string\n\tnarrow: boolean\n}) {\n\tconst [ancestorsOpen, setAncestorsOpen] = useState(false)\n\tconst parts = path.split('/').filter(Boolean)\n\tconst crumbs = [{ label: rootLabel, path: '/' }].concat(\n\t\tparts.map((part, index) => ({\n\t\t\tlabel: part,\n\t\t\tpath: `/${parts.slice(0, index + 1).join('/')}`\n\t\t}))\n\t)\n\tconst visibleCrumbs: VisibleBreadcrumbCrumb[] =\n\t\tnarrow && crumbs.length > 1\n\t\t\t? [\n\t\t\t\t\t{ kind: 'collapsed', key: 'collapsed' },\n\t\t\t\t\t{ ...crumbs[crumbs.length - 1], kind: 'crumb', key: path }\n\t\t\t\t]\n\t\t\t: getVisibleBreadcrumbs(crumbs)\n\n\treturn (\n\t\t<nav aria-label=\"Breadcrumb\" className=\"flex min-w-0 max-w-full items-center gap-1\">\n\t\t\t{narrow && parts.length > 0 ? (\n\t\t\t\t<button\n\t\t\t\t\taria-label=\"Parent folder\"\n\t\t\t\t\tclassName={toolButton(false)}\n\t\t\t\t\tonClick={() => void onNavigate(getFileBrowserDirname(path))}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<ChevronLeft aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{visibleCrumbs.map((crumb, index) => (\n\t\t\t\t<span className=\"flex min-w-0 items-center gap-1 last:flex-1\" key={crumb.key}>\n\t\t\t\t\t{index > 0 ? (\n\t\t\t\t\t\t<span className=\"text-[var(--fb-muted)]\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t/\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{crumb.kind === 'collapsed' ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label=\"Collapsed breadcrumb\"\n\t\t\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t\t\t\tclassName={`${toolButton(false)} border-0`}\n\t\t\t\t\t\t\tonClick={() => setAncestorsOpen(true)}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t...\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tclassName={`min-h-[var(--fb-control-h)] min-w-[var(--fb-control-h)] max-w-[160px] truncate rounded-[calc(var(--fb-radius)-4px)] px-1.5 py-1 text-[12px] font-semibold hover:bg-[var(--fb-bg)] [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:min-w-[calc(var(--fb-gap)*11)] ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\tonClick={() => void onNavigate(crumb.path)}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{crumb.label}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</span>\n\t\t\t))}\n\t\t\t{ancestorsOpen ? (\n\t\t\t\t<ActionSheet label=\"Folder path\" onClose={() => setAncestorsOpen(false)}>\n\t\t\t\t\t<div className=\"flex min-w-0 flex-col\">\n\t\t\t\t\t\t{crumbs.map((crumb) => (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tkey={crumb.path}\n\t\t\t\t\t\t\t\tclassName={`${commandButton(false)} my-[var(--fb-gap)] block w-full truncate text-left`}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetAncestorsOpen(false)\n\t\t\t\t\t\t\t\t\tvoid onNavigate(crumb.path)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{crumb.label}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\t\t</nav>\n\t)\n}\n\ntype BreadcrumbCrumb = {\n\tlabel: string\n\tpath: string\n}\n\ntype VisibleBreadcrumbCrumb =\n\t| (BreadcrumbCrumb & {\n\t\t\tkind: 'crumb'\n\t\t\tkey: string\n\t })\n\t| {\n\t\t\tkind: 'collapsed'\n\t\t\tkey: string\n\t }\n\nfunction getVisibleBreadcrumbs(crumbs: BreadcrumbCrumb[]): VisibleBreadcrumbCrumb[] {\n\tif (crumbs.length <= 4) {\n\t\treturn crumbs.map((crumb) => ({ ...crumb, kind: 'crumb', key: crumb.path }))\n\t}\n\n\treturn [\n\t\t{ ...crumbs[0], kind: 'crumb', key: crumbs[0].path },\n\t\t{ ...crumbs[1], kind: 'crumb', key: crumbs[1].path },\n\t\t{ kind: 'collapsed', key: 'collapsed' },\n\t\t...crumbs.slice(-2).map((crumb) => ({\n\t\t\t...crumb,\n\t\t\tkind: 'crumb' as const,\n\t\t\tkey: crumb.path\n\t\t}))\n\t]\n}\n\nfunction DetailsPanel<TMetadata>({\n\tcanDownload,\n\titem,\n\tonCopyPath,\n\tonDownload,\n\trenderDetailsContent,\n\tselectedCount,\n\ttotalBytes,\n\tsheet\n}: {\n\tcanDownload: boolean\n\titem: FileNode<TMetadata> | null\n\tonCopyPath: () => void\n\tonDownload: () => void\n\trenderDetailsContent?: (item: FileNode<TMetadata>, defaultContent: ReactNode) => ReactNode\n\tselectedCount: number\n\ttotalBytes: number\n\tsheet: boolean\n}) {\n\tconst panelClass = `min-w-0 max-w-full shrink-0 bg-[var(--fb-surface)] [overflow-wrap:anywhere] [&_*]:max-w-full ${SURFACE_MOTION} ${\n\t\tsheet\n\t\t\t? 'w-full'\n\t\t\t: 'w-[var(--fb-panel-w)] rounded-r-[var(--fb-radius)] border-l border-[var(--fb-border)] p-[var(--fb-panel-pad)]'\n\t}`\n\tif (!item) {\n\t\treturn (\n\t\t\t<aside aria-label=\"Details\" className={`${panelClass} flex`}>\n\t\t\t\t<div className=\"flex min-h-full flex-1 flex-col items-center justify-center text-center\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={`grid h-28 w-full place-items-center rounded-[var(--fb-radius)] bg-[var(--fb-bg)] ${SURFACE_MOTION}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Square className=\"size-12 text-[var(--fb-muted)]\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<h2 className=\"mt-4 text-[14px] font-semibold\">No item selected</h2>\n\t\t\t\t</div>\n\t\t\t</aside>\n\t\t)\n\t}\n\n\tif (selectedCount > 1) {\n\t\treturn (\n\t\t\t<aside aria-label=\"Details\" className={panelClass}>\n\t\t\t\t<div className={`grid h-28 place-items-center rounded-[var(--fb-radius)] bg-[var(--fb-bg)] ${SURFACE_MOTION}`}>\n\t\t\t\t\t<CopyIcon className=\"size-12 text-[var(--fb-muted)]\" />\n\t\t\t\t</div>\n\t\t\t\t<h2 className=\"mt-4 text-[14px] font-semibold\">{formatItemCount(selectedCount)} selected</h2>\n\t\t\t\t<dl className=\"mt-3 space-y-2 text-[12px]\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Total size</dt>\n\t\t\t\t\t\t<dd className=\"font-medium\">{formatBytes(totalBytes)}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t</dl>\n\t\t\t\t{canDownload ? (\n\t\t\t\t\t<button\n\t\t\t\t\t\taria-label={`Download ${formatItemCount(selectedCount)}`}\n\t\t\t\t\t\tclassName={`${commandButton(false)} mt-4 w-full justify-center`}\n\t\t\t\t\t\tonClick={onDownload}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Download className=\"size-4\" />\n\t\t\t\t\t\tDownload\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t\t<button\n\t\t\t\t\taria-label={`Copy ${formatItemCount(selectedCount)} paths`}\n\t\t\t\t\tclassName={`${commandButton(false)} mt-2 w-full justify-center`}\n\t\t\t\t\tonClick={onCopyPath}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<CopyIcon className=\"size-4\" />\n\t\t\t\t\tCopy paths\n\t\t\t\t</button>\n\t\t\t</aside>\n\t\t)\n\t}\n\n\tconst defaultContent = (\n\t\t<>\n\t\t\t<div className={`grid h-28 place-items-center rounded-[var(--fb-radius)] bg-[var(--fb-bg)] ${SURFACE_MOTION}`}>\n\t\t\t\t{item.kind === 'folder' ? (\n\t\t\t\t\t<Folder className=\"size-12 text-[var(--fb-folder)]\" />\n\t\t\t\t) : (\n\t\t\t\t\t<File className=\"size-12 text-[var(--fb-muted)]\" />\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<h2 className=\"mt-4 truncate text-[14px] font-semibold\">{item.name}</h2>\n\t\t\t<dl className=\"mt-3 space-y-2 text-[12px]\">\n\t\t\t\t<div>\n\t\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Path</dt>\n\t\t\t\t\t<dd className=\"truncate font-medium\">{item.path}</dd>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Type</dt>\n\t\t\t\t\t<dd className=\"font-medium\">{item.kind}</dd>\n\t\t\t\t</div>\n\t\t\t\t{item.kind === 'file' ? (\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Size</dt>\n\t\t\t\t\t\t<dd className=\"font-medium\">{formatBytes(item.size ?? 0)}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t</dl>\n\t\t\t{canDownload ? (\n\t\t\t\t<button\n\t\t\t\t\taria-label={`Download ${item.name}`}\n\t\t\t\t\tclassName={`${commandButton(false)} mt-4 w-full justify-center`}\n\t\t\t\t\tonClick={onDownload}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<Download className=\"size-4\" />\n\t\t\t\t\tDownload\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t<button\n\t\t\t\taria-label={`Copy path of ${item.name}`}\n\t\t\t\tclassName={`${commandButton(false)} mt-2 w-full justify-center`}\n\t\t\t\tonClick={onCopyPath}\n\t\t\t\ttype=\"button\"\n\t\t\t>\n\t\t\t\t<CopyIcon className=\"size-4\" />\n\t\t\t\tCopy path\n\t\t\t</button>\n\t\t</>\n\t)\n\n\treturn (\n\t\t<aside aria-label=\"Details\" className={panelClass}>\n\t\t\t{renderDetailsContent ? renderDetailsContent(item, defaultContent) : defaultContent}\n\t\t</aside>\n\t)\n}\n\nfunction PreviewOriginalLink<TMetadata>({ preview }: { preview: PreviewState<TMetadata> }) {\n\tif (!preview.url) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<a\n\t\t\taria-label={`Open original ${preview.item.name}`}\n\t\t\tclassName={`mt-4 inline-flex min-h-[var(--fb-control-h)] items-center rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] px-2.5 text-[12px] font-medium text-[var(--fb-accent)] outline-none hover:bg-[var(--fb-bg)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${TOUCH_CONTROL} ${CONTROL_MOTION}`}\n\t\t\thref={preview.url}\n\t\t\trel=\"noreferrer\"\n\t\t\ttarget=\"_blank\"\n\t\t>\n\t\t\tOpen original\n\t\t</a>\n\t)\n}\n\nfunction SkeletonGrid({ rootLabel }: { rootLabel: string }) {\n\treturn (\n\t\t<div\n\t\t\taria-label={rootLabel}\n\t\t\tclassName=\"grid min-w-0 grid-cols-[repeat(2,minmax(0,1fr))] gap-[var(--fb-grid-gap)] @min-[40rem]/fb:grid-cols-[repeat(auto-fill,minmax(min(100%,var(--fb-card-min)),1fr))]\"\n\t\t\trole=\"grid\"\n\t\t>\n\t\t\t{Array.from({ length: 8 }, (_, index) => (\n\t\t\t\t<div\n\t\t\t\t\tclassName={`min-h-[var(--fb-card-minh)] animate-pulse rounded-[calc(var(--fb-radius)-1px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-[var(--fb-card-pad)] ${SURFACE_MOTION}`}\n\t\t\t\t\tkey={index}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"h-[var(--fb-thumb-h)] rounded-[calc(var(--fb-radius)-3px)] bg-[var(--fb-surface-2)]\" />\n\t\t\t\t\t<div className=\"mt-3 h-3 w-3/4 rounded bg-[var(--fb-surface-2)]\" />\n\t\t\t\t\t<div className=\"mt-2 h-3 w-1/2 rounded bg-[var(--fb-surface-2)]\" />\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t)\n}\n\nfunction StateMessage({ title, value, tone }: { title: ReactNode; value?: ReactNode; tone?: 'danger' }) {\n\treturn (\n\t\t<div\n\t\t\tclassName={`grid min-h-[min(280px,50svh)] min-w-0 place-items-center rounded-[var(--fb-radius)] border border-dashed border-[var(--fb-border)] bg-[var(--fb-surface)] p-[var(--fb-pad)] text-center [overflow-wrap:anywhere] [&_*]:max-w-full ${SURFACE_MOTION}`}\n\t\t>\n\t\t\t<div>\n\t\t\t\t<div className={`font-semibold ${tone === 'danger' ? 'text-[var(--fb-danger)]' : ''}`}>{title}</div>\n\t\t\t\t{value === undefined ? null : <div className=\"mt-1 text-[12px] text-[var(--fb-muted)]\">{value}</div>}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction UploadRejectionAlert({\n\tonDismiss,\n\trejections\n}: {\n\tonDismiss: () => void\n\trejections: FileBrowserUploadRejection[]\n}) {\n\treturn (\n\t\t<div\n\t\t\taria-label=\"Upload rejected\"\n\t\t\tclassName=\"min-w-0 border-b border-[var(--fb-border)] bg-[var(--fb-danger-soft)] px-3 py-2 text-[12px] text-[var(--fb-text)] [overflow-wrap:anywhere]\"\n\t\t\trole=\"alert\"\n\t\t>\n\t\t\t<div className=\"flex items-start gap-3\">\n\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t<div className=\"font-semibold text-[var(--fb-danger)]\">Upload rejected</div>\n\t\t\t\t\t<ul className=\"mt-1 space-y-1\">\n\t\t\t\t\t\t{rejections.map((rejection) => (\n\t\t\t\t\t\t\t<li className=\"min-w-0\" key={rejection.relativePath}>\n\t\t\t\t\t\t\t\t<span className=\"font-medium\">{rejection.relativePath}</span>\n\t\t\t\t\t\t\t\t<span className=\"text-[var(--fb-muted)]\"> {rejection.reasons.join('; ')}</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\taria-label=\"Dismiss upload rejection\"\n\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\tonClick={onDismiss}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\tDismiss\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction selectWithEvent<TMetadata>(\n\tbrowser: BrowserLike<TMetadata>,\n\tpath: string,\n\tevent: MouseEvent | KeyboardEvent,\n\toptions: {\n\t\tcancelPendingSelectedItemUnselect: () => void\n\t\tscheduleSelectedItemUnselect: (path: string) => void\n\t}\n) {\n\tif ('shiftKey' in event && event.shiftKey) {\n\t\toptions.cancelPendingSelectedItemUnselect()\n\t\tbrowser.selectRange(path)\n\t} else if ('metaKey' in event && (event.metaKey || event.ctrlKey)) {\n\t\toptions.cancelPendingSelectedItemUnselect()\n\t\tbrowser.toggleSelection(path)\n\t} else if (browser.selectedPaths.length === 1 && browser.selectedPaths[0] === path) {\n\t\toptions.scheduleSelectedItemUnselect(path)\n\t} else {\n\t\toptions.cancelPendingSelectedItemUnselect()\n\t\tbrowser.selectOnly(path)\n\t}\n}\n\nfunction hasSelectionModifier(event: MouseEvent | KeyboardEvent): boolean {\n\treturn Boolean('shiftKey' in event && (event.shiftKey || event.metaKey || event.ctrlKey))\n}\n\nfunction isKeyboardNavigationKey(key: string) {\n\treturn ['ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'End', 'Home'].includes(key)\n}\n\nfunction getNextKeyboardIndex(key: string, currentIndex: number, length: number) {\n\tif (key === 'Home') {\n\t\treturn 0\n\t}\n\tif (key === 'End') {\n\t\treturn length - 1\n\t}\n\tif (key === 'ArrowUp' || key === 'ArrowLeft') {\n\t\treturn Math.max(0, currentIndex - 1)\n\t}\n\treturn Math.min(length - 1, currentIndex + 1)\n}\n\nfunction escapeAttributeSelector(value: string) {\n\tif (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n\t\treturn CSS.escape(value)\n\t}\n\n\treturn value.replace(/[\"\\\\]/g, '\\\\$&')\n}\n\nfunction getDraggedPaths(dataTransfer: DataTransfer) {\n\tif (typeof dataTransfer.getData !== 'function') {\n\t\treturn []\n\t}\n\n\tconst raw = dataTransfer.getData(FILE_BROWSER_DRAG_MIME)\n\tif (!raw) {\n\t\treturn []\n\t}\n\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown\n\t\tif (!Array.isArray(parsed)) {\n\t\t\treturn []\n\t\t}\n\t\treturn parsed.filter((path): path is string => typeof path === 'string').map(normalizeFileBrowserPath)\n\t} catch {\n\t\treturn []\n\t}\n}\n\nfunction getErrorState(error: Error | null) {\n\tif (isAccessDeniedError(error)) {\n\t\treturn {\n\t\t\ttitle: 'Access denied',\n\t\t\tvalue: error?.message ?? 'You do not have access to this folder.'\n\t\t}\n\t}\n\n\treturn {\n\t\ttitle: 'Could not load this folder',\n\t\tvalue: error?.message ?? 'Unknown error'\n\t}\n}\n\nfunction isAccessDeniedError(error: Error | null) {\n\tif (!error) {\n\t\treturn false\n\t}\n\n\tconst metadata = error as Error & {\n\t\tcode?: unknown\n\t\tstatus?: unknown\n\t\tstatusCode?: unknown\n\t}\n\treturn (\n\t\tmetadata.status === 403 ||\n\t\tmetadata.statusCode === 403 ||\n\t\tmetadata.code === 'access_denied' ||\n\t\tmetadata.code === 'forbidden' ||\n\t\tmetadata.code === 'permission_denied'\n\t)\n}\n\nfunction toErrorMessage(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error)\n}\n\nfunction isEditableEventTarget(target: EventTarget | null): boolean {\n\tif (!(target instanceof HTMLElement)) {\n\t\treturn false\n\t}\n\n\treturn target.isContentEditable || ['INPUT', 'SELECT', 'TEXTAREA'].includes(target.tagName)\n}\n\nfunction formatBytes(bytes: number) {\n\tif (bytes < 1024) {\n\t\treturn `${bytes} B`\n\t}\n\tconst kib = bytes / 1024\n\tif (kib < 1024) {\n\t\treturn `${kib.toFixed(1)} KB`\n\t}\n\treturn `${(kib / 1024).toFixed(1)} MB`\n}\n\nfunction formatItemCount(count: number) {\n\treturn `${count} ${count === 1 ? 'item' : 'items'}`\n}\n\nfunction normalizeUploadConflictResolutions(resolutions: readonly FileBrowserUploadConflictResolution[]) {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\tresolutions.filter((resolution) =>\n\t\t\t\tDEFAULT_UPLOAD_CONFLICT_RESOLUTIONS.includes(resolution as (typeof DEFAULT_UPLOAD_CONFLICT_RESOLUTIONS)[number])\n\t\t\t)\n\t\t)\n\t)\n}\n\nfunction formatUploadConflictResolution(resolution: FileBrowserUploadConflictResolution) {\n\tif (resolution === 'keep-both') {\n\t\treturn 'Keep both'\n\t}\n\treturn resolution === 'replace' ? 'Replace' : 'Skip'\n}\n\nfunction canDownloadItems<TMetadata>(items: FileNode<TMetadata>[], supportsBulkDownload: boolean) {\n\treturn items.length === 1 && items[0].kind === 'file' ? true : items.length > 0 && supportsBulkDownload\n}\n\nfunction formatScreenReaderStatus({\n\tcurrentPath,\n\titemCount,\n\trootLabel,\n\tselectedCount,\n\tstatus\n}: {\n\tcurrentPath: string\n\titemCount: number\n\trootLabel: string\n\tselectedCount: number\n\tstatus: string\n}) {\n\tconst folderName = currentPath === '/' ? rootLabel : (currentPath.split('/').filter(Boolean).at(-1) ?? rootLabel)\n\treturn `${folderName} ${status}. ${itemCount} ${itemCount === 1 ? 'item' : 'items'}. ${selectedCount} selected.`\n}\n\nfunction toolButton(active: boolean) {\n\treturn `inline-flex h-[var(--fb-control-h)] min-w-[var(--fb-control-h)] items-center justify-center gap-1 rounded-[calc(var(--fb-radius)-3px)] border px-2 text-[12px] font-medium outline-none disabled:opacity-45 focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\tactive\n\t\t\t? 'border-[var(--fb-accent)] bg-[var(--fb-accent-soft)] text-[var(--fb-accent)]'\n\t\t\t: 'border-[var(--fb-border)] bg-[var(--fb-surface)] text-[var(--fb-muted)] hover:bg-[var(--fb-bg)]'\n\t}`\n}\n\nfunction commandButton(active: boolean) {\n\treturn `inline-flex h-[var(--fb-control-h)] items-center gap-1.5 rounded-[calc(var(--fb-radius)-3px)] border px-2.5 text-[12px] font-medium outline-none disabled:cursor-not-allowed disabled:opacity-45 focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\tactive\n\t\t\t? 'border-[var(--fb-accent)] bg-[var(--fb-accent-soft)] text-[var(--fb-accent)]'\n\t\t\t: 'border-[var(--fb-border)] bg-[var(--fb-surface)] text-[var(--fb-text)] hover:bg-[var(--fb-bg)]'\n\t}`\n}\n\nfunction primaryButton() {\n\treturn `inline-flex h-[var(--fb-control-h)] items-center gap-1.5 rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-accent)] bg-[var(--fb-accent)] px-2.5 text-[12px] font-semibold text-[var(--fb-surface)] outline-none hover:opacity-90 focus:ring-2 focus:ring-[var(--fb-accent-soft)] ${TOUCH_CONTROL} ${CONTROL_MOTION}`\n}\n\nfunction dangerButton() {\n\treturn `inline-flex h-[var(--fb-control-h)] items-center gap-1.5 rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-danger)] bg-[var(--fb-danger-soft)] px-2.5 text-[12px] font-medium text-[var(--fb-danger)] outline-none hover:bg-[var(--fb-danger-soft)] focus:ring-2 focus:ring-[var(--fb-danger-soft)] ${TOUCH_CONTROL} ${CONTROL_MOTION}`\n}\n\nfunction selectInput() {\n\treturn `h-[var(--fb-control-h)] min-w-0 max-w-full rounded-[calc(var(--fb-radius)-3px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] px-2 text-[12px] font-medium text-[var(--fb-text)] outline-none focus:border-[var(--fb-accent)] focus:ring-2 focus:ring-[var(--fb-accent-soft)] [@media(pointer:coarse)]:text-[16px] ${TOUCH_CONTROL} ${CONTROL_MOTION}`\n}\n"],"x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode","__iconNode"],"sources":["../src/core/use-file-browser.ts","../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.mjs","../node_modules/lucide-react/dist/esm/defaultAttributes.mjs","../node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs","../node_modules/lucide-react/dist/esm/context.mjs","../node_modules/lucide-react/dist/esm/Icon.mjs","../node_modules/lucide-react/dist/esm/createLucideIcon.mjs","../node_modules/lucide-react/dist/esm/icons/arrow-down.mjs","../node_modules/lucide-react/dist/esm/icons/arrow-up.mjs","../node_modules/lucide-react/dist/esm/icons/check.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-down.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-left.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-right.mjs","../node_modules/lucide-react/dist/esm/icons/chevron-up.mjs","../node_modules/lucide-react/dist/esm/icons/circle-alert.mjs","../node_modules/lucide-react/dist/esm/icons/copy.mjs","../node_modules/lucide-react/dist/esm/icons/download.mjs","../node_modules/lucide-react/dist/esm/icons/ellipsis.mjs","../node_modules/lucide-react/dist/esm/icons/folder-input.mjs","../node_modules/lucide-react/dist/esm/icons/folder-plus.mjs","../node_modules/lucide-react/dist/esm/icons/folder.mjs","../node_modules/lucide-react/dist/esm/icons/info.mjs","../node_modules/lucide-react/dist/esm/icons/layout-grid.mjs","../node_modules/lucide-react/dist/esm/icons/list.mjs","../node_modules/lucide-react/dist/esm/icons/lock.mjs","../node_modules/lucide-react/dist/esm/icons/pause.mjs","../node_modules/lucide-react/dist/esm/icons/pencil.mjs","../node_modules/lucide-react/dist/esm/icons/play.mjs","../node_modules/lucide-react/dist/esm/icons/scissors.mjs","../node_modules/lucide-react/dist/esm/icons/search.mjs","../node_modules/lucide-react/dist/esm/icons/square-check-big.mjs","../node_modules/lucide-react/dist/esm/icons/trash-2.mjs","../node_modules/lucide-react/dist/esm/icons/upload.mjs","../node_modules/lucide-react/dist/esm/icons/x.mjs","../src/core/upload-drop.ts","../src/transfers/transfer-manager.ts","../src/components/responsive.tsx","../src/transfers/file-browser-provider.tsx","../src/components/file-browser.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { Dispatch, SetStateAction } from 'react'\nimport { FileBrowserAdapterError, FileBrowserBulkActionError } from './types'\nimport type { FileBrowserAdapter, FileNode } from './types'\nimport {\n\tgetFileBrowserDirname,\n\tisFileBrowserDescendantOrSelf,\n\tjoinFileBrowserPath,\n\tnormalizeFileBrowserPath\n} from './path'\n\nexport type FileBrowserStatus = 'idle' | 'loading' | 'ready' | 'error'\nexport type FileBrowserFolderChildren<TMetadata = unknown> = {\n\tstatus: 'loading' | 'ready' | 'error'\n\titems: FileNode<TMetadata>[]\n\tcursor?: string\n\terror: Error | null\n}\n/** A flattened list-view row: an item at some nesting depth, or a status line for an expanded folder. */\nexport type FileBrowserListRow<TMetadata = unknown> =\n\t| { type: 'item'; item: FileNode<TMetadata>; depth: number; expanded: boolean }\n\t| {\n\t\t\ttype: 'status'\n\t\t\tparentPath: string\n\t\t\tdepth: number\n\t\t\tstatus: 'loading' | 'empty' | 'error' | 'more'\n\t\t\terror: Error | null\n\t }\nexport type FileBrowserView = 'grid' | 'list'\nexport type FileBrowserKindFilter = 'all' | 'files' | 'folders'\nexport type FileBrowserUploadConflictResolution = 'replace' | 'keep-both' | 'skip'\nexport type FileBrowserUploadFilesOptions = {\n\tonConflict?: FileBrowserUploadConflictResolution\n}\nexport type FileBrowserClipboard = { type: 'copy'; paths: string[] } | { type: 'cut'; paths: string[] } | null\n\nexport type FileBrowserCapabilities = {\n\tcreateFolder: boolean\n\trename: boolean\n\tmove: boolean\n\tcopy: boolean\n\tstat: boolean\n\texists: boolean\n\tmultipart: boolean\n\tbulkDownload: boolean\n}\n\nexport type FileBrowserPathChangeContext<TMetadata = unknown> =\n\t| {\n\t\t\tsource: 'item'\n\t\t\titem: FileNode<TMetadata>\n\t }\n\t| {\n\t\t\tsource: 'breadcrumb' | 'programmatic'\n\t\t\titem?: FileNode<TMetadata>\n\t }\n\nexport type UseFileBrowserOptions<TMetadata = unknown> = {\n\tadapter: FileBrowserAdapter<TMetadata>\n\tpath?: string\n\tinitialPath?: string\n\tonPathChange?: (path: string, context: FileBrowserPathChangeContext<TMetadata>) => void\n\tsearchQuery?: string\n\tinitialSearchQuery?: string\n\tonSearchQueryChange?: (query: string) => void\n\t/** The view the browser opens in. Defaults to the list. */\n\tinitialView?: FileBrowserView\n}\n\nexport type UseFileBrowserResult<TMetadata = unknown> = {\n\tadapter: FileBrowserAdapter<TMetadata>\n\tcapabilities: FileBrowserCapabilities\n\tcurrentPath: string\n\tstatus: FileBrowserStatus\n\titems: FileNode<TMetadata>[]\n\terror: Error | null\n\thasMore: boolean\n\tselectedPaths: string[]\n\tselectedItems: FileNode<TMetadata>[]\n\tfocusedPath: string | null\n\tclipboard: FileBrowserClipboard\n\tview: FileBrowserView\n\tsearchQuery: string\n\tfilterKind: FileBrowserKindFilter\n\tsortBy: 'name' | 'modifiedAt' | 'size'\n\tsortDirection: 'asc' | 'desc'\n\tfilteredItems: FileNode<TMetadata>[]\n\t/** List view rows with expanded folders' children inlined. */\n\tlistRows: FileBrowserListRow<TMetadata>[]\n\t/** Items in on-screen order: `filteredItems` in grid view, every item row of `listRows` in list view. */\n\tvisibleItems: FileNode<TMetadata>[]\n\texpandedPaths: string[]\n\tsetView: Dispatch<SetStateAction<FileBrowserView>>\n\tsetSearchQuery: Dispatch<SetStateAction<string>>\n\tsetFilterKind: Dispatch<SetStateAction<FileBrowserKindFilter>>\n\tsetSortBy: Dispatch<SetStateAction<'name' | 'modifiedAt' | 'size'>>\n\tsetSortDirection: Dispatch<SetStateAction<'asc' | 'desc'>>\n\trefresh: () => Promise<void>\n\tloadMore: () => Promise<void>\n\tnavigate: (path: string, context?: FileBrowserPathChangeContext<TMetadata>) => Promise<void>\n\topen: (node: FileNode<TMetadata>) => Promise<void>\n\texpandFolder: (path: string) => void\n\tcollapseFolder: (path: string) => void\n\ttoggleFolder: (path: string) => void\n\tloadMoreFolder: (path: string) => void\n\tselectOnly: (path: string) => void\n\ttoggleSelection: (path: string) => void\n\tselectRange: (path: string) => void\n\tsetSelection: (paths: string[], options?: { additive?: boolean }) => void\n\tselectAllLoaded: () => void\n\tclearSelection: () => void\n\tcreateFolder: (name: string) => Promise<FileNode<TMetadata>>\n\trename: (path: string, newName: string) => Promise<FileNode<TMetadata>>\n\tdeleteSelected: () => Promise<void>\n\tdeletePaths: (paths: string[]) => Promise<void>\n\tmovePathsTo: (paths: string[], toDir: string) => Promise<void>\n\tmoveSelectedTo: (toDir: string) => Promise<void>\n\tcopySelection: (paths?: string[]) => void\n\tcutSelection: (paths?: string[]) => void\n\tpasteInto: (toDir: string) => Promise<void>\n\tuploadFiles: (files: File[] | FileList, options?: FileBrowserUploadFilesOptions) => Promise<FileNode<TMetadata>[]>\n}\n\nexport function useFileBrowser<TMetadata = unknown>({\n\tadapter,\n\tpath,\n\tinitialPath = '/',\n\tonPathChange,\n\tsearchQuery: controlledSearchQuery,\n\tinitialSearchQuery = '',\n\tonSearchQueryChange,\n\tinitialView = 'list'\n}: UseFileBrowserOptions<TMetadata>): UseFileBrowserResult<TMetadata> {\n\tconst controlledPath = path === undefined ? undefined : normalizeFileBrowserPath(path)\n\tconst [uncontrolledPath, setUncontrolledPath] = useState(() => normalizeFileBrowserPath(initialPath))\n\tconst currentPath = controlledPath ?? uncontrolledPath\n\tconst [status, setStatus] = useState<FileBrowserStatus>('loading')\n\tconst [items, setItems] = useState<FileNode<TMetadata>[]>([])\n\tconst [cursor, setCursor] = useState<string | undefined>()\n\tconst [error, setError] = useState<Error | null>(null)\n\tconst [selected, setSelected] = useState<Set<string>>(() => new Set())\n\tconst [focusedPath, setFocusedPath] = useState<string | null>(null)\n\tconst [rangeAnchor, setRangeAnchor] = useState<string | null>(null)\n\tconst [clipboard, setClipboard] = useState<FileBrowserClipboard>(null)\n\tconst [view, setViewState] = useState<FileBrowserView>(initialView)\n\tconst viewRef = useRef(view)\n\tviewRef.current = view\n\tconst [uncontrolledSearchQuery, setUncontrolledSearchQuery] = useState(initialSearchQuery)\n\tconst searchQuery = controlledSearchQuery ?? uncontrolledSearchQuery\n\tconst [filterKind, setFilterKind] = useState<FileBrowserKindFilter>('all')\n\tconst [sortBy, setSortBy] = useState<'name' | 'modifiedAt' | 'size'>('name')\n\tconst [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc')\n\tconst [expanded, setExpanded] = useState<Set<string>>(() => new Set())\n\tconst [folderChildren, setFolderChildren] = useState<Map<string, FileBrowserFolderChildren<TMetadata>>>(\n\t\t() => new Map()\n\t)\n\tconst expandedRef = useRef(expanded)\n\texpandedRef.current = expanded\n\tconst folderChildrenRef = useRef(folderChildren)\n\tfolderChildrenRef.current = folderChildren\n\tconst folderRequestCounterRef = useRef(0)\n\tconst folderRequestIdsRef = useRef(new Map<string, number>())\n\tconst requestIdRef = useRef(0)\n\tconst currentPathRef = useRef(currentPath)\n\tconst cursorRef = useRef<string | undefined>(undefined)\n\tconst searchQueryRef = useRef(searchQuery)\n\tsearchQueryRef.current = searchQuery\n\n\tconst setSearchQuery = useCallback<Dispatch<SetStateAction<string>>>(\n\t\t(nextQuery) => {\n\t\t\tconst resolved = typeof nextQuery === 'function' ? nextQuery(searchQueryRef.current) : nextQuery\n\t\t\tsearchQueryRef.current = resolved\n\t\t\tif (controlledSearchQuery === undefined) {\n\t\t\t\tsetUncontrolledSearchQuery(resolved)\n\t\t\t}\n\t\t\tonSearchQueryChange?.(resolved)\n\t\t},\n\t\t[controlledSearchQuery, onSearchQueryChange]\n\t)\n\n\tconst setView = useCallback<Dispatch<SetStateAction<FileBrowserView>>>((nextView) => {\n\t\tconst resolved = typeof nextView === 'function' ? nextView(viewRef.current) : nextView\n\t\tviewRef.current = resolved\n\t\tsetViewState(resolved)\n\t\tif (resolved !== 'grid') return\n\t\t// Grid shows only the current folder, so selections made inside expanded list-view folders would be hidden.\n\t\tconst isNested = (path: string | null) => path !== null && getFileBrowserDirname(path) !== currentPathRef.current\n\t\tsetSelected((current) => {\n\t\t\tconst next = new Set(Array.from(current).filter((path) => !isNested(path)))\n\t\t\treturn next.size === current.size ? current : next\n\t\t})\n\t\tsetFocusedPath((current) => (isNested(current) ? null : current))\n\t\tsetRangeAnchor((current) => (isNested(current) ? null : current))\n\t}, [])\n\n\tconst capabilities = useMemo<FileBrowserCapabilities>(\n\t\t() => ({\n\t\t\tcreateFolder: typeof adapter.createFolder === 'function',\n\t\t\trename: typeof adapter.rename === 'function',\n\t\t\tmove: typeof adapter.move === 'function',\n\t\t\tcopy: typeof adapter.copy === 'function',\n\t\t\tstat: typeof adapter.stat === 'function',\n\t\t\texists: typeof adapter.exists === 'function',\n\t\t\tmultipart:\n\t\t\t\ttypeof adapter.createMultipartUpload === 'function' &&\n\t\t\t\ttypeof adapter.uploadPart === 'function' &&\n\t\t\t\ttypeof adapter.completeMultipartUpload === 'function',\n\t\t\tbulkDownload: typeof adapter.bulkDownloadUrl === 'function'\n\t\t}),\n\t\t[adapter]\n\t)\n\n\tconst selectedPaths = useMemo(() => sortPaths(Array.from(selected)), [selected])\n\tconst selectedItems = useMemo(() => {\n\t\tconst nodes = new Map(items.map((item) => [item.path, item]))\n\t\tfor (const entry of folderChildren.values()) {\n\t\t\tfor (const item of entry.items) {\n\t\t\t\tif (!nodes.has(item.path)) nodes.set(item.path, item)\n\t\t\t}\n\t\t}\n\t\treturn Array.from(nodes.values()).filter((item) => selected.has(item.path))\n\t}, [folderChildren, items, selected])\n\n\tconst filteredItems = useMemo(\n\t\t() => filterAndSortNodes(items, searchQuery, filterKind, sortBy, sortDirection),\n\t\t[filterKind, items, searchQuery, sortBy, sortDirection]\n\t)\n\n\tconst listRows = useMemo(() => {\n\t\tconst rows: FileBrowserListRow<TMetadata>[] = []\n\t\tconst visit = (nodes: FileNode<TMetadata>[], depth: number) => {\n\t\t\tfor (const item of nodes) {\n\t\t\t\tconst isExpanded = item.kind === 'folder' && expanded.has(item.path)\n\t\t\t\trows.push({ type: 'item', item, depth, expanded: isExpanded })\n\t\t\t\tif (!isExpanded) continue\n\n\t\t\t\tconst entry = folderChildren.get(item.path)\n\t\t\t\t// Search narrows the current folder only; expanded children stay complete, like an OS outline view.\n\t\t\t\tconst children = entry ? filterAndSortNodes(entry.items, '', filterKind, sortBy, sortDirection) : []\n\t\t\t\tvisit(children, depth + 1)\n\t\t\t\tconst status = getFolderRowStatus(entry, children.length)\n\t\t\t\tif (status) {\n\t\t\t\t\trows.push({ type: 'status', parentPath: item.path, depth: depth + 1, status, error: entry?.error ?? null })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvisit(filteredItems, 0)\n\t\treturn rows\n\t}, [expanded, filterKind, filteredItems, folderChildren, sortBy, sortDirection])\n\n\tconst visibleItems = useMemo(\n\t\t() => (view === 'list' ? listRows.flatMap((row) => (row.type === 'item' ? [row.item] : [])) : filteredItems),\n\t\t[filteredItems, listRows, view]\n\t)\n\tconst expandedPaths = useMemo(() => sortPaths(Array.from(expanded)), [expanded])\n\n\tconst loadFolder = useCallback(\n\t\tasync (folderPath: string, mode: 'replace' | 'append') => {\n\t\t\tconst requestId = ++folderRequestCounterRef.current\n\t\t\tfolderRequestIdsRef.current.set(folderPath, requestId)\n\t\t\tconst cursor = mode === 'append' ? folderChildrenRef.current.get(folderPath)?.cursor : undefined\n\t\t\tsetFolderChildren((current) =>\n\t\t\t\twithFolderChildren(current, folderPath, {\n\t\t\t\t\titems: current.get(folderPath)?.items ?? [],\n\t\t\t\t\tcursor: current.get(folderPath)?.cursor,\n\t\t\t\t\tstatus: 'loading',\n\t\t\t\t\terror: null\n\t\t\t\t})\n\t\t\t)\n\n\t\t\ttry {\n\t\t\t\tconst result = await adapter.list(folderPath, { cursor })\n\t\t\t\tif (folderRequestIdsRef.current.get(folderPath) !== requestId) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetFolderChildren((current) =>\n\t\t\t\t\twithFolderChildren(current, folderPath, {\n\t\t\t\t\t\titems: mode === 'append' ? mergeItems(current.get(folderPath)?.items ?? [], result.items) : result.items,\n\t\t\t\t\t\tcursor: result.cursor,\n\t\t\t\t\t\tstatus: 'ready',\n\t\t\t\t\t\terror: null\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t} catch (caught) {\n\t\t\t\tif (folderRequestIdsRef.current.get(folderPath) !== requestId) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetFolderChildren((current) =>\n\t\t\t\t\twithFolderChildren(current, folderPath, {\n\t\t\t\t\t\titems: current.get(folderPath)?.items ?? [],\n\t\t\t\t\t\tcursor: current.get(folderPath)?.cursor,\n\t\t\t\t\t\tstatus: 'error',\n\t\t\t\t\t\terror: toError(caught)\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t}\n\t\t},\n\t\t[adapter]\n\t)\n\n\tconst reloadExpandedFolders = useCallback(\n\t\tasync (paths: Iterable<string> = expandedRef.current) => {\n\t\t\tconst targets = Array.from(paths).filter((path) => expandedRef.current.has(path))\n\t\t\tawait Promise.all(targets.map((path) => loadFolder(path, 'replace')))\n\t\t},\n\t\t[loadFolder]\n\t)\n\n\tconst resetTree = useCallback(() => {\n\t\tfolderRequestIdsRef.current.clear()\n\t\tsetExpanded(new Set())\n\t\tsetFolderChildren(new Map())\n\t}, [])\n\n\tconst pruneTree = useCallback((paths: string[]) => {\n\t\tfor (const folderPath of Array.from(folderRequestIdsRef.current.keys())) {\n\t\t\tif (paths.some((path) => isFileBrowserDescendantOrSelf(path, folderPath))) {\n\t\t\t\tfolderRequestIdsRef.current.delete(folderPath)\n\t\t\t}\n\t\t}\n\t\tsetExpanded((current) => pruneExpandedPaths(current, paths))\n\t\tsetFolderChildren((current) => pruneFolderChildren(current, paths))\n\t}, [])\n\n\tconst expandFolder = useCallback(\n\t\t(folderPath: string) => {\n\t\t\tconst normalized = normalizeFileBrowserPath(folderPath)\n\t\t\tsetExpanded((current) => (current.has(normalized) ? current : new Set(current).add(normalized)))\n\t\t\tvoid loadFolder(normalized, 'replace')\n\t\t},\n\t\t[loadFolder]\n\t)\n\n\tconst collapseFolder = useCallback((folderPath: string) => {\n\t\tconst normalized = normalizeFileBrowserPath(folderPath)\n\t\tconst isHidden = (path: string | null) =>\n\t\t\tpath !== null && path !== normalized && isFileBrowserDescendantOrSelf(normalized, path)\n\t\tsetExpanded((current) => {\n\t\t\tif (!current.has(normalized)) return current\n\t\t\tconst next = new Set(current)\n\t\t\tnext.delete(normalized)\n\t\t\treturn next\n\t\t})\n\t\t// Hidden rows must not stay selected, or keyboard delete/move would act on items the user cannot see.\n\t\tsetSelected((current) => {\n\t\t\tconst next = new Set(Array.from(current).filter((path) => !isHidden(path)))\n\t\t\treturn next.size === current.size ? current : next\n\t\t})\n\t\tsetFocusedPath((current) => (isHidden(current) ? normalized : current))\n\t\tsetRangeAnchor((current) => (isHidden(current) ? null : current))\n\t}, [])\n\n\tconst toggleFolder = useCallback(\n\t\t(folderPath: string) => {\n\t\t\tif (expandedRef.current.has(normalizeFileBrowserPath(folderPath))) {\n\t\t\t\tcollapseFolder(folderPath)\n\t\t\t} else {\n\t\t\t\texpandFolder(folderPath)\n\t\t\t}\n\t\t},\n\t\t[collapseFolder, expandFolder]\n\t)\n\n\tconst loadMoreFolder = useCallback(\n\t\t(folderPath: string) => {\n\t\t\tconst normalized = normalizeFileBrowserPath(folderPath)\n\t\t\tconst entry = folderChildrenRef.current.get(normalized)\n\t\t\tif (!entry?.cursor || entry.status === 'loading') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvoid loadFolder(normalized, 'append')\n\t\t},\n\t\t[loadFolder]\n\t)\n\n\tconst loadPath = useCallback(\n\t\tasync (path: string, mode: 'replace' | 'append') => {\n\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\tconst requestId = ++requestIdRef.current\n\n\t\t\tsetStatus((current) => (mode === 'replace' || current === 'idle' ? 'loading' : current))\n\t\t\tsetError(null)\n\n\t\t\ttry {\n\t\t\t\tconst result = await adapter.list(normalized, {\n\t\t\t\t\tcursor: mode === 'append' ? cursorRef.current : undefined\n\t\t\t\t})\n\n\t\t\t\tif (requestId !== requestIdRef.current) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tsetItems((current) => (mode === 'append' ? mergeItems(current, result.items) : result.items))\n\t\t\t\tcursorRef.current = result.cursor\n\t\t\t\tsetCursor(result.cursor)\n\t\t\t\tsetStatus('ready')\n\t\t\t} catch (caught) {\n\t\t\t\tif (requestId !== requestIdRef.current) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tsetError(toError(caught))\n\t\t\t\tsetStatus('error')\n\t\t\t}\n\t\t},\n\t\t[adapter]\n\t)\n\n\tconst refresh = useCallback(async () => {\n\t\tawait Promise.all([loadPath(currentPath, 'replace'), reloadExpandedFolders()])\n\t}, [currentPath, loadPath, reloadExpandedFolders])\n\n\tconst navigate = useCallback(\n\t\tasync (nextPath: string, context: FileBrowserPathChangeContext<TMetadata> = { source: 'programmatic' }) => {\n\t\t\tconst normalized = normalizeFileBrowserPath(nextPath)\n\t\t\tif (normalized === currentPathRef.current) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tonPathChange?.(normalized, context)\n\t\t\tif (controlledPath !== undefined) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tcurrentPathRef.current = normalized\n\t\t\tsetUncontrolledPath(normalized)\n\t\t\tsetSelected(new Set())\n\t\t\tsetFocusedPath(null)\n\t\t\tsetRangeAnchor(null)\n\t\t\tresetTree()\n\t\t\tcursorRef.current = undefined\n\t\t\tsetCursor(undefined)\n\t\t\tawait loadPath(normalized, 'replace')\n\t\t},\n\t\t[controlledPath, loadPath, onPathChange, resetTree]\n\t)\n\n\tconst loadMore = useCallback(async () => {\n\t\tif (!cursor || status === 'loading') {\n\t\t\treturn\n\t\t}\n\n\t\tawait loadPath(currentPath, 'append')\n\t}, [currentPath, cursor, loadPath, status])\n\n\tuseEffect(() => {\n\t\tconst nextPath = currentPath\n\t\tif (nextPath !== currentPathRef.current) {\n\t\t\tcurrentPathRef.current = nextPath\n\t\t\tsetSelected(new Set())\n\t\t\tsetFocusedPath(null)\n\t\t\tsetRangeAnchor(null)\n\t\t}\n\t\tresetTree()\n\t\tcursorRef.current = undefined\n\t\tsetCursor(undefined)\n\t\tvoid Promise.resolve().then(() => loadPath(nextPath, 'replace'))\n\t\t// Uncontrolled navigation loads directly. This effect handles adapter\n\t\t// replacement and externally controlled path changes only.\n\t\t// oxlint-disable-next-line react/exhaustive-deps\n\t}, [adapter, controlledPath])\n\n\tconst selectOnly = useCallback((path: string) => {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tsetSelected(new Set([normalized]))\n\t\tsetFocusedPath(normalized)\n\t\tsetRangeAnchor(normalized)\n\t}, [])\n\n\tconst toggleSelection = useCallback((path: string) => {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tsetSelected((current) => {\n\t\t\tconst next = new Set(current)\n\t\t\tif (next.has(normalized)) {\n\t\t\t\tnext.delete(normalized)\n\t\t\t} else {\n\t\t\t\tnext.add(normalized)\n\t\t\t}\n\t\t\treturn next\n\t\t})\n\t\tsetFocusedPath(normalized)\n\t}, [])\n\n\tconst selectRange = useCallback(\n\t\t(path: string) => {\n\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\tconst anchor = rangeAnchor ?? focusedPath ?? normalized\n\t\t\tconst visiblePaths = visibleItems.map((item) => item.path)\n\t\t\tconst anchorIndex = visiblePaths.indexOf(anchor)\n\t\t\tconst targetIndex = visiblePaths.indexOf(normalized)\n\n\t\t\tif (anchorIndex === -1 || targetIndex === -1) {\n\t\t\t\tselectOnly(normalized)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst start = Math.min(anchorIndex, targetIndex)\n\t\t\tconst end = Math.max(anchorIndex, targetIndex)\n\t\t\tsetSelected(new Set(visiblePaths.slice(start, end + 1)))\n\t\t\tsetFocusedPath(normalized)\n\t\t},\n\t\t[focusedPath, rangeAnchor, selectOnly, visibleItems]\n\t)\n\n\tconst setSelection = useCallback((paths: string[], options: { additive?: boolean } = {}) => {\n\t\tconst normalizedPaths = paths.map(normalizeFileBrowserPath)\n\t\tsetSelected((current) => {\n\t\t\tconst next = options.additive ? new Set(current) : new Set<string>()\n\t\t\tfor (const path of normalizedPaths) {\n\t\t\t\tnext.add(path)\n\t\t\t}\n\t\t\treturn next\n\t\t})\n\t\tsetFocusedPath(normalizedPaths.at(-1) ?? null)\n\t\tsetRangeAnchor(normalizedPaths.at(0) ?? null)\n\t}, [])\n\n\tconst selectAllLoaded = useCallback(() => {\n\t\tconst paths = new Set(items.map((item) => item.path))\n\t\tif (view === 'list') {\n\t\t\tfor (const item of visibleItems) paths.add(item.path)\n\t\t}\n\t\tsetSelected(paths)\n\t\tsetFocusedPath(items.at(0)?.path ?? null)\n\t\tsetRangeAnchor(items.at(0)?.path ?? null)\n\t}, [items, view, visibleItems])\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelected(new Set())\n\t\tsetFocusedPath(null)\n\t\tsetRangeAnchor(null)\n\t}, [])\n\n\tconst open = useCallback(\n\t\tasync (node: FileNode<TMetadata>) => {\n\t\t\tif (node.kind === 'folder') {\n\t\t\t\tawait navigate(node.path, { source: 'item', item: node })\n\t\t\t} else {\n\t\t\t\tselectOnly(node.path)\n\t\t\t}\n\t\t},\n\t\t[navigate, selectOnly]\n\t)\n\n\tconst createFolder = useCallback(\n\t\tasync (name: string) => {\n\t\t\tif (!adapter.createFolder) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Folder creation is not supported by this adapter')\n\t\t\t}\n\t\t\tconst path = joinFileBrowserPath(currentPath, name.trim())\n\t\t\tconst optimistic: FileNode<TMetadata> = {\n\t\t\t\tpath,\n\t\t\t\tname: name.trim(),\n\t\t\t\tkind: 'folder',\n\t\t\t\tmodifiedAt: new Date().toISOString()\n\t\t\t}\n\t\t\tsetItems((current) => mergeItems(current, [optimistic]))\n\n\t\t\ttry {\n\t\t\t\tconst created = await adapter.createFolder(path)\n\t\t\t\tsetItems((current) => mergeItems(removePaths(current, [path]), [created]))\n\t\t\t\treturn created\n\t\t\t} catch (caught) {\n\t\t\t\tsetItems((current) => removePaths(current, [path]))\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t},\n\t\t[adapter, currentPath]\n\t)\n\n\tconst rename = useCallback(\n\t\tasync (path: string, newName: string) => {\n\t\t\tif (!adapter.rename) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Rename is not supported by this adapter')\n\t\t\t}\n\n\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\tconst previous = items\n\t\t\tconst previousChildren = folderChildrenRef.current\n\t\t\tconst replace = (next: (item: FileNode<TMetadata>) => FileNode<TMetadata>) => {\n\t\t\t\tconst update = (nodes: FileNode<TMetadata>[]) =>\n\t\t\t\t\tnodes.map((item) => (item.path === normalized ? next(item) : item))\n\t\t\t\tsetItems(update)\n\t\t\t\tsetFolderChildren((current) => mapFolderChildItems(current, update))\n\t\t\t}\n\t\t\treplace((item) => ({ ...item, name: newName.trim() }))\n\n\t\t\ttry {\n\t\t\t\tconst renamed = await adapter.rename(normalized, newName.trim())\n\t\t\t\treplace(() => renamed)\n\t\t\t\treturn renamed\n\t\t\t} catch (caught) {\n\t\t\t\tsetItems(previous)\n\t\t\t\tsetFolderChildren(previousChildren)\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t},\n\t\t[adapter, items]\n\t)\n\n\tconst deletePaths = useCallback(\n\t\tasync (paths: string[]) => {\n\t\t\tconst normalizedPaths = paths.map(normalizeFileBrowserPath)\n\t\t\tconst previousItems = items\n\t\t\tconst previousSelected = selected\n\t\t\tconst previousExpanded = expandedRef.current\n\t\t\tconst previousChildren = folderChildrenRef.current\n\n\t\t\tsetItems((current) => removePaths(current, normalizedPaths))\n\t\t\tpruneTree(normalizedPaths)\n\t\t\tsetSelected((current) => {\n\t\t\t\tconst next = new Set(current)\n\t\t\t\tfor (const path of normalizedPaths) {\n\t\t\t\t\tnext.delete(path)\n\t\t\t\t}\n\t\t\t\treturn next\n\t\t\t})\n\n\t\t\ttry {\n\t\t\t\tawait adapter.delete(normalizedPaths)\n\t\t\t} catch (caught) {\n\t\t\t\tif (caught instanceof FileBrowserBulkActionError) {\n\t\t\t\t\tconst succeededPaths = caught.succeededPaths.map(normalizeFileBrowserPath)\n\t\t\t\t\tconst failedPaths = caught.failures.map((failure) => normalizeFileBrowserPath(failure.path))\n\t\t\t\t\tsetItems(removePaths(previousItems, succeededPaths))\n\t\t\t\t\tsetExpanded(pruneExpandedPaths(previousExpanded, succeededPaths))\n\t\t\t\t\tsetFolderChildren(pruneFolderChildren(previousChildren, succeededPaths))\n\t\t\t\t\tsetSelected(new Set(failedPaths))\n\t\t\t\t\tsetFocusedPath(failedPaths.at(0) ?? null)\n\t\t\t\t\tsetRangeAnchor(failedPaths.at(0) ?? null)\n\t\t\t\t\tthrow caught\n\t\t\t\t}\n\t\t\t\tsetItems(previousItems)\n\t\t\t\tsetExpanded(previousExpanded)\n\t\t\t\tsetFolderChildren(previousChildren)\n\t\t\t\tsetSelected(previousSelected)\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t},\n\t\t[adapter, items, pruneTree, selected]\n\t)\n\n\tconst deleteSelected = useCallback(async () => {\n\t\tawait deletePaths(selectedPaths)\n\t}, [deletePaths, selectedPaths])\n\n\tconst movePathsTo = useCallback(\n\t\tasync (paths: string[], toDir: string) => {\n\t\t\tif (!adapter.move) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Move is not supported by this adapter')\n\t\t\t}\n\n\t\t\tconst normalizedPaths = paths.map(normalizeFileBrowserPath)\n\t\t\tif (normalizedPaths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst destination = normalizeFileBrowserPath(toDir)\n\t\t\ttry {\n\t\t\t\tawait adapter.move(normalizedPaths, destination)\n\t\t\t} catch (caught) {\n\t\t\t\tif (caught instanceof FileBrowserBulkActionError) {\n\t\t\t\t\tconst succeededPaths = caught.succeededPaths.map(normalizeFileBrowserPath)\n\t\t\t\t\tconst failedPaths = caught.failures.map((failure) => normalizeFileBrowserPath(failure.path))\n\t\t\t\t\tpruneTree(succeededPaths)\n\t\t\t\t\tif (destination === currentPath) {\n\t\t\t\t\t\tawait refresh()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetItems((current) => removePaths(current, succeededPaths))\n\t\t\t\t\t\tawait reloadExpandedFolders([destination])\n\t\t\t\t\t}\n\t\t\t\t\tsetSelected(new Set(failedPaths))\n\t\t\t\t\tsetFocusedPath(failedPaths.at(0) ?? null)\n\t\t\t\t\tsetRangeAnchor(failedPaths.at(0) ?? null)\n\t\t\t\t\tthrow caught\n\t\t\t\t}\n\t\t\t\tthrow caught\n\t\t\t}\n\t\t\tsetSelected((current) => {\n\t\t\t\tconst next = new Set(current)\n\t\t\t\tfor (const path of normalizedPaths) {\n\t\t\t\t\tnext.delete(path)\n\t\t\t\t}\n\t\t\t\treturn next\n\t\t\t})\n\t\t\tsetFocusedPath(null)\n\t\t\tsetRangeAnchor(null)\n\t\t\tpruneTree(normalizedPaths)\n\n\t\t\tif (destination === currentPath) {\n\t\t\t\tawait refresh()\n\t\t\t} else {\n\t\t\t\tsetItems((current) => removePaths(current, normalizedPaths))\n\t\t\t\tawait reloadExpandedFolders([destination])\n\t\t\t}\n\t\t},\n\t\t[adapter, currentPath, pruneTree, refresh, reloadExpandedFolders]\n\t)\n\n\tconst moveSelectedTo = useCallback(\n\t\tasync (toDir: string) => {\n\t\t\tawait movePathsTo(selectedPaths, toDir)\n\t\t\tsetClipboard((current) => (current?.type === 'cut' ? null : current))\n\t\t},\n\t\t[movePathsTo, selectedPaths]\n\t)\n\n\tconst copySelection = useCallback(\n\t\t(paths = selectedPaths) => {\n\t\t\tsetClipboard({ type: 'copy', paths: paths.map(normalizeFileBrowserPath) })\n\t\t},\n\t\t[selectedPaths]\n\t)\n\n\tconst cutSelection = useCallback(\n\t\t(paths = selectedPaths) => {\n\t\t\tsetClipboard({ type: 'cut', paths: paths.map(normalizeFileBrowserPath) })\n\t\t},\n\t\t[selectedPaths]\n\t)\n\n\tconst pasteInto = useCallback(\n\t\tasync (toDir: string) => {\n\t\t\tif (!clipboard || clipboard.paths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst destination = normalizeFileBrowserPath(toDir)\n\t\t\tif (clipboard.type === 'copy') {\n\t\t\t\tif (!adapter.copy) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Copy is not supported by this adapter')\n\t\t\t\t}\n\t\t\t\tawait adapter.copy(clipboard.paths, destination)\n\t\t\t} else {\n\t\t\t\tif (!adapter.move) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Move is not supported by this adapter')\n\t\t\t\t}\n\t\t\t\tawait movePathsTo(clipboard.paths, destination)\n\t\t\t\tsetClipboard(null)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (destination === currentPath) {\n\t\t\t\tawait refresh()\n\t\t\t} else {\n\t\t\t\tawait reloadExpandedFolders([destination])\n\t\t\t}\n\t\t},\n\t\t[adapter, clipboard, currentPath, movePathsTo, refresh, reloadExpandedFolders]\n\t)\n\n\tconst uploadFiles = useCallback(\n\t\tasync (files: File[] | FileList, options: FileBrowserUploadFilesOptions = {}) => {\n\t\t\tif (options.onConflict === 'skip') {\n\t\t\t\treturn []\n\t\t\t}\n\n\t\t\tconst fileArray = Array.from(files)\n\t\t\tconst uploaded: FileNode<TMetadata>[] = []\n\n\t\t\tfor (const file of fileArray) {\n\t\t\t\tconst path = joinFileBrowserPath(currentPathRef.current, file.name)\n\t\t\t\tconst result = await adapter.upload(path, file, {\n\t\t\t\t\tonConflict: options.onConflict ?? 'keep-both'\n\t\t\t\t})\n\t\t\t\tuploaded.push(result)\n\t\t\t\tsetItems((current) => mergeItems(current, [result]))\n\t\t\t}\n\n\t\t\treturn uploaded\n\t\t},\n\t\t[adapter]\n\t)\n\n\treturn {\n\t\tadapter,\n\t\tcapabilities,\n\t\tcurrentPath,\n\t\tstatus,\n\t\titems,\n\t\terror,\n\t\thasMore: Boolean(cursor),\n\t\tselectedPaths,\n\t\tselectedItems,\n\t\tfocusedPath,\n\t\tclipboard,\n\t\tview,\n\t\tsearchQuery,\n\t\tfilterKind,\n\t\tsortBy,\n\t\tsortDirection,\n\t\tfilteredItems,\n\t\tlistRows,\n\t\tvisibleItems,\n\t\texpandedPaths,\n\t\tsetView,\n\t\tsetSearchQuery,\n\t\tsetFilterKind,\n\t\tsetSortBy,\n\t\tsetSortDirection,\n\t\trefresh,\n\t\tloadMore,\n\t\tnavigate,\n\t\topen,\n\t\texpandFolder,\n\t\tcollapseFolder,\n\t\ttoggleFolder,\n\t\tloadMoreFolder,\n\t\tselectOnly,\n\t\ttoggleSelection,\n\t\tselectRange,\n\t\tsetSelection,\n\t\tselectAllLoaded,\n\t\tclearSelection,\n\t\tcreateFolder,\n\t\trename,\n\t\tdeleteSelected,\n\t\tdeletePaths,\n\t\tmovePathsTo,\n\t\tmoveSelectedTo,\n\t\tcopySelection,\n\t\tcutSelection,\n\t\tpasteInto,\n\t\tuploadFiles\n\t}\n}\n\nfunction mergeItems<TMetadata>(current: FileNode<TMetadata>[], incoming: FileNode<TMetadata>[]): FileNode<TMetadata>[] {\n\tconst map = new Map(current.map((item) => [item.path, item]))\n\tfor (const item of incoming) {\n\t\tmap.set(item.path, item)\n\t}\n\treturn Array.from(map.values()).sort((left, right) => compareNodes(left, right, 'name', 'asc'))\n}\n\nfunction removePaths<TMetadata>(items: FileNode<TMetadata>[], paths: string[]): FileNode<TMetadata>[] {\n\tconst remove = new Set(paths)\n\treturn items.filter((item) => !remove.has(item.path))\n}\n\nfunction filterAndSortNodes<TMetadata>(\n\titems: FileNode<TMetadata>[],\n\tsearchQuery: string,\n\tfilterKind: FileBrowserKindFilter,\n\tsortBy: 'name' | 'modifiedAt' | 'size',\n\tsortDirection: 'asc' | 'desc'\n): FileNode<TMetadata>[] {\n\tconst query = searchQuery.trim().toLowerCase()\n\treturn items\n\t\t.filter((item) => (query ? item.name.toLowerCase().includes(query) : true))\n\t\t.filter((item) => (filterKind === 'all' ? true : item.kind === (filterKind === 'files' ? 'file' : 'folder')))\n\t\t.sort((left, right) => compareNodes(left, right, sortBy, sortDirection))\n}\n\nfunction getFolderRowStatus<TMetadata>(\n\tentry: FileBrowserFolderChildren<TMetadata> | undefined,\n\tvisibleChildCount: number\n): Extract<FileBrowserListRow, { type: 'status' }>['status'] | null {\n\tif (!entry || (entry.status === 'loading' && (visibleChildCount === 0 || entry.cursor))) return 'loading'\n\tif (entry.status === 'error') return 'error'\n\tif (entry.cursor) return 'more'\n\treturn visibleChildCount === 0 ? 'empty' : null\n}\n\nfunction withFolderChildren<TMetadata>(\n\tcurrent: Map<string, FileBrowserFolderChildren<TMetadata>>,\n\tfolderPath: string,\n\tentry: FileBrowserFolderChildren<TMetadata>\n): Map<string, FileBrowserFolderChildren<TMetadata>> {\n\treturn new Map(current).set(folderPath, entry)\n}\n\nfunction mapFolderChildItems<TMetadata>(\n\tcurrent: Map<string, FileBrowserFolderChildren<TMetadata>>,\n\tupdate: (items: FileNode<TMetadata>[]) => FileNode<TMetadata>[]\n): Map<string, FileBrowserFolderChildren<TMetadata>> {\n\tconst next = new Map<string, FileBrowserFolderChildren<TMetadata>>()\n\tfor (const [folderPath, entry] of current) {\n\t\tnext.set(folderPath, { ...entry, items: update(entry.items) })\n\t}\n\treturn next\n}\n\nfunction pruneFolderChildren<TMetadata>(\n\tcurrent: Map<string, FileBrowserFolderChildren<TMetadata>>,\n\tpaths: string[]\n): Map<string, FileBrowserFolderChildren<TMetadata>> {\n\tconst next = new Map<string, FileBrowserFolderChildren<TMetadata>>()\n\tfor (const [folderPath, entry] of current) {\n\t\tif (paths.some((path) => isFileBrowserDescendantOrSelf(path, folderPath))) continue\n\t\tnext.set(folderPath, { ...entry, items: removePaths(entry.items, paths) })\n\t}\n\treturn next\n}\n\nfunction pruneExpandedPaths(current: Set<string>, paths: string[]): Set<string> {\n\tconst next = new Set(\n\t\tArray.from(current).filter((folderPath) => !paths.some((path) => isFileBrowserDescendantOrSelf(path, folderPath)))\n\t)\n\treturn next.size === current.size ? current : next\n}\n\nfunction compareNodes<TMetadata>(\n\tleft: FileNode<TMetadata>,\n\tright: FileNode<TMetadata>,\n\tsortBy: 'name' | 'modifiedAt' | 'size',\n\tdirection: 'asc' | 'desc'\n): number {\n\tconst multiplier = direction === 'asc' ? 1 : -1\n\n\tif (left.kind !== right.kind) {\n\t\treturn left.kind === 'folder' ? -1 : 1\n\t}\n\n\tif (sortBy === 'size') {\n\t\treturn ((left.size ?? 0) - (right.size ?? 0)) * multiplier\n\t}\n\n\tif (sortBy === 'modifiedAt') {\n\t\treturn String(left.modifiedAt ?? '').localeCompare(String(right.modifiedAt ?? '')) * multiplier\n\t}\n\n\treturn (\n\t\tleft.name.localeCompare(right.name, undefined, {\n\t\t\tnumeric: true,\n\t\t\tsensitivity: 'base'\n\t\t}) * multiplier\n\t)\n}\n\nfunction sortPaths(paths: string[]): string[] {\n\treturn [...paths].sort((left, right) => left.localeCompare(right))\n}\n\nfunction toError(caught: unknown): Error {\n\treturn caught instanceof Error ? caught : new Error(String(caught))\n}\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses };\n//# sourceMappingURL=mergeClasses.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n\nexport { toKebabCase };\n//# sourceMappingURL=toKebabCase.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\n\nexport { toCamelCase };\n//# sourceMappingURL=toCamelCase.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { toCamelCase } from './toCamelCase.mjs';\n\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\n\nexport { toPascalCase };\n//# sourceMappingURL=toPascalCase.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n return false;\n};\n\nexport { hasA11yProp };\n//# sourceMappingURL=hasA11yProp.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { createContext, useContext, useMemo, createElement } from 'react';\n\nconst LucideContext = createContext({});\nfunction LucideProvider({\n children,\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n}) {\n const value = useMemo(\n () => ({\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n }),\n [size, color, strokeWidth, absoluteStrokeWidth, className]\n );\n return createElement(LucideContext.Provider, { value }, children);\n}\nconst useLucideContext = () => useContext(LucideContext);\n\nexport { LucideProvider, useLucideContext };\n//# sourceMappingURL=context.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.mjs';\nimport { hasA11yProp } from './shared/src/utils/hasA11yProp.mjs';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { useLucideContext } from './context.mjs';\n\nconst Icon = forwardRef(\n ({ color, size, strokeWidth, absoluteStrokeWidth, className = \"\", children, iconNode, ...rest }, ref) => {\n const {\n size: contextSize = 24,\n strokeWidth: contextStrokeWidth = 2,\n absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,\n color: contextColor = \"currentColor\",\n className: contextClass = \"\"\n } = useLucideContext() ?? {};\n const calculatedStrokeWidth = absoluteStrokeWidth ?? contextAbsoluteStrokeWidth ? Number(strokeWidth ?? contextStrokeWidth) * 24 / Number(size ?? contextSize) : strokeWidth ?? contextStrokeWidth;\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size ?? contextSize ?? defaultAttributes.width,\n height: size ?? contextSize ?? defaultAttributes.height,\n stroke: color ?? contextColor,\n strokeWidth: calculatedStrokeWidth,\n className: mergeClasses(\"lucide\", contextClass, className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { toKebabCase } from './shared/src/utils/toKebabCase.mjs';\nimport { toPascalCase } from './shared/src/utils/toPascalCase.mjs';\nimport Icon from './Icon.mjs';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }],\n [\"path\", { d: \"m19 12-7 7-7-7\", key: \"1idqje\" }]\n];\nconst ArrowDown = createLucideIcon(\"arrow-down\", __iconNode);\n\nexport { __iconNode, ArrowDown as default };\n//# sourceMappingURL=arrow-down.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m5 12 7-7 7 7\", key: \"hav0vg\" }],\n [\"path\", { d: \"M12 19V5\", key: \"x0mq9r\" }]\n];\nconst ArrowUp = createLucideIcon(\"arrow-up\", __iconNode);\n\nexport { __iconNode, ArrowUp as default };\n//# sourceMappingURL=arrow-up.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"M20 6 9 17l-5-5\", key: \"1gmf2c\" }]];\nconst Check = createLucideIcon(\"check\", __iconNode);\n\nexport { __iconNode, Check as default };\n//# sourceMappingURL=check.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]];\nconst ChevronDown = createLucideIcon(\"chevron-down\", __iconNode);\n\nexport { __iconNode, ChevronDown as default };\n//# sourceMappingURL=chevron-down.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m15 18-6-6 6-6\", key: \"1wnfg3\" }]];\nconst ChevronLeft = createLucideIcon(\"chevron-left\", __iconNode);\n\nexport { __iconNode, ChevronLeft as default };\n//# sourceMappingURL=chevron-left.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m9 18 6-6-6-6\", key: \"mthhwq\" }]];\nconst ChevronRight = createLucideIcon(\"chevron-right\", __iconNode);\n\nexport { __iconNode, ChevronRight as default };\n//# sourceMappingURL=chevron-right.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m18 15-6-6-6 6\", key: \"153udz\" }]];\nconst ChevronUp = createLucideIcon(\"chevron-up\", __iconNode);\n\nexport { __iconNode, ChevronUp as default };\n//# sourceMappingURL=chevron-up.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n];\nconst CircleAlert = createLucideIcon(\"circle-alert\", __iconNode);\n\nexport { __iconNode, CircleAlert as default };\n//# sourceMappingURL=circle-alert.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"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\" }]\n];\nconst Copy = createLucideIcon(\"copy\", __iconNode);\n\nexport { __iconNode, Copy as default };\n//# sourceMappingURL=copy.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 15V3\", key: \"m9g1x1\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"path\", { d: \"m7 10 5 5 5-5\", key: \"brsn70\" }]\n];\nconst Download = createLucideIcon(\"download\", __iconNode);\n\nexport { __iconNode, Download as default };\n//# sourceMappingURL=download.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"19\", cy: \"12\", r: \"1\", key: \"1wjl8i\" }],\n [\"circle\", { cx: \"5\", cy: \"12\", r: \"1\", key: \"1pcz8c\" }]\n];\nconst Ellipsis = createLucideIcon(\"ellipsis\", __iconNode);\n\nexport { __iconNode, Ellipsis as default };\n//# sourceMappingURL=ellipsis.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1\",\n key: \"fm4g5t\"\n }\n ],\n [\"path\", { d: \"M2 13h10\", key: \"pgb2dq\" }],\n [\"path\", { d: \"m9 16 3-3-3-3\", key: \"6m91ic\" }]\n];\nconst FolderInput = createLucideIcon(\"folder-input\", __iconNode);\n\nexport { __iconNode, FolderInput as default };\n//# sourceMappingURL=folder-input.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 10v6\", key: \"1bos4e\" }],\n [\"path\", { d: \"M9 13h6\", key: \"1uhe8q\" }],\n [\n \"path\",\n {\n 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\",\n key: \"1kt360\"\n }\n ]\n];\nconst FolderPlus = createLucideIcon(\"folder-plus\", __iconNode);\n\nexport { __iconNode, FolderPlus as default };\n//# sourceMappingURL=folder-plus.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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\",\n key: \"1kt360\"\n }\n ]\n];\nconst Folder = createLucideIcon(\"folder\", __iconNode);\n\nexport { __iconNode, Folder as default };\n//# sourceMappingURL=folder.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 16v-4\", key: \"1dtifu\" }],\n [\"path\", { d: \"M12 8h.01\", key: \"e9boi3\" }]\n];\nconst Info = createLucideIcon(\"info\", __iconNode);\n\nexport { __iconNode, Info as default };\n//# sourceMappingURL=info.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"7\", height: \"7\", x: \"3\", y: \"3\", rx: \"1\", key: \"1g98yp\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"3\", rx: \"1\", key: \"6d4xhi\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"14\", rx: \"1\", key: \"nxv5o0\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"3\", y: \"14\", rx: \"1\", key: \"1bb6yr\" }]\n];\nconst LayoutGrid = createLucideIcon(\"layout-grid\", __iconNode);\n\nexport { __iconNode, LayoutGrid as default };\n//# sourceMappingURL=layout-grid.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 5h.01\", key: \"18ugdj\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M3 19h.01\", key: \"noohij\" }],\n [\"path\", { d: \"M8 5h13\", key: \"1pao27\" }],\n [\"path\", { d: \"M8 12h13\", key: \"1za7za\" }],\n [\"path\", { d: \"M8 19h13\", key: \"m83p4d\" }]\n];\nconst List = createLucideIcon(\"list\", __iconNode);\n\nexport { __iconNode, List as default };\n//# sourceMappingURL=list.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"11\", x: \"3\", y: \"11\", rx: \"2\", ry: \"2\", key: \"1w4ew1\" }],\n [\"path\", { d: \"M7 11V7a5 5 0 0 1 10 0v4\", key: \"fwvmzm\" }]\n];\nconst Lock = createLucideIcon(\"lock\", __iconNode);\n\nexport { __iconNode, Lock as default };\n//# sourceMappingURL=lock.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { x: \"14\", y: \"3\", width: \"5\", height: \"18\", rx: \"1\", key: \"kaeet6\" }],\n [\"rect\", { x: \"5\", y: \"3\", width: \"5\", height: \"18\", rx: \"1\", key: \"1wsw3u\" }]\n];\nconst Pause = createLucideIcon(\"pause\", __iconNode);\n\nexport { __iconNode, Pause as default };\n//# sourceMappingURL=pause.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\",\n key: \"1a8usu\"\n }\n ],\n [\"path\", { d: \"m15 5 4 4\", key: \"1mk7zo\" }]\n];\nconst Pencil = createLucideIcon(\"pencil\", __iconNode);\n\nexport { __iconNode, Pencil as default };\n//# sourceMappingURL=pencil.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\",\n key: \"10ikf1\"\n }\n ]\n];\nconst Play = createLucideIcon(\"play\", __iconNode);\n\nexport { __iconNode, Play as default };\n//# sourceMappingURL=play.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n];\nconst Scissors = createLucideIcon(\"scissors\", __iconNode);\n\nexport { __iconNode, Scissors as default };\n//# sourceMappingURL=scissors.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M21 10.656V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h12.344\", key: \"2acyp4\" }\n ],\n [\"path\", { d: \"m9 11 3 3L22 4\", key: \"1pflzl\" }]\n];\nconst SquareCheckBig = createLucideIcon(\"square-check-big\", __iconNode);\n\nexport { __iconNode, SquareCheckBig as default };\n//# sourceMappingURL=square-check-big.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3v12\", key: \"1x0j5s\" }],\n [\"path\", { d: \"m17 8-5-5-5 5\", key: \"7q97r8\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }]\n];\nconst Upload = createLucideIcon(\"upload\", __iconNode);\n\nexport { __iconNode, Upload as default };\n//# sourceMappingURL=upload.mjs.map\n","/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.mjs.map\n","export type FileBrowserUploadCandidate = {\n\tfile: File\n\trelativePath: string\n}\n\ntype FileSystemEntryLike = FileSystemFileEntryLike | FileSystemDirectoryEntryLike\n\ntype FileSystemFileEntryLike = {\n\tisFile: true\n\tisDirectory: false\n\tname: string\n\tfile: (success: (file: File) => void, error?: (error: DOMException) => void) => void\n}\n\ntype FileSystemDirectoryEntryLike = {\n\tisFile: false\n\tisDirectory: true\n\tname: string\n\tcreateReader: () => {\n\t\treadEntries: (success: (entries: FileSystemEntryLike[]) => void, error?: (error: DOMException) => void) => void\n\t}\n}\n\ntype DataTransferItemWithEntry = {\n\twebkitGetAsEntry?: () => FileSystemEntryLike | null\n}\n\nexport async function collectUploadCandidatesFromDataTransfer(\n\tdataTransfer: DataTransfer\n): Promise<FileBrowserUploadCandidate[]> {\n\tconst entries = Array.from(dataTransfer.items)\n\t\t.map((item) => (item as unknown as DataTransferItemWithEntry).webkitGetAsEntry?.())\n\t\t.filter((entry): entry is FileSystemEntryLike => Boolean(entry))\n\n\tif (entries.length === 0) {\n\t\treturn getFileBrowserUploadCandidates(dataTransfer.files)\n\t}\n\n\tconst candidates: FileBrowserUploadCandidate[] = []\n\tfor (const entry of entries) {\n\t\tcandidates.push(...(await collectEntryCandidates(entry)))\n\t}\n\treturn candidates\n}\n\nexport function getFileBrowserUploadCandidates(files: File[] | FileList): FileBrowserUploadCandidate[] {\n\treturn Array.from(files).map((file) => ({\n\t\tfile,\n\t\trelativePath: sanitizeRelativePath(getFileRelativePath(file))\n\t}))\n}\n\nasync function collectEntryCandidates(entry: FileSystemEntryLike, prefix = ''): Promise<FileBrowserUploadCandidate[]> {\n\tif (entry.isFile) {\n\t\tconst file = await readEntryFile(entry)\n\t\treturn [\n\t\t\t{\n\t\t\t\tfile,\n\t\t\t\trelativePath: sanitizeRelativePath(joinRelativePath(prefix, file.name))\n\t\t\t}\n\t\t]\n\t}\n\n\tconst nextPrefix = joinRelativePath(prefix, entry.name)\n\tconst entries = await readAllDirectoryEntries(entry)\n\tconst candidates: FileBrowserUploadCandidate[] = []\n\n\tfor (const child of entries) {\n\t\tcandidates.push(...(await collectEntryCandidates(child, nextPrefix)))\n\t}\n\n\treturn candidates\n}\n\nfunction readEntryFile(entry: FileSystemFileEntryLike): Promise<File> {\n\treturn new Promise((resolve, reject) => {\n\t\tentry.file(resolve, reject)\n\t})\n}\n\nasync function readAllDirectoryEntries(entry: FileSystemDirectoryEntryLike): Promise<FileSystemEntryLike[]> {\n\tconst reader = entry.createReader()\n\tconst entries: FileSystemEntryLike[] = []\n\n\twhile (true) {\n\t\tconst batch = await new Promise<FileSystemEntryLike[]>((resolve, reject) => {\n\t\t\treader.readEntries(resolve, reject)\n\t\t})\n\t\tif (batch.length === 0) {\n\t\t\tbreak\n\t\t}\n\t\tentries.push(...batch)\n\t}\n\n\treturn entries\n}\n\nfunction getFileRelativePath(file: File): string {\n\tconst withRelativePath = file as File & { webkitRelativePath?: string }\n\treturn withRelativePath.webkitRelativePath || file.name\n}\n\nfunction joinRelativePath(...parts: string[]): string {\n\treturn parts.filter(Boolean).join('/')\n}\n\nfunction sanitizeRelativePath(path: string): string {\n\treturn path\n\t\t.replaceAll('\\\\', '/')\n\t\t.split('/')\n\t\t.filter((part) => part && part !== '.' && part !== '..')\n\t\t.join('/')\n}\n","import { zipSync } from 'fflate'\nimport type { Zippable } from 'fflate'\nimport { FileBrowserAdapterError } from '../core/types'\nimport type { FileBrowserAdapter, FileBrowserUploadOptions, FileNode, MultipartUploadPart } from '../core/types'\nimport { getFileBrowserBasename, getFileBrowserDirname, joinFileBrowserPath } from '../core/path'\n\nexport type TransferStatus = 'queued' | 'uploading' | 'paused' | 'failed' | 'completed' | 'cancelled'\n\nexport type UploadTransfer = {\n\tid: string\n\tkind: 'upload'\n\tstatus: TransferStatus\n\tpath: string\n\tname: string\n\tloadedBytes: number\n\ttotalBytes: number\n\tbytesPerSecond?: number\n\tcompletedParts: MultipartUploadPart[]\n\tcreatedAt: string\n\tupdatedAt: string\n\terror?: string\n\tuploadId?: string\n\tpartSize?: number\n\tfile?: File\n\tonConflict?: FileBrowserUploadOptions['onConflict']\n\tadapter?: FileBrowserAdapter\n\tresult?: FileNode\n\tabortController?: AbortController\n\tgroup?: UploadTransferGroup\n}\n\nexport type UploadTransferGroup = {\n\tid: string\n\tname: string\n\ttotalFiles: number\n\tcreatedFolders: number\n}\n\nexport type BulkDownloadJob = {\n\tid: string\n\tkind: 'bulk-download'\n\tstatus: 'preparing' | 'warning' | 'ready' | 'failed'\n\tstrategy: 'single' | 'server' | 'client'\n\tpaths: string[]\n\tselectedBytes: number\n\tcreatedAt: string\n\tupdatedAt: string\n\turl?: string\n\texpiresAt?: string\n\twarning?: 'client_zip_size'\n\terror?: string\n}\n\ntype InternalBulkDownloadJob = BulkDownloadJob & {\n\tadapter?: FileBrowserAdapter\n}\n\nexport type TransferSnapshot = {\n\tuploads: UploadTransfer[]\n\tdownloads: BulkDownloadJob[]\n}\n\nexport type EnqueueUploadInput = {\n\tadapter: FileBrowserAdapter\n\tdestinationPath: string\n\tfile: File\n\tonConflict?: FileBrowserUploadOptions['onConflict']\n\tgroup?: UploadTransferGroup\n}\n\nexport type ResumeRestoredUploadInput = {\n\tid: string\n\tadapter: FileBrowserAdapter\n\tfile: File\n\tonConflict?: FileBrowserUploadOptions['onConflict']\n}\n\nexport type PrepareBulkDownloadInput = {\n\tadapter: FileBrowserAdapter\n\tpaths: string[]\n\tselectedBytes: number\n\twarnZipSizeBytes?: number\n\tallowClientZipFallback?: boolean\n}\n\nexport type PrepareSingleDownloadInput = {\n\tadapter: FileBrowserAdapter\n\tpath: string\n\tselectedBytes?: number\n}\n\nexport type TransferManagerOptions = {\n\tstorage?: Storage | null\n\tstorageKey?: string\n\tidFactory?: () => string\n\tnow?: () => Date\n\tmaxConcurrentUploads?: number\n}\n\ntype PersistedUploadTransfer = Pick<\n\tUploadTransfer,\n\t| 'id'\n\t| 'kind'\n\t| 'status'\n\t| 'path'\n\t| 'name'\n\t| 'loadedBytes'\n\t| 'totalBytes'\n\t| 'bytesPerSecond'\n\t| 'completedParts'\n\t| 'createdAt'\n\t| 'updatedAt'\n\t| 'error'\n\t| 'uploadId'\n\t| 'partSize'\n\t| 'onConflict'\n\t| 'group'\n>\n\ntype PersistedTransferSnapshot = {\n\tuploads: PersistedUploadTransfer[]\n\tdownloads: BulkDownloadJob[]\n}\n\ntype UploadSpeedSample = {\n\tloadedBytes: number\n\ttimeMs: number\n}\n\nconst DEFAULT_STORAGE_KEY = 'react-file-browser-transfers'\nconst DOWNLOAD_RETENTION_MS = 24 * 60 * 60 * 1000\n\nexport class TransferManager {\n\tprivate readonly uploads = new Map<string, UploadTransfer>()\n\tprivate readonly downloads = new Map<string, InternalBulkDownloadJob>()\n\tprivate readonly uploadSpeedSamples = new Map<string, UploadSpeedSample>()\n\tprivate readonly subscribers = new Set<() => void>()\n\tprivate readonly activeTasks = new Set<Promise<void>>()\n\tprivate readonly runningUploadIds = new Set<string>()\n\tprivate readonly storage?: Storage\n\tprivate readonly storageKey: string\n\tprivate readonly idFactory: () => string\n\tprivate readonly now: () => Date\n\tprivate readonly maxConcurrentUploads: number\n\tprivate snapshotCache: TransferSnapshot | undefined\n\n\tconstructor(options: TransferManagerOptions = {}) {\n\t\tthis.storage = options.storage ?? undefined\n\t\tthis.storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY\n\t\tthis.idFactory = options.idFactory ?? createId\n\t\tthis.now = options.now ?? (() => new Date())\n\t\tthis.maxConcurrentUploads = validateMaxConcurrentUploads(options.maxConcurrentUploads)\n\t\tthis.restorePersisted()\n\t\tif (this.downloads.size > 0) {\n\t\t\tthis.pruneExpiredDownloads()\n\t\t}\n\t}\n\n\tsubscribe(listener: () => void): () => void {\n\t\tthis.subscribers.add(listener)\n\t\treturn () => {\n\t\t\tthis.subscribers.delete(listener)\n\t\t}\n\t}\n\n\tgetSnapshot(): TransferSnapshot {\n\t\tthis.snapshotCache ??= {\n\t\t\tuploads: Array.from(this.uploads.values()).map(cloneUpload),\n\t\t\tdownloads: Array.from(this.downloads.values()).map((download) => ({\n\t\t\t\t...cloneDownload(download)\n\t\t\t}))\n\t\t}\n\t\treturn this.snapshotCache\n\t}\n\n\tgetUpload(id: string): UploadTransfer | undefined {\n\t\tconst upload = this.uploads.get(id)\n\t\treturn upload ? cloneUpload(upload) : undefined\n\t}\n\n\tgetRestorableUploads(): UploadTransfer[] {\n\t\treturn Array.from(this.uploads.values())\n\t\t\t.filter((upload) => ['queued', 'uploading', 'paused', 'failed'].includes(upload.status))\n\t\t\t.filter((upload) => !upload.file || !upload.adapter)\n\t\t\t.map(cloneUpload)\n\t}\n\n\tdismissRestoredUploads(ids: string[]): void {\n\t\tfor (const id of ids) {\n\t\t\tconst upload = this.uploads.get(id)\n\t\t\tif (!upload) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tupload.status = 'cancelled'\n\t\t\tthis.uploadSpeedSamples.delete(id)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t}\n\t\tthis.persistAndNotify()\n\t}\n\n\tdismissDownload(id: string): void {\n\t\tconst download = this.downloads.get(id)\n\t\tif (!download) {\n\t\t\treturn\n\t\t}\n\n\t\trevokeDownloadUrl(download.url)\n\t\tthis.downloads.delete(id)\n\t\tthis.persistAndNotify()\n\t}\n\n\thasActiveTransfers(): boolean {\n\t\tconst snapshot = this.getSnapshot()\n\t\treturn (\n\t\t\tsnapshot.uploads.some((upload) => ['queued', 'uploading'].includes(upload.status)) ||\n\t\t\tsnapshot.downloads.some((download) => download.status === 'preparing')\n\t\t)\n\t}\n\n\tenqueueUpload({ adapter, destinationPath, file, group, onConflict }: EnqueueUploadInput): string {\n\t\tconst id = this.idFactory()\n\t\tconst timestamp = this.timestamp()\n\t\tconst upload: UploadTransfer = {\n\t\t\tid,\n\t\t\tkind: 'upload',\n\t\t\tstatus: 'queued',\n\t\t\tpath: destinationPath,\n\t\t\tname: file.name,\n\t\t\tloadedBytes: 0,\n\t\t\ttotalBytes: file.size,\n\t\t\tcompletedParts: [],\n\t\t\tcreatedAt: timestamp,\n\t\t\tupdatedAt: timestamp,\n\t\t\tadapter,\n\t\t\tfile,\n\t\t\tgroup,\n\t\t\tonConflict,\n\t\t\tabortController: new AbortController()\n\t\t}\n\t\tthis.uploads.set(id, upload)\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\treturn id\n\t}\n\n\tresumeUpload(id: string): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload || !upload.adapter || !upload.file || this.runningUploadIds.has(id)) {\n\t\t\treturn Promise.resolve()\n\t\t}\n\n\t\tupload.status = 'queued'\n\t\tupload.error = undefined\n\t\tupload.bytesPerSecond = undefined\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.abortController = new AbortController()\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\treturn Promise.resolve()\n\t}\n\n\tresumeRestoredUpload({ adapter, file, id, onConflict }: ResumeRestoredUploadInput): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload) {\n\t\t\treturn Promise.resolve()\n\t\t}\n\n\t\tupload.adapter = adapter\n\t\tupload.file = file\n\t\tupload.name = file.name\n\t\tupload.totalBytes = file.size\n\t\tupload.onConflict = onConflict ?? upload.onConflict\n\t\tupload.status = 'queued'\n\t\tupload.error = undefined\n\t\tupload.bytesPerSecond = undefined\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.abortController = new AbortController()\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\treturn Promise.resolve()\n\t}\n\n\tpauseUpload(id: string): void {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload) {\n\t\t\treturn\n\t\t}\n\t\tupload.status = 'paused'\n\t\tupload.abortController?.abort()\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t}\n\n\tasync cancelUpload(id: string): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload) {\n\t\t\treturn\n\t\t}\n\n\t\tupload.status = 'cancelled'\n\t\tupload.abortController?.abort()\n\t\tthis.uploadSpeedSamples.delete(id)\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\tthis.pumpUploadQueue()\n\t\tif (upload.uploadId && upload.adapter?.abortMultipartUpload) {\n\t\t\tawait upload.adapter.abortMultipartUpload(upload.uploadId)\n\t\t}\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\twhile (this.activeTasks.size > 0) {\n\t\t\tawait Promise.allSettled(Array.from(this.activeTasks))\n\t\t}\n\t}\n\n\tasync prepareBulkDownload({\n\t\tadapter,\n\t\tpaths,\n\t\tselectedBytes,\n\t\twarnZipSizeBytes = Number.POSITIVE_INFINITY,\n\t\tallowClientZipFallback = true\n\t}: PrepareBulkDownloadInput): Promise<BulkDownloadJob> {\n\t\tconst id = this.idFactory()\n\t\tconst timestamp = this.timestamp()\n\t\tconst job: InternalBulkDownloadJob = {\n\t\t\tid,\n\t\t\tkind: 'bulk-download',\n\t\t\tstatus: 'preparing',\n\t\t\tstrategy: adapter.bulkDownloadUrl ? 'server' : 'client',\n\t\t\tadapter,\n\t\t\tpaths: [...paths],\n\t\t\tselectedBytes,\n\t\t\tcreatedAt: timestamp,\n\t\t\tupdatedAt: timestamp\n\t\t}\n\t\tthis.downloads.set(id, job)\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tif (adapter.bulkDownloadUrl) {\n\t\t\t\tconst result = await adapter.bulkDownloadUrl(paths)\n\t\t\t\tjob.status = 'ready'\n\t\t\t\tjob.url = result.url\n\t\t\t\tjob.expiresAt = result.expiresAt\n\t\t\t} else if (!allowClientZipFallback) {\n\t\t\t\tthrow new Error('Client-side ZIP fallback is disabled.')\n\t\t\t} else if (selectedBytes > warnZipSizeBytes) {\n\t\t\t\tjob.status = 'warning'\n\t\t\t\tjob.warning = 'client_zip_size'\n\t\t\t} else {\n\t\t\t\tjob.url = await createClientZipUrl(adapter, paths)\n\t\t\t\tjob.status = 'ready'\n\t\t\t}\n\t\t} catch (caught) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = toErrorMessage(caught)\n\t\t}\n\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\treturn cloneDownload(job)\n\t}\n\n\tasync prepareSingleDownload({\n\t\tadapter,\n\t\tpath,\n\t\tselectedBytes = 0\n\t}: PrepareSingleDownloadInput): Promise<BulkDownloadJob> {\n\t\tconst id = this.idFactory()\n\t\tconst timestamp = this.timestamp()\n\t\tconst job: InternalBulkDownloadJob = {\n\t\t\tid,\n\t\t\tkind: 'bulk-download',\n\t\t\tstatus: 'preparing',\n\t\t\tstrategy: 'single',\n\t\t\tadapter,\n\t\t\tpaths: [path],\n\t\t\tselectedBytes,\n\t\t\tcreatedAt: timestamp,\n\t\t\tupdatedAt: timestamp\n\t\t}\n\t\tthis.downloads.set(id, job)\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tjob.url = await adapter.signedUrl(path)\n\t\t\tjob.status = 'ready'\n\t\t} catch (caught) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = toErrorMessage(caught)\n\t\t}\n\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\treturn cloneDownload(job)\n\t}\n\n\tasync confirmBulkDownload(id: string): Promise<BulkDownloadJob | undefined> {\n\t\tconst job = this.downloads.get(id)\n\t\tif (!job) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tif (job.status !== 'warning') {\n\t\t\treturn cloneDownload(job)\n\t\t}\n\n\t\tif (!job.adapter) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = 'This download can no longer continue in the current session.'\n\t\t\tjob.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t\treturn cloneDownload(job)\n\t\t}\n\n\t\tjob.status = 'preparing'\n\t\tjob.warning = undefined\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tjob.url = await createClientZipUrl(job.adapter, job.paths)\n\t\t\tjob.status = 'ready'\n\t\t} catch (caught) {\n\t\t\tjob.status = 'failed'\n\t\t\tjob.error = toErrorMessage(caught)\n\t\t}\n\n\t\tjob.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\t\treturn cloneDownload(job)\n\t}\n\n\tprivate async runUpload(id: string): Promise<void> {\n\t\tconst upload = this.uploads.get(id)\n\t\tif (!upload?.adapter || !upload.file || upload.status !== 'queued') {\n\t\t\treturn\n\t\t}\n\n\t\tupload.status = 'uploading'\n\t\tupload.updatedAt = this.timestamp()\n\t\tthis.persistAndNotify()\n\n\t\ttry {\n\t\t\tconst result = hasMultipart(upload.adapter)\n\t\t\t\t? await this.runMultipartUpload(upload)\n\t\t\t\t: await this.runSimpleUpload(upload)\n\t\t\tif (['paused', 'cancelled'].includes(upload.status)) {\n\t\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\t\tthis.persistAndNotify()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tupload.status = 'completed'\n\t\t\tupload.loadedBytes = upload.totalBytes\n\t\t\tupload.result = result\n\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t} catch (caught) {\n\t\t\tif (['paused', 'cancelled'].includes(upload.status)) {\n\t\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\t\tthis.persistAndNotify()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tupload.status = 'failed'\n\t\t\tupload.error = toErrorMessage(caught)\n\t\t\tthis.uploadSpeedSamples.delete(upload.id)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t}\n\t}\n\n\tprivate async runSimpleUpload(upload: UploadTransfer): Promise<FileNode> {\n\t\tif (!upload.adapter || !upload.file) {\n\t\t\tthrow new Error('Upload is missing adapter or file')\n\t\t}\n\n\t\treturn upload.adapter.upload(upload.path, upload.file, {\n\t\t\tonConflict: upload.onConflict,\n\t\t\tsignal: upload.abortController?.signal,\n\t\t\tonProgress: (loaded, total) => {\n\t\t\t\tthis.updateUploadProgress(upload, loaded, total)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate async runMultipartUpload(upload: UploadTransfer): Promise<FileNode> {\n\t\tconst adapter = upload.adapter\n\t\tconst file = upload.file\n\t\tif (!adapter || !file || !hasMultipart(adapter)) {\n\t\t\tthrow new Error('Multipart upload is not available')\n\t\t}\n\n\t\tif (!upload.uploadId || !upload.partSize) {\n\t\t\tawait prepareMultipartDestination(upload)\n\t\t\tconst created = await adapter.createMultipartUpload(upload.path, file.size)\n\t\t\tupload.uploadId = created.uploadId\n\t\t\tupload.partSize = created.partSize\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t}\n\n\t\tconst partSize = upload.partSize\n\t\tconst partCount = Math.ceil(file.size / partSize)\n\t\tfor (let partNumber = 1; partNumber <= partCount; partNumber += 1) {\n\t\t\tif (upload.completedParts.some((part) => part.partNumber === partNumber)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst start = (partNumber - 1) * partSize\n\t\t\tconst end = Math.min(start + partSize, file.size)\n\t\t\tconst chunk = file.slice(start, end)\n\t\t\tconst completedBeforePart = completedBytes(upload)\n\t\t\tconst result = await adapter.uploadPart({\n\t\t\t\tuploadId: upload.uploadId,\n\t\t\t\tpartNumber,\n\t\t\t\tchunk,\n\t\t\t\tsignal: upload.abortController?.signal,\n\t\t\t\tonProgress: (loaded) => {\n\t\t\t\t\tthis.updateUploadProgress(upload, completedBeforePart + loaded, upload.totalBytes)\n\t\t\t\t}\n\t\t\t})\n\t\t\tupload.completedParts = [...upload.completedParts, { partNumber, etag: result.etag }].sort(\n\t\t\t\t(left, right) => left.partNumber - right.partNumber\n\t\t\t)\n\t\t\tupload.loadedBytes = completedBytes(upload)\n\t\t\tupload.updatedAt = this.timestamp()\n\t\t\tthis.persistAndNotify()\n\t\t}\n\n\t\treturn adapter.completeMultipartUpload({\n\t\t\tuploadId: upload.uploadId,\n\t\t\tparts: upload.completedParts\n\t\t})\n\t}\n\n\tprivate updateUploadProgress(upload: UploadTransfer, loadedBytes: number, totalBytes: number): void {\n\t\tconst sampledAt = this.now()\n\t\tconst timeMs = sampledAt.getTime()\n\t\tconst previous = this.uploadSpeedSamples.get(upload.id)\n\n\t\tupload.loadedBytes = loadedBytes\n\t\tupload.totalBytes = totalBytes\n\t\tif (previous && loadedBytes > previous.loadedBytes && timeMs > previous.timeMs) {\n\t\t\tupload.bytesPerSecond = ((loadedBytes - previous.loadedBytes) / (timeMs - previous.timeMs)) * 1000\n\t\t}\n\t\tthis.uploadSpeedSamples.set(upload.id, { loadedBytes, timeMs })\n\t\tupload.updatedAt = sampledAt.toISOString()\n\t\tthis.persistAndNotify()\n\t}\n\n\tprivate pumpUploadQueue(): void {\n\t\twhile (this.runningUploadIds.size < this.maxConcurrentUploads) {\n\t\t\tconst upload = Array.from(this.uploads.values()).find(\n\t\t\t\t(candidate) =>\n\t\t\t\t\tcandidate.status === 'queued' &&\n\t\t\t\t\tBoolean(candidate.adapter) &&\n\t\t\t\t\tBoolean(candidate.file) &&\n\t\t\t\t\t!this.runningUploadIds.has(candidate.id)\n\t\t\t)\n\t\t\tif (!upload) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.runningUploadIds.add(upload.id)\n\t\t\tconst task = this.runUpload(upload.id)\n\t\t\tthis.activeTasks.add(task)\n\t\t\tconst release = () => {\n\t\t\t\tthis.activeTasks.delete(task)\n\t\t\t\tthis.runningUploadIds.delete(upload.id)\n\t\t\t\tthis.pumpUploadQueue()\n\t\t\t}\n\t\t\tvoid task.then(release, release)\n\t\t}\n\t}\n\n\tprivate persistAndNotify(): void {\n\t\tthis.snapshotCache = undefined\n\t\tthis.persist()\n\t\tfor (const subscriber of this.subscribers) {\n\t\t\tsubscriber()\n\t\t}\n\t}\n\n\tprivate persist(): void {\n\t\tif (!this.storage) {\n\t\t\treturn\n\t\t}\n\n\t\tconst payload: PersistedTransferSnapshot = {\n\t\t\tuploads: Array.from(this.uploads.values()).map(toPersistedUpload),\n\t\t\tdownloads: Array.from(this.downloads.values()).map(toPersistedDownload)\n\t\t}\n\t\tthis.storage.setItem(this.storageKey, JSON.stringify(payload))\n\t}\n\n\tprivate restorePersisted(): void {\n\t\tif (!this.storage) {\n\t\t\treturn\n\t\t}\n\n\t\tconst raw = this.storage.getItem(this.storageKey)\n\t\tif (!raw) {\n\t\t\treturn\n\t\t}\n\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(raw) as Partial<PersistedTransferSnapshot>\n\t\t\tfor (const upload of parsed.uploads ?? []) {\n\t\t\t\tconst restored = restorePersistedUpload(upload)\n\t\t\t\tthis.uploads.set(restored.id, restored)\n\t\t\t}\n\t\t\tfor (const download of parsed.downloads ?? []) {\n\t\t\t\tconst restored = restorePersistedDownload(download)\n\t\t\t\tthis.downloads.set(restored.id, restored)\n\t\t\t}\n\t\t} catch {\n\t\t\tthis.storage.removeItem(this.storageKey)\n\t\t}\n\t}\n\n\tprivate timestamp(): string {\n\t\treturn this.now().toISOString()\n\t}\n\n\tprivate pruneExpiredDownloads(): void {\n\t\tconst nowMs = this.now().getTime()\n\t\tlet changed = false\n\n\t\tfor (const [id, download] of this.downloads) {\n\t\t\tif (!isExpiredOrStaleDownload(download, nowMs)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\trevokeDownloadUrl(download.url)\n\t\t\tthis.downloads.delete(id)\n\t\t\tchanged = true\n\t\t}\n\n\t\tif (!changed) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.snapshotCache = undefined\n\t\tthis.persist()\n\t}\n}\n\nfunction hasMultipart(\n\tadapter: FileBrowserAdapter\n): adapter is FileBrowserAdapter &\n\tRequired<Pick<FileBrowserAdapter, 'createMultipartUpload' | 'uploadPart' | 'completeMultipartUpload'>> {\n\treturn (\n\t\ttypeof adapter.createMultipartUpload === 'function' &&\n\t\ttypeof adapter.uploadPart === 'function' &&\n\t\ttypeof adapter.completeMultipartUpload === 'function'\n\t)\n}\n\nfunction completedBytes(upload: UploadTransfer): number {\n\tconst partSize = upload.partSize ?? upload.totalBytes\n\treturn upload.completedParts.reduce((total, part) => {\n\t\tconst start = (part.partNumber - 1) * partSize\n\t\treturn total + Math.min(partSize, upload.totalBytes - start)\n\t}, 0)\n}\n\nasync function prepareMultipartDestination(upload: UploadTransfer): Promise<void> {\n\tconst adapter = upload.adapter\n\tif (!adapter?.exists) {\n\t\treturn\n\t}\n\tconst exists: NonNullable<FileBrowserAdapter['exists']> = (paths) => adapter.exists?.(paths) ?? Promise.resolve({})\n\n\tconst current = await exists([upload.path])\n\tif (!current[upload.path]) {\n\t\treturn\n\t}\n\n\tif (upload.onConflict === 'keep-both') {\n\t\tupload.path = await nextAvailableUploadPath(exists, upload.path)\n\t\treturn\n\t}\n\n\tif (upload.onConflict !== 'replace') {\n\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${upload.path}`)\n\t}\n}\n\nasync function nextAvailableUploadPath(\n\texists: NonNullable<FileBrowserAdapter['exists']>,\n\tpath: string\n): Promise<string> {\n\tconst dir = getFileBrowserDirname(path)\n\tconst basename = getFileBrowserBasename(path)\n\tconst dotIndex = basename.lastIndexOf('.')\n\tconst hasExtension = dotIndex > 0\n\tconst stem = hasExtension ? basename.slice(0, dotIndex) : basename\n\tconst extension = hasExtension ? basename.slice(dotIndex) : ''\n\n\tfor (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n\t\tconst candidate = joinFileBrowserPath(dir, `${stem} (${index})${extension}`)\n\t\tconst result = await exists([candidate])\n\t\tif (!result[candidate]) {\n\t\t\treturn candidate\n\t\t}\n\t}\n\n\tthrow new FileBrowserAdapterError('conflict', `Could not allocate a unique file browser path for ${path}`)\n}\n\nfunction cloneUpload(upload: UploadTransfer): UploadTransfer {\n\treturn {\n\t\t...upload,\n\t\tgroup: upload.group ? { ...upload.group } : undefined,\n\t\tcompletedParts: upload.completedParts.map((part) => ({ ...part }))\n\t}\n}\n\nfunction cloneDownload(download: InternalBulkDownloadJob): BulkDownloadJob {\n\tconst { adapter: _adapter, ...snapshot } = download\n\tvoid _adapter\n\treturn {\n\t\t...snapshot,\n\t\tpaths: [...download.paths]\n\t}\n}\n\nfunction toPersistedUpload(upload: UploadTransfer): PersistedUploadTransfer {\n\treturn {\n\t\tid: upload.id,\n\t\tkind: upload.kind,\n\t\tstatus: upload.status,\n\t\tpath: upload.path,\n\t\tname: upload.name,\n\t\tloadedBytes: upload.loadedBytes,\n\t\ttotalBytes: upload.totalBytes,\n\t\tbytesPerSecond: upload.bytesPerSecond,\n\t\tcompletedParts: upload.completedParts.map((part) => ({ ...part })),\n\t\tcreatedAt: upload.createdAt,\n\t\tupdatedAt: upload.updatedAt,\n\t\terror: upload.error,\n\t\tuploadId: upload.uploadId,\n\t\tpartSize: upload.partSize,\n\t\tonConflict: upload.onConflict,\n\t\tgroup: upload.group ? { ...upload.group } : undefined\n\t}\n}\n\nfunction restorePersistedUpload(upload: PersistedUploadTransfer): UploadTransfer {\n\treturn {\n\t\tid: upload.id,\n\t\tkind: 'upload',\n\t\tstatus: upload.status,\n\t\tpath: upload.path,\n\t\tname: upload.name,\n\t\tloadedBytes: upload.loadedBytes,\n\t\ttotalBytes: upload.totalBytes,\n\t\tbytesPerSecond: upload.bytesPerSecond,\n\t\tcompletedParts: upload.completedParts.map((part) => ({ ...part })),\n\t\tcreatedAt: upload.createdAt,\n\t\tupdatedAt: upload.updatedAt,\n\t\terror: upload.error,\n\t\tuploadId: upload.uploadId,\n\t\tpartSize: upload.partSize,\n\t\tonConflict: upload.onConflict,\n\t\tgroup: upload.group ? { ...upload.group } : undefined\n\t}\n}\n\nfunction toPersistedDownload(download: InternalBulkDownloadJob): BulkDownloadJob {\n\treturn {\n\t\tid: download.id,\n\t\tkind: download.kind,\n\t\tstatus: download.status,\n\t\tstrategy: download.strategy,\n\t\tpaths: [...download.paths],\n\t\tselectedBytes: download.selectedBytes,\n\t\tcreatedAt: download.createdAt,\n\t\tupdatedAt: download.updatedAt,\n\t\turl: download.url,\n\t\texpiresAt: download.expiresAt,\n\t\twarning: download.warning,\n\t\terror: download.error\n\t}\n}\n\nfunction restorePersistedDownload(download: BulkDownloadJob): InternalBulkDownloadJob {\n\treturn toPersistedDownload(download)\n}\n\nfunction validateMaxConcurrentUploads(value: number | undefined): number {\n\tif (value === undefined) {\n\t\treturn Number.POSITIVE_INFINITY\n\t}\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new RangeError('maxConcurrentUploads must be a positive integer')\n\t}\n\treturn value\n}\n\nfunction isExpiredOrStaleDownload(download: InternalBulkDownloadJob, nowMs: number): boolean {\n\tif (download.status === 'preparing') {\n\t\treturn false\n\t}\n\n\tif (download.expiresAt) {\n\t\tconst expiresAtMs = Date.parse(download.expiresAt)\n\t\tif (Number.isFinite(expiresAtMs) && expiresAtMs <= nowMs) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\tconst updatedAtMs = Date.parse(download.updatedAt)\n\treturn Number.isFinite(updatedAtMs) && nowMs - updatedAtMs > DOWNLOAD_RETENTION_MS\n}\n\nfunction revokeDownloadUrl(url: string | undefined): void {\n\tif (!url?.startsWith('blob:') || typeof URL === 'undefined' || typeof URL.revokeObjectURL !== 'function') {\n\t\treturn\n\t}\n\n\tURL.revokeObjectURL(url)\n}\n\nfunction createId(): string {\n\treturn `transfer-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`\n}\n\nfunction toErrorMessage(caught: unknown): string {\n\treturn caught instanceof Error ? caught.message : String(caught)\n}\n\ntype ClientZipEntry = {\n\tpath: string\n\tarchivePath: string\n}\n\nasync function createClientZipUrl(adapter: FileBrowserAdapter, paths: string[]): Promise<string> {\n\tconst entries = await collectClientZipEntries(adapter, paths)\n\tconst zippable: Zippable = {}\n\n\tfor (const entry of entries) {\n\t\tconst url = await adapter.signedUrl(entry.path)\n\t\tconst response = await fetch(url)\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Could not fetch ${entry.path} for the client zip`)\n\t\t}\n\t\tzippable[entry.archivePath] = new Uint8Array(await response.arrayBuffer())\n\t}\n\n\tconst zip = zipSync(zippable)\n\treturn URL.createObjectURL(new Blob([zip], { type: 'application/zip' }))\n}\n\nasync function collectClientZipEntries(adapter: FileBrowserAdapter, paths: string[]): Promise<ClientZipEntry[]> {\n\tconst entries: ClientZipEntry[] = []\n\tconst seen = new Set<string>()\n\n\tfor (const path of paths) {\n\t\tawait collectClientZipPath(adapter, path, entries, seen)\n\t}\n\n\treturn entries\n}\n\nasync function collectClientZipPath(\n\tadapter: FileBrowserAdapter,\n\tpath: string,\n\tentries: ClientZipEntry[],\n\tseen: Set<string>\n): Promise<void> {\n\tif (seen.has(path)) {\n\t\treturn\n\t}\n\tseen.add(path)\n\n\tconst node = await tryStat(adapter, path)\n\tif (node?.kind === 'file') {\n\t\tentries.push({ path, archivePath: toArchivePath(path) })\n\t\treturn\n\t}\n\n\tif (node?.kind === 'folder') {\n\t\tawait collectClientZipFolder(adapter, path, entries, seen)\n\t\treturn\n\t}\n\n\tconst listed = await tryListFolder(adapter, path)\n\tif (listed) {\n\t\tfor (const item of listed) {\n\t\t\tawait collectClientZipPath(adapter, item.path, entries, seen)\n\t\t}\n\t\treturn\n\t}\n\n\tentries.push({ path, archivePath: toArchivePath(path) })\n}\n\nasync function collectClientZipFolder(\n\tadapter: FileBrowserAdapter,\n\tpath: string,\n\tentries: ClientZipEntry[],\n\tseen: Set<string>\n): Promise<void> {\n\tlet cursor: string | undefined\n\tdo {\n\t\tconst result = await adapter.list(path, { cursor })\n\t\tfor (const item of result.items) {\n\t\t\tawait collectClientZipPath(adapter, item.path, entries, seen)\n\t\t}\n\t\tcursor = result.cursor\n\t} while (cursor)\n}\n\nasync function tryStat(adapter: FileBrowserAdapter, path: string): Promise<FileNode | undefined> {\n\tif (!adapter.stat) {\n\t\treturn undefined\n\t}\n\n\ttry {\n\t\treturn await adapter.stat(path)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nasync function tryListFolder(adapter: FileBrowserAdapter, path: string): Promise<FileNode[] | undefined> {\n\ttry {\n\t\tlet cursor: string | undefined\n\t\tconst items: FileNode[] = []\n\t\tdo {\n\t\t\tconst result = await adapter.list(path, { cursor })\n\t\t\titems.push(...result.items)\n\t\t\tcursor = result.cursor\n\t\t} while (cursor)\n\t\treturn items\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nfunction toArchivePath(path: string): string {\n\treturn path.replace(/^\\/+/, '') || 'download'\n}\n","import { useEffect, useRef, useState } from 'react'\nimport type { MouseEvent, ReactNode, RefObject, TouchEvent } from 'react'\n\nexport function useNarrowViewport() {\n\tconst [narrow, setNarrow] = useState(false)\n\tuseEffect(() => {\n\t\tconst query = window.matchMedia?.('(max-width: 39.999rem)')\n\t\tif (!query) return\n\t\tconst update = () => setNarrow(query.matches)\n\t\tupdate()\n\t\tquery.addEventListener('change', update)\n\t\treturn () => query.removeEventListener('change', update)\n\t}, [])\n\treturn narrow\n}\n\nexport function useBrowserLayout(ref: RefObject<HTMLElement | null>) {\n\tconst [width, setWidth] = useState<number | null>(null)\n\tconst [rem, setRem] = useState(16)\n\n\tuseEffect(() => {\n\t\tconst element = ref.current\n\t\tif (!element) return\n\n\t\tconst measure = (nextWidth = element.clientWidth) => {\n\t\t\tsetRem(Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16)\n\t\t\tif (nextWidth > 0) setWidth(nextWidth)\n\t\t}\n\t\tmeasure()\n\t\tconst observer =\n\t\t\ttypeof ResizeObserver === 'undefined'\n\t\t\t\t? undefined\n\t\t\t\t: new ResizeObserver(([entry]) => measure(entry.contentRect.width))\n\t\tobserver?.observe(element)\n\t\tconst onResize = () => measure()\n\t\twindow.addEventListener('resize', onResize)\n\t\treturn () => {\n\t\t\tobserver?.disconnect()\n\t\t\twindow.removeEventListener('resize', onResize)\n\t\t}\n\t}, [ref])\n\n\treturn {\n\t\tisNarrow: width !== null && width < 40 * rem,\n\t\thasSidebar: width === null || width >= 64 * rem\n\t}\n}\n\nexport function useLongPress(onLongPress: () => void) {\n\tconst timer = useRef<ReturnType<typeof setTimeout> | null>(null)\n\tconst pressed = useRef(false)\n\tconst callback = useRef(onLongPress)\n\tcallback.current = onLongPress\n\n\tfunction cancel() {\n\t\tif (timer.current !== null) clearTimeout(timer.current)\n\t\ttimer.current = null\n\t}\n\n\tuseEffect(() => cancel, [])\n\n\treturn {\n\t\tonTouchStart(event: TouchEvent) {\n\t\t\tcancel()\n\t\t\tpressed.current = false\n\t\t\tif (event.touches?.length > 1 || (event.target as Element).closest('input, [data-fb-touch-control]')) return\n\t\t\ttimer.current = setTimeout(() => {\n\t\t\t\ttimer.current = null\n\t\t\t\tpressed.current = true\n\t\t\t\tcallback.current()\n\t\t\t}, 500)\n\t\t},\n\t\tonTouchMove: cancel,\n\t\tonTouchCancel() {\n\t\t\tcancel()\n\t\t\tpressed.current = false\n\t\t},\n\t\tonTouchEnd() {\n\t\t\tcancel()\n\t\t\tif (pressed.current) {\n\t\t\t\ttimer.current = setTimeout(() => {\n\t\t\t\t\ttimer.current = null\n\t\t\t\t\tpressed.current = false\n\t\t\t\t}, 350)\n\t\t\t}\n\t\t},\n\t\tonClickCapture(event: MouseEvent) {\n\t\t\tif (!pressed.current) return\n\t\t\tcancel()\n\t\t\tpressed.current = false\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t},\n\t\tonContextMenuCapture(event: MouseEvent) {\n\t\t\tif (pressed.current) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tevent.stopPropagation()\n\t\t\t}\n\t\t}\n\t}\n}\n\nconst FOCUSABLE =\n\t'button:not(:disabled), a[href], input:not(:disabled):not([type=\"hidden\"]), select:not(:disabled), textarea:not(:disabled), [tabindex=\"0\"]'\n\nexport function ResponsiveDialog({\n\tchildren,\n\tlabel,\n\tnarrow = false,\n\tonClose\n}: {\n\tchildren: ReactNode\n\tlabel: string\n\tnarrow?: boolean\n\tonClose: () => void\n}) {\n\tconst ref = useRef<HTMLDivElement>(null)\n\tconst closeRef = useRef(onClose)\n\tcloseRef.current = onClose\n\n\tuseEffect(() => {\n\t\tconst previousFocus = document.activeElement\n\t\tconst dialog = ref.current\n\t\tif (!dialog?.contains(document.activeElement)) {\n\t\t\tconst input = dialog?.querySelector<HTMLElement>('input:not([type=\"hidden\"]):not([type=\"checkbox\"])')\n\t\t\t;(input ?? dialog)?.focus({ preventScroll: true })\n\t\t}\n\t\treturn () => {\n\t\t\tif (previousFocus instanceof HTMLElement && previousFocus.isConnected) {\n\t\t\t\tpreviousFocus.focus({ preventScroll: true })\n\t\t\t}\n\t\t}\n\t}, [])\n\n\treturn (\n\t\t// oxlint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- A dialog owns focus trapping and backdrop dismissal.\n\t\t<div\n\t\t\taria-label={label}\n\t\t\taria-modal=\"true\"\n\t\t\tclassName={`fixed inset-0 z-[60] flex min-w-0 justify-center overflow-y-auto overscroll-contain bg-[color-mix(in_oklch,var(--fb-text)_40%,transparent)] p-[calc(var(--fb-gap)*3)] text-[var(--fb-text)] outline-none [overflow-wrap:anywhere] ${\n\t\t\t\tnarrow ? 'items-end' : 'items-center'\n\t\t\t}`}\n\t\t\tdata-fb-dialog={narrow ? 'sheet' : 'modal'}\n\t\t\tonClick={(event) => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tif (event.target === event.currentTarget) closeRef.current()\n\t\t\t}}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tcloseRef.current()\n\t\t\t\t}\n\t\t\t\tif (event.key !== 'Tab') return\n\t\t\t\tconst targets = Array.from(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? []).filter(\n\t\t\t\t\t(element) => !element.closest('[hidden]') && getComputedStyle(element).display !== 'none'\n\t\t\t\t)\n\t\t\t\tconst first = targets[0]\n\t\t\t\tconst last = targets.at(-1)\n\t\t\t\tif (!first) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tref.current?.focus()\n\t\t\t\t} else if (event.shiftKey && (document.activeElement === first || document.activeElement === ref.current)) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tlast?.focus()\n\t\t\t\t} else if (!event.shiftKey && document.activeElement === last) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tfirst.focus()\n\t\t\t\t}\n\t\t\t}}\n\t\t\tref={ref}\n\t\t\trole=\"dialog\"\n\t\t\tstyle={{\n\t\t\t\tpaddingBottom: 'max(calc(var(--fb-gap) * 3), env(safe-area-inset-bottom))',\n\t\t\t\tpaddingTop: 'max(calc(var(--fb-gap) * 3), env(safe-area-inset-top))'\n\t\t\t}}\n\t\t\ttabIndex={-1}\n\t\t>\n\t\t\t<div className=\"flex max-h-[calc(100dvh-max(calc(var(--fb-gap)*6),env(safe-area-inset-bottom)+env(safe-area-inset-top)))] w-full min-w-0 max-w-[calc(var(--fb-gap)*180)] flex-col items-center overflow-y-auto overscroll-contain [scrollbar-gutter:stable] [&>*]:shrink-0\">\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport function ActionSheet({ children, label, onClose }: { children: ReactNode; label: string; onClose: () => void }) {\n\treturn (\n\t\t<ResponsiveDialog label={label} narrow onClose={onClose}>\n\t\t\t<section className=\"w-full min-w-0 max-w-[calc(var(--fb-gap)*120)] rounded-[20px] bg-[var(--fb-surface)] px-4 pb-5 pt-2.5 shadow-[0_-8px_30px_color-mix(in_oklch,var(--fb-text)_14%,transparent)]\">\n\t\t\t\t<div aria-hidden=\"true\" className=\"mx-auto mb-2.5 h-1 w-10 rounded-full bg-[var(--fb-border-strong)]\" />\n\t\t\t\t<header className=\"mb-2 flex items-center justify-between gap-[calc(var(--fb-gap)*2)] border-b border-[var(--fb-border)] pb-2\">\n\t\t\t\t\t<h2 className=\"m-0 min-w-0 truncate text-[15px] font-bold\">{label}</h2>\n\t\t\t\t\t<button\n\t\t\t\t\t\taria-label={`Close ${label}`}\n\t\t\t\t\t\tclassName=\"min-h-[calc(var(--fb-gap)*11)] shrink-0 rounded-[var(--fb-radius)] px-[calc(var(--fb-gap)*3)] font-semibold text-[color-mix(in_oklch,var(--fb-accent)_80%,var(--fb-text))] focus-visible:outline-2 focus-visible:outline-[var(--fb-accent)]\"\n\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\tClose\n\t\t\t\t\t</button>\n\t\t\t\t</header>\n\t\t\t\t{children}\n\t\t\t</section>\n\t\t</ResponsiveDialog>\n\t)\n}\n","import { ChevronDown, ChevronUp, Download, Pause, Play, X } from 'lucide-react'\nimport { createContext, useContext, useEffect, useState, useSyncExternalStore } from 'react'\nimport type { PropsWithChildren } from 'react'\nimport { createPortal } from 'react-dom'\nimport { TransferManager } from './transfer-manager'\nimport { ResponsiveDialog, useNarrowViewport } from '../components/responsive'\nimport type {\n\tBulkDownloadJob,\n\tResumeRestoredUploadInput,\n\tTransferManagerOptions,\n\tTransferSnapshot,\n\tUploadTransfer,\n\tUploadTransferGroup\n} from './transfer-manager'\n\nconst TransferContext = createContext<TransferManager | null>(null)\nconst WIDGET_CONTROL_MOTION =\n\t'transition-[background-color,border-color,color,box-shadow,opacity] duration-150 ease-out motion-reduce:transition-none'\nconst WIDGET_SURFACE_MOTION =\n\t'transition-[background-color,border-color,box-shadow,opacity] duration-200 ease-out motion-reduce:transition-none'\nconst WIDGET_TOUCH_CONTROL =\n\t'min-h-[calc(var(--fb-gap)*11)] min-w-[calc(var(--fb-gap)*11)] shrink-0 whitespace-nowrap sm:min-h-7 sm:min-w-7 [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:min-w-[calc(var(--fb-gap)*11)]'\n\nexport type FileBrowserProviderProps = PropsWithChildren<{\n\tmanager?: TransferManager\n\toptions?: TransferManagerOptions\n\tresolveRestoredUpload?: (\n\t\tupload: UploadTransfer\n\t) => Omit<ResumeRestoredUploadInput, 'id'> | Promise<Omit<ResumeRestoredUploadInput, 'id'> | undefined> | undefined\n\tshowFloatingWidget?: boolean\n}>\n\nexport function FileBrowserProvider({\n\tchildren,\n\tmanager,\n\toptions,\n\tresolveRestoredUpload,\n\tshowFloatingWidget = true\n}: FileBrowserProviderProps) {\n\tconst [providerManager] = useState(() => manager ?? new TransferManager(withDefaultStorage(options)))\n\tconst transferManager = manager ?? providerManager\n\tconst snapshot = useTransfersSnapshot(transferManager)\n\tconst [resumePromptDismissed, setResumePromptDismissed] = useState(false)\n\tconst restorableUploads = transferManager.getRestorableUploads()\n\n\tuseBeforeUnloadGuard(transferManager)\n\n\tasync function resumeRestoredUploads(uploads: UploadTransfer[]) {\n\t\tfor (const upload of uploads) {\n\t\t\tif (upload.adapter && upload.file) {\n\t\t\t\tawait transferManager.resumeUpload(upload.id)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst resolved = await resolveRestoredUpload?.(upload)\n\t\t\tif (resolved) {\n\t\t\t\tawait transferManager.resumeRestoredUpload({\n\t\t\t\t\tid: upload.id,\n\t\t\t\t\t...resolved\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tsetResumePromptDismissed(true)\n\t}\n\n\treturn (\n\t\t<TransferContext.Provider value={transferManager}>\n\t\t\t{children}\n\t\t\t{showFloatingWidget ? <FloatingTransferWidget manager={transferManager} snapshot={snapshot} /> : null}\n\t\t\t{!resumePromptDismissed && restorableUploads.length > 0 ? (\n\t\t\t\t<ResumeUploadsPrompt\n\t\t\t\t\tcount={restorableUploads.length}\n\t\t\t\t\tonDismiss={() => {\n\t\t\t\t\t\ttransferManager.dismissRestoredUploads(restorableUploads.map((upload) => upload.id))\n\t\t\t\t\t\tsetResumePromptDismissed(true)\n\t\t\t\t\t}}\n\t\t\t\t\tonResume={() => {\n\t\t\t\t\t\tvoid resumeRestoredUploads(restorableUploads)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</TransferContext.Provider>\n\t)\n}\n\nexport function useTransfers(): TransferManager {\n\tconst manager = useContext(TransferContext)\n\treturn manager ?? fallbackTransferManager\n}\n\nexport function useTransferSnapshot(): TransferSnapshot {\n\treturn useTransfersSnapshot(useTransfers())\n}\n\nfunction useTransfersSnapshot(manager: TransferManager): TransferSnapshot {\n\treturn useSyncExternalStore(\n\t\t(listener) => manager.subscribe(listener),\n\t\t() => manager.getSnapshot(),\n\t\t() => ({ uploads: [], downloads: [] })\n\t)\n}\n\nfunction useBeforeUnloadGuard(manager: TransferManager): void {\n\tuseEffect(() => {\n\t\tconst listener = (event: BeforeUnloadEvent) => {\n\t\t\tif (!manager.hasActiveTransfers()) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tevent.preventDefault()\n\t\t\tevent.returnValue = ''\n\t\t}\n\t\twindow.addEventListener('beforeunload', listener)\n\t\treturn () => window.removeEventListener('beforeunload', listener)\n\t}, [manager])\n}\n\nfunction withDefaultStorage(options: TransferManagerOptions | undefined): TransferManagerOptions {\n\tif (options?.storage !== undefined) {\n\t\treturn options\n\t}\n\n\tconst storage = typeof window === 'undefined' ? undefined : window.localStorage\n\tif (!storage) {\n\t\treturn options ?? {}\n\t}\n\n\treturn {\n\t\t...options,\n\t\tstorage\n\t}\n}\n\nfunction FloatingTransferWidget({ manager, snapshot }: { manager: TransferManager; snapshot: TransferSnapshot }) {\n\tconst narrow = useNarrowViewport()\n\tconst [expanded, setExpanded] = useState<boolean | null>(null)\n\tconst isExpanded = expanded ?? !narrow\n\tconst activeUploads = snapshot.uploads.filter(isVisibleUpload)\n\tconst uploadGroups = getActiveUploadGroups(snapshot.uploads)\n\tconst groupedUploadIds = new Set(uploadGroups.flatMap((group) => group.activeUploads.map((upload) => upload.id)))\n\tconst standaloneUploads = activeUploads.filter((upload) => !groupedUploadIds.has(upload.id))\n\tconst downloads = snapshot.downloads.filter((download) =>\n\t\t['preparing', 'warning', 'ready', 'failed'].includes(download.status)\n\t)\n\n\tif (activeUploads.length === 0 && downloads.length === 0) {\n\t\treturn null\n\t}\n\n\tconst content = (\n\t\t<aside\n\t\t\taria-label=\"Transfers\"\n\t\t\tclassName={`fixed bottom-[calc(env(safe-area-inset-bottom)+var(--fb-gap)*28)] right-[max(calc(var(--fb-gap)*3),env(safe-area-inset-right))] z-50 flex max-h-[50dvh] max-w-[calc(100%-var(--fb-gap)*6)] flex-col rounded-[calc(var(--fb-radius)+2px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] px-4 py-3.5 text-[13px] text-[var(--fb-text)] shadow-[0_12px_32px_color-mix(in_oklch,var(--fb-text)_12%,transparent)] sm:bottom-[calc(env(safe-area-inset-bottom)+var(--fb-gap)*5)] sm:right-[max(calc(var(--fb-gap)*5),env(safe-area-inset-right))] ${isExpanded ? 'w-[320px]' : 'w-auto'} ${WIDGET_SURFACE_MOTION}`}\n\t\t>\n\t\t\t<div className=\"flex shrink-0 items-center justify-between gap-2\">\n\t\t\t\t<div className=\"font-bold\">Transfers</div>\n\t\t\t\t<div className=\"ml-auto text-[12px] text-[var(--fb-muted)]\">\n\t\t\t\t\t{activeUploads.length + downloads.length} active\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\taria-expanded={isExpanded}\n\t\t\t\t\taria-label={isExpanded ? 'Collapse transfers' : 'Expand transfers'}\n\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\tonClick={() => setExpanded(!isExpanded)}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t{isExpanded ? (\n\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<ChevronUp aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t{isExpanded ? (\n\t\t\t\t<div className=\"mt-2.5 flex min-h-0 min-w-0 flex-col gap-3.5 overflow-y-auto overscroll-contain [overflow-wrap:anywhere]\">\n\t\t\t\t\t{uploadGroups.map((group) => (\n\t\t\t\t\t\t<UploadGroupCard group={group} key={group.group.id} manager={manager} />\n\t\t\t\t\t))}\n\t\t\t\t\t{standaloneUploads.map((upload) => (\n\t\t\t\t\t\t<UploadTransferRow key={upload.id} manager={manager} upload={upload} />\n\t\t\t\t\t))}\n\t\t\t\t\t{downloads.map((download) => (\n\t\t\t\t\t\t<div className=\"text-[12px] text-[var(--fb-muted)]\" key={download.id}>\n\t\t\t\t\t\t\t{download.status === 'ready' && download.url ? (\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-between gap-2 rounded-[var(--fb-radius)] bg-[var(--fb-ok-soft)] py-1 pl-1 pr-1.5\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\taria-label=\"Open prepared download\"\n\t\t\t\t\t\t\t\t\t\tclassName={`inline-flex min-h-[calc(var(--fb-gap)*11)] min-w-0 items-center gap-1.5 rounded-[calc(var(--fb-radius)-2px)] px-2 py-1 font-semibold text-[color-mix(in_oklch,var(--fb-ok)_85%,var(--fb-text))] hover:bg-[color-mix(in_oklch,var(--fb-ok-soft)_60%,var(--fb-surface))] sm:min-h-8 [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] ${WIDGET_CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\t\tdownload\n\t\t\t\t\t\t\t\t\t\thref={download.url}\n\t\t\t\t\t\t\t\t\t\tonClick={() => manager.dismissDownload(download.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Download aria-hidden=\"true\" className=\"size-3.5 shrink-0\" />\n\t\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{formatDownloadReadyLabel(download)}</span>\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\taria-label=\"Dismiss download\"\n\t\t\t\t\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\t\t\t\t\tonClick={() => manager.dismissDownload(download.id)}\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{download.status === 'warning' ? (\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-between gap-2\">\n\t\t\t\t\t\t\t\t\t<span>Large client zip</span>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\tclassName={widgetTextButton()}\n\t\t\t\t\t\t\t\t\t\tonClick={() => void manager.confirmBulkDownload(download.id)}\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{download.status === 'preparing' ? (\n\t\t\t\t\t\t\t\t<div className=\"flex flex-col gap-1.5\">\n\t\t\t\t\t\t\t\t\t<span className=\"font-semibold text-[var(--fb-text)]\">Preparing zip</span>\n\t\t\t\t\t\t\t\t\t<span className=\"relative h-1.5 overflow-hidden rounded-full bg-[var(--fb-surface-2)]\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"absolute inset-y-0 left-[20%] w-[30%] animate-pulse rounded-full bg-[var(--fb-accent)] motion-reduce:animate-none\" />\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{download.status === 'failed' ? (\n\t\t\t\t\t\t\t\t<span className=\"text-[var(--fb-danger)]\">{download.error ?? 'Download failed'}</span>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</aside>\n\t)\n\n\treturn createPortal(content, document.body)\n}\n\ntype ActiveUploadGroup = {\n\tgroup: UploadTransferGroup\n\tuploads: UploadTransfer[]\n\tactiveUploads: UploadTransfer[]\n\tcompletedCount: number\n}\n\nfunction UploadGroupCard({ group, manager }: { group: ActiveUploadGroup; manager: TransferManager }) {\n\treturn (\n\t\t<div className={WIDGET_SURFACE_MOTION}>\n\t\t\t<div className=\"flex items-center justify-between gap-2\">\n\t\t\t\t<div className=\"min-w-0\">\n\t\t\t\t\t<div className=\"truncate font-semibold\">Uploading {group.group.name}</div>\n\t\t\t\t\t<div className=\"text-[12px] text-[var(--fb-muted)]\">{formatUploadGroupSummary(group)}</div>\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\taria-label={`Cancel upload group ${group.group.name}`}\n\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tfor (const upload of group.activeUploads) {\n\t\t\t\t\t\t\tvoid manager.cancelUpload(upload.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t\ttitle=\"Cancel\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<X aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclassName={`mt-2.5 flex flex-col gap-2.5 border-l-2 border-[var(--fb-border)] pl-3 ${WIDGET_SURFACE_MOTION}`}\n\t\t\t>\n\t\t\t\t{group.activeUploads.map((upload) => (\n\t\t\t\t\t<UploadTransferRow compact key={upload.id} manager={manager} upload={upload} />\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction UploadTransferRow({\n\tcompact = false,\n\tmanager,\n\tupload\n}: {\n\tcompact?: boolean\n\tmanager: TransferManager\n\tupload: UploadTransfer\n}) {\n\treturn (\n\t\t<div className={WIDGET_SURFACE_MOTION}>\n\t\t\t<div className=\"flex items-center justify-between gap-2\">\n\t\t\t\t<div className=\"min-w-0\">\n\t\t\t\t\t<span className=\"block truncate font-semibold\">{upload.name}</span>\n\t\t\t\t\t<span className=\"text-[12px] text-[var(--fb-muted)]\">{formatUploadStatus(upload)}</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"flex shrink-0 items-center gap-1\">\n\t\t\t\t\t{['queued', 'uploading'].includes(upload.status) ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label={`Pause upload ${upload.name}`}\n\t\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\t\tonClick={() => manager.pauseUpload(upload.id)}\n\t\t\t\t\t\t\ttitle=\"Pause\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Pause aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{['failed', 'paused'].includes(upload.status) ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label={`Resume upload ${upload.name}`}\n\t\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\t\tonClick={() => void manager.resumeUpload(upload.id)}\n\t\t\t\t\t\t\ttitle=\"Resume\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Play aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<button\n\t\t\t\t\t\taria-label={`Cancel upload ${upload.name}`}\n\t\t\t\t\t\tclassName={widgetIconButton()}\n\t\t\t\t\t\tonClick={() => void manager.cancelUpload(upload.id)}\n\t\t\t\t\t\ttitle=\"Cancel\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<X aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclassName={`h-1.5 overflow-hidden rounded-full bg-[var(--fb-surface-2)] ${WIDGET_SURFACE_MOTION} ${\n\t\t\t\t\tcompact ? 'mt-1' : 'mt-1.5'\n\t\t\t\t}`}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"h-full rounded-full bg-[var(--fb-accent)] transition-[width] duration-300 ease-out motion-reduce:transition-none\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: `${Math.min(100, upload.totalBytes ? (upload.loadedBytes / upload.totalBytes) * 100 : 0)}%`\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction ResumeUploadsPrompt({\n\tcount,\n\tonDismiss,\n\tonResume\n}: {\n\tcount: number\n\tonDismiss: () => void\n\tonResume: () => void\n}) {\n\tconst narrow = useNarrowViewport()\n\treturn createPortal(\n\t\t<ResponsiveDialog label=\"Resume uploads\" narrow={narrow} onClose={onDismiss}>\n\t\t\t<div\n\t\t\t\tclassName={`w-[min(400px,100%)] rounded-[calc(var(--fb-radius)+6px)] bg-[var(--fb-surface)] p-6 shadow-[0_24px_60px_color-mix(in_oklch,var(--fb-text)_28%,transparent)] ${WIDGET_SURFACE_MOTION}`}\n\t\t\t>\n\t\t\t\t<h2 className=\"m-0 text-[17px] font-bold\">Resume uploads</h2>\n\t\t\t\t<p className=\"mt-2 text-[14px] leading-relaxed text-[var(--fb-muted)]\">\n\t\t\t\t\tResume {count} upload{count === 1 ? '?' : 's?'}\n\t\t\t\t</p>\n\t\t\t\t<div className=\"mt-6 flex flex-wrap justify-end gap-2\">\n\t\t\t\t\t<button className={widgetTextButton()} onClick={onDismiss} type=\"button\">\n\t\t\t\t\t\tDismiss\n\t\t\t\t\t</button>\n\t\t\t\t\t<button className={widgetPrimaryButton()} onClick={onResume} type=\"button\">\n\t\t\t\t\t\tResume uploads\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</ResponsiveDialog>,\n\t\tdocument.body\n\t)\n}\n\nconst fallbackTransferManager = new TransferManager()\n\nfunction widgetIconButton() {\n\treturn `grid size-8 place-items-center rounded-[calc(var(--fb-radius)-2px)] border border-transparent bg-transparent text-[var(--fb-muted)] outline-none hover:bg-[var(--fb-surface-2)] hover:text-[var(--fb-text)] focus-visible:ring-[3px] focus-visible:ring-[color-mix(in_oklch,var(--fb-accent)_22%,transparent)] ${WIDGET_TOUCH_CONTROL} ${WIDGET_CONTROL_MOTION}`\n}\n\nfunction widgetTextButton() {\n\treturn `inline-flex h-9 items-center justify-center rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] px-3.5 text-[13px] font-semibold text-[var(--fb-text)] outline-none hover:bg-[var(--fb-surface-2)] focus-visible:ring-[3px] focus-visible:ring-[color-mix(in_oklch,var(--fb-accent)_22%,transparent)] ${WIDGET_TOUCH_CONTROL} ${WIDGET_CONTROL_MOTION}`\n}\n\nfunction widgetPrimaryButton() {\n\treturn `inline-flex h-9 items-center justify-center rounded-[var(--fb-radius)] border border-transparent bg-[var(--fb-accent)] px-3.5 text-[13px] font-semibold text-[var(--fb-surface)] outline-none hover:bg-[color-mix(in_oklch,var(--fb-accent)_88%,var(--fb-text))] focus-visible:ring-[3px] focus-visible:ring-[color-mix(in_oklch,var(--fb-accent)_22%,transparent)] ${WIDGET_TOUCH_CONTROL} ${WIDGET_CONTROL_MOTION}`\n}\n\nfunction isVisibleUpload(upload: UploadTransfer): boolean {\n\treturn ['queued', 'uploading', 'failed', 'paused'].includes(upload.status)\n}\n\nfunction getActiveUploadGroups(uploads: UploadTransfer[]): ActiveUploadGroup[] {\n\tconst groups = new Map<string, ActiveUploadGroup>()\n\n\tfor (const upload of uploads) {\n\t\tif (!upload.group) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst existing = groups.get(upload.group.id) ?? {\n\t\t\tgroup: upload.group,\n\t\t\tuploads: [],\n\t\t\tactiveUploads: [],\n\t\t\tcompletedCount: 0\n\t\t}\n\t\texisting.uploads.push(upload)\n\t\tif (upload.status === 'completed') {\n\t\t\texisting.completedCount += 1\n\t\t}\n\t\tif (isVisibleUpload(upload)) {\n\t\t\texisting.activeUploads.push(upload)\n\t\t}\n\t\tgroups.set(upload.group.id, existing)\n\t}\n\n\treturn Array.from(groups.values()).filter((group) => group.activeUploads.length > 0)\n}\n\nfunction formatUploadGroupSummary(group: ActiveUploadGroup): string {\n\tconst folders = group.group.createdFolders\n\tconst files = `${group.completedCount} of ${group.group.totalFiles} files`\n\tif (folders <= 0) {\n\t\treturn files\n\t}\n\n\treturn `${files}, ${folders} folder${folders === 1 ? '' : 's'} created`\n}\n\nfunction formatUploadStatus(upload: UploadTransfer): string {\n\tif (\n\t\tupload.status !== 'uploading' ||\n\t\ttypeof upload.bytesPerSecond !== 'number' ||\n\t\t!Number.isFinite(upload.bytesPerSecond) ||\n\t\tupload.bytesPerSecond <= 0\n\t) {\n\t\treturn upload.status\n\t}\n\n\treturn `${upload.status}, ${formatTransferBytes(upload.bytesPerSecond)}/s`\n}\n\nfunction formatTransferBytes(bytes: number): string {\n\tconst units = ['B', 'KB', 'MB', 'GB', 'TB']\n\tlet value = Math.max(0, bytes)\n\tlet unitIndex = 0\n\n\twhile (value >= 1024 && unitIndex < units.length - 1) {\n\t\tvalue /= 1024\n\t\tunitIndex += 1\n\t}\n\n\tconst formatted = unitIndex === 0 || value >= 10 ? Math.round(value).toString() : value.toFixed(1)\n\treturn `${formatted} ${units[unitIndex]}`\n}\n\nfunction formatDownloadReadyLabel(download: BulkDownloadJob): string {\n\tconst expiresIn = download.expiresAt ? formatExpiresIn(download.expiresAt) : undefined\n\n\treturn expiresIn ? `Download ready, expires in ${expiresIn}` : 'Download ready'\n}\n\nfunction formatExpiresIn(expiresAt: string): string | undefined {\n\tconst remainingMs = Date.parse(expiresAt) - Date.now()\n\tif (!Number.isFinite(remainingMs) || remainingMs <= 0) {\n\t\treturn undefined\n\t}\n\n\tif (remainingMs < 60 * 60 * 1000) {\n\t\treturn `${Math.ceil(remainingMs / (60 * 1000))}m`\n\t}\n\n\tif (remainingMs < 24 * 60 * 60 * 1000) {\n\t\treturn `${Math.ceil(remainingMs / (60 * 60 * 1000))}h`\n\t}\n\n\treturn `${Math.ceil(remainingMs / (24 * 60 * 60 * 1000))}d`\n}\n","import {\n\tCheck,\n\tCheckSquare,\n\tChevronDown,\n\tChevronLeft,\n\tChevronRight,\n\tCopy as CopyIcon,\n\tDownload,\n\tFolder,\n\tFolderInput,\n\tLayoutGrid,\n\tFolderPlus,\n\tArrowDown,\n\tArrowUp,\n\tLock,\n\tCircleAlert,\n\tInfo,\n\tList,\n\tMoreHorizontal,\n\tPencil,\n\tScissors,\n\tSearch,\n\tTrash2,\n\tUpload,\n\tX as XIcon\n} from 'lucide-react'\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport type { CSSProperties, DragEvent, KeyboardEvent, MouseEvent, ReactNode } from 'react'\nimport Selecto from 'react-selecto'\nimport type { OnSelect } from 'react-selecto'\nimport type { FileBrowserDensity } from '../theme'\nimport { useFileBrowser } from '../core/use-file-browser'\nimport type {\n\tFileBrowserListRow,\n\tFileBrowserPathChangeContext,\n\tFileBrowserUploadConflictResolution,\n\tFileBrowserView,\n\tUseFileBrowserResult\n} from '../core/use-file-browser'\nimport { getFileBrowserDirname, joinFileBrowserPath, normalizeFileBrowserPath } from '../core/path'\nimport { FileBrowserAdapterError, FileBrowserBulkActionError } from '../core/types'\nimport type { FileBrowserAdapter, FileNode } from '../core/types'\nimport { collectUploadCandidatesFromDataTransfer, getFileBrowserUploadCandidates } from '../core/upload-drop'\nimport type { FileBrowserUploadCandidate } from '../core/upload-drop'\nimport { useTransferSnapshot, useTransfers } from '../transfers/file-browser-provider'\nimport type { UploadTransferGroup } from '../transfers/transfer-manager'\nimport { ActionSheet, ResponsiveDialog, useBrowserLayout, useLongPress } from './responsive'\n\nexport type FileBrowserProps<TMetadata = unknown> = {\n\tadapter: FileBrowserAdapter<TMetadata>\n\tclassName?: string\n\temptyState?: {\n\t\ttitle: ReactNode\n\t\tdescription?: ReactNode\n\t}\n\t/** The view the browser opens in: `list` (default) or `grid`. */\n\tinitialView?: FileBrowserView\n\tinitialPath?: string\n\tpath?: string\n\tonPathChange?: (path: string, context: FileBrowserPathChangeContext<TMetadata>) => void\n\trootLabel?: string\n\tsearchQuery?: string\n\tinitialSearchQuery?: string\n\tonSearchQueryChange?: (query: string) => void\n\tdensity?: FileBrowserDensity\n\treadOnly?: boolean\n\tshowDetailsPanel?: boolean\n\tuploadPolicy?: FileBrowserUploadPolicy\n\tuploadConflictResolutions?: readonly FileBrowserUploadConflictResolution[]\n\tallowClientZipFallback?: boolean\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\trenderDetailsContent?: (item: FileNode<TMetadata>, defaultContent: ReactNode) => ReactNode\n\twarnZipSizeBytes?: number\n}\n\nexport type FileBrowserUploadPolicy = {\n\tallowedMimeTypes?: string[]\n\tmaxFilesPerBatch?: number\n\tmaxFileSizeBytes?: number\n\tremainingQuotaBytes?: number\n\tvalidate?: (\n\t\tcandidate: FileBrowserUploadCandidate,\n\t\tcontext: {\n\t\t\tacceptedBytes: number\n\t\t\tcurrentPath: string\n\t\t}\n\t) => string | string[] | null | undefined\n}\n\nexport type FileBrowserUploadRejection = {\n\tfileName: string\n\trelativePath: string\n\treasons: string[]\n}\n\ntype ContextMenuState<TMetadata = unknown> =\n\t| {\n\t\t\ttarget: 'item'\n\t\t\titem: FileNode<TMetadata>\n\t\t\tx: number\n\t\t\ty: number\n\t\t\tmode?: 'context' | 'sheet'\n\t }\n\t| {\n\t\t\ttarget: 'empty'\n\t\t\tx: number\n\t\t\ty: number\n\t\t\tmode?: 'context' | 'sheet'\n\t }\n\ntype UploadConflictQueue = {\n\tcandidates: FileBrowserUploadCandidate[]\n\tconflictPaths: string[]\n\tgroup?: UploadTransferGroup\n\tindex: number\n}\n\ntype MoveDestination = {\n\tpath: string\n\tname: string\n\tdepth: number\n}\n\ntype MoveDestinationStatus = 'idle' | 'loading' | 'ready' | 'error'\n\ntype PreviewState<TMetadata = unknown> = {\n\titem: FileNode<TMetadata>\n\tstatus: 'loading' | 'ready' | 'error'\n\turl?: string\n\terror?: string\n}\n\nconst FILE_BROWSER_DRAG_MIME = 'application/x.react-file-browser.paths'\nconst SELECTED_ITEM_DOUBLE_CLICK_WINDOW_MS = 220\nconst CLIPBOARD_NOTICE_DURATION_MS = 5000\nconst CONTROL_MOTION =\n\t'transition-[background-color,border-color,color,box-shadow,opacity] duration-150 ease-out motion-reduce:transition-none'\nconst TOUCH_CONTROL =\n\t'shrink-0 whitespace-nowrap [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:min-w-[calc(var(--fb-gap)*11)]'\nconst SURFACE_MOTION =\n\t'transition-[background-color,border-color,box-shadow,opacity] duration-200 ease-out motion-reduce:transition-none'\n// Accent-tinted text that stays legible on accent-soft fills in light and dark themes.\nconst ACCENT_INK = 'text-[color-mix(in_oklch,var(--fb-accent)_80%,var(--fb-text))]'\nconst DEFAULT_UPLOAD_CONFLICT_RESOLUTIONS = [\n\t'skip',\n\t'replace',\n\t'keep-both'\n] as const satisfies readonly FileBrowserUploadConflictResolution[]\n\n// Density drives layout scale through CSS variables set inline on the root, so the effect works for\n// every consumer without shipping global CSS. Classes below reference these vars (e.g. h-[var(--fb-control-h)]).\nconst DENSITY_STYLES: Record<FileBrowserDensity, CSSProperties> = {\n\tcomfortable: {\n\t\t'--fb-font': '14px',\n\t\t'--fb-font-sm': '12px',\n\t\t'--fb-control-h': '40px',\n\t\t'--fb-bar-control-h': '30px',\n\t\t'--fb-header-h': '64px',\n\t\t'--fb-bar-h': '48px',\n\t\t'--fb-row-h': '52px',\n\t\t'--fb-cell-x': '16px',\n\t\t'--fb-cell-y': '10px',\n\t\t'--fb-pad': '24px',\n\t\t'--fb-card-min': '140px',\n\t\t'--fb-card-minh': '150px',\n\t\t'--fb-card-pad': '10px',\n\t\t'--fb-thumb-h': '92px',\n\t\t'--fb-grid-gap': '14px',\n\t\t'--fb-panel-w': '280px',\n\t\t'--fb-panel-pad': '20px'\n\t} as CSSProperties,\n\tcompact: {\n\t\t'--fb-font': '13px',\n\t\t'--fb-font-sm': '11px',\n\t\t'--fb-control-h': '32px',\n\t\t'--fb-bar-control-h': '26px',\n\t\t'--fb-header-h': '52px',\n\t\t'--fb-bar-h': '40px',\n\t\t'--fb-row-h': '40px',\n\t\t'--fb-cell-x': '12px',\n\t\t'--fb-cell-y': '6px',\n\t\t'--fb-pad': '16px',\n\t\t'--fb-card-min': '120px',\n\t\t'--fb-card-minh': '120px',\n\t\t'--fb-card-pad': '8px',\n\t\t'--fb-thumb-h': '64px',\n\t\t'--fb-grid-gap': '10px',\n\t\t'--fb-panel-w': '240px',\n\t\t'--fb-panel-pad': '16px'\n\t} as CSSProperties\n}\n\nexport function FileBrowser<TMetadata = unknown>({\n\tadapter,\n\tclassName,\n\temptyState,\n\tinitialPath = '/',\n\tinitialView,\n\tpath,\n\tonPathChange,\n\trootLabel = 'Files',\n\tsearchQuery,\n\tinitialSearchQuery,\n\tonSearchQueryChange,\n\tdensity = 'comfortable',\n\treadOnly = false,\n\tshowDetailsPanel = true,\n\tuploadPolicy,\n\tuploadConflictResolutions,\n\tallowClientZipFallback = true,\n\trenderItemMeta,\n\trenderDetailsContent,\n\twarnZipSizeBytes\n}: FileBrowserProps<TMetadata>) {\n\tconst browser = useFileBrowser<TMetadata>({\n\t\tadapter,\n\t\tinitialPath,\n\t\tpath,\n\t\tonPathChange,\n\t\tsearchQuery,\n\t\tinitialSearchQuery,\n\t\tinitialView,\n\t\tonSearchQueryChange\n\t})\n\tconst transfers = useTransfers()\n\tconst transferSnapshot = useTransferSnapshot()\n\tconst [newFolderOpen, setNewFolderOpen] = useState(false)\n\tconst [newFolderName, setNewFolderName] = useState('')\n\tconst [newFolderError, setNewFolderError] = useState<string | null>(null)\n\tconst [renameItem, setRenameItem] = useState<FileNode<TMetadata> | null>(null)\n\tconst [renameValue, setRenameValue] = useState('')\n\tconst [renameError, setRenameError] = useState<string | null>(null)\n\tconst [inlineRenameItem, setInlineRenameItem] = useState<FileNode<TMetadata> | null>(null)\n\tconst [inlineRenameValue, setInlineRenameValue] = useState('')\n\tconst [inlineRenameError, setInlineRenameError] = useState<string | null>(null)\n\tconst [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false)\n\tconst [moveDialogOpen, setMoveDialogOpen] = useState(false)\n\tconst [bulkFailure, setBulkFailure] = useState<FileBrowserBulkActionError | null>(null)\n\tconst [moveDestination, setMoveDestination] = useState(path ?? initialPath)\n\tconst [moveDestinations, setMoveDestinations] = useState<MoveDestination[]>([])\n\tconst [moveDestinationStatus, setMoveDestinationStatus] = useState<MoveDestinationStatus>('idle')\n\tconst [moveDestinationError, setMoveDestinationError] = useState<string | null>(null)\n\tconst [contextMenu, setContextMenu] = useState<ContextMenuState<TMetadata> | null>(null)\n\tconst [uploadConflictQueue, setUploadConflictQueue] = useState<UploadConflictQueue | null>(null)\n\tconst [uploadRejections, setUploadRejections] = useState<FileBrowserUploadRejection[]>([])\n\tconst [applyUploadResolution, setApplyUploadResolution] = useState(false)\n\tconst [clipboardNotice, setClipboardNotice] = useState<string | null>(null)\n\tconst [dropActive, setDropActive] = useState(false)\n\tconst [folderDropTargetPath, setFolderDropTargetPath] = useState<string | null>(null)\n\tconst [preview, setPreview] = useState<PreviewState<TMetadata> | null>(null)\n\tconst rootRef = useRef<HTMLElement | null>(null)\n\tconst { isNarrow, hasSidebar } = useBrowserLayout(rootRef)\n\tconst [mobileSelectionPath, setMobileSelectionPath] = useState<string | null>(null)\n\tconst [toolbarOpen, setToolbarOpen] = useState(false)\n\tconst [detailsOpen, setDetailsOpen] = useState(false)\n\tconst [selectionActionsOpen, setSelectionActionsOpen] = useState(false)\n\tconst mobileSelection = isNarrow && mobileSelectionPath === browser.currentPath\n\tuseEffect(() => {\n\t\tsetMobileSelectionPath(null)\n\t\tsetSelectionActionsOpen(false)\n\t\tsetDetailsOpen(false)\n\t\tsetToolbarOpen(false)\n\t}, [browser.currentPath, isNarrow])\n\tconst uploadInputRef = useRef<HTMLInputElement | null>(null)\n\tconst draggedItemPathsRef = useRef<string[]>([])\n\tconst pendingSelectedItemUnselectRef = useRef<{\n\t\tpath: string\n\t\ttimeoutId: ReturnType<typeof setTimeout>\n\t} | null>(null)\n\tconst lastItemClickRef = useRef<{ path: string; timeMs: number } | null>(null)\n\tconst doubleClickOpenPathRef = useRef<string | null>(null)\n\tconst refreshedUploadIdsRef = useRef<Set<string>>(new Set())\n\tconst selected = browser.selectedItems.at(0) ?? null\n\tconst allowedUploadConflictResolutions = useMemo(\n\t\t() => normalizeUploadConflictResolutions(uploadConflictResolutions ?? DEFAULT_UPLOAD_CONFLICT_RESOLUTIONS),\n\t\t[uploadConflictResolutions]\n\t)\n\tconst supportsBulkDownload = browser.capabilities.bulkDownload || allowClientZipFallback\n\tconst canDownloadSelection = canDownloadItems(browser.selectedItems, supportsBulkDownload)\n\tconst previewFiles = useMemo(\n\t\t() => browser.visibleItems.filter((item) => item.kind === 'file'),\n\t\t[browser.visibleItems]\n\t)\n\tconst openPreview = useCallback(\n\t\tasync (item: FileNode<TMetadata>) => {\n\t\t\tsetPreview({ item, status: 'loading' })\n\t\t\ttry {\n\t\t\t\tconst url = await adapter.signedUrl(item.path)\n\t\t\t\tsetPreview((current) => (current?.item.path === item.path ? { item, status: 'ready', url } : current))\n\t\t\t} catch (error) {\n\t\t\t\tsetPreview((current) =>\n\t\t\t\t\tcurrent?.item.path === item.path ? { item, status: 'error', error: toErrorMessage(error) } : current\n\t\t\t\t)\n\t\t\t}\n\t\t},\n\t\t[adapter]\n\t)\n\tconst cancelPendingSelectedItemUnselect = useCallback(() => {\n\t\tif (!pendingSelectedItemUnselectRef.current) {\n\t\t\treturn\n\t\t}\n\n\t\tclearTimeout(pendingSelectedItemUnselectRef.current.timeoutId)\n\t\tpendingSelectedItemUnselectRef.current = null\n\t}, [])\n\tconst scheduleSelectedItemUnselect = useCallback(\n\t\t(path: string) => {\n\t\t\tcancelPendingSelectedItemUnselect()\n\t\t\tpendingSelectedItemUnselectRef.current = {\n\t\t\t\tpath,\n\t\t\t\ttimeoutId: setTimeout(() => {\n\t\t\t\t\tif (pendingSelectedItemUnselectRef.current?.path !== path) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tpendingSelectedItemUnselectRef.current = null\n\t\t\t\t\tbrowser.clearSelection()\n\t\t\t\t}, SELECTED_ITEM_DOUBLE_CLICK_WINDOW_MS)\n\t\t\t}\n\t\t},\n\t\t[browser, cancelPendingSelectedItemUnselect]\n\t)\n\tconst selectItemWithEvent = useCallback(\n\t\t(path: string, event: MouseEvent | KeyboardEvent) => {\n\t\t\tif (isNarrow) {\n\t\t\t\tif (mobileSelection) {\n\t\t\t\t\tbrowser.toggleSelection(path)\n\t\t\t\t} else {\n\t\t\t\t\tconst item = browser.visibleItems.find((candidate) => candidate.path === path)\n\t\t\t\t\tif (item?.kind === 'folder') void browser.open(item)\n\t\t\t\t\telse if (item) void openPreview(item)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst clickedAt = Date.now()\n\t\t\tconst previousClick = lastItemClickRef.current\n\t\t\tconst isFastRepeatClick =\n\t\t\t\tpreviousClick?.path === path && clickedAt - previousClick.timeMs <= SELECTED_ITEM_DOUBLE_CLICK_WINDOW_MS\n\n\t\t\tif ('detail' in event && event.detail > 1) {\n\t\t\t\tif (isFastRepeatClick) {\n\t\t\t\t\tcancelPendingSelectedItemUnselect()\n\t\t\t\t\tdoubleClickOpenPathRef.current = path\n\t\t\t\t}\n\t\t\t\tlastItemClickRef.current = { path, timeMs: clickedAt }\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdoubleClickOpenPathRef.current = null\n\t\t\tlastItemClickRef.current = { path, timeMs: clickedAt }\n\t\t\tselectWithEvent(browser, path, event, {\n\t\t\t\tcancelPendingSelectedItemUnselect,\n\t\t\t\tscheduleSelectedItemUnselect\n\t\t\t})\n\t\t},\n\t\t[browser, cancelPendingSelectedItemUnselect, isNarrow, mobileSelection, openPreview, scheduleSelectedItemUnselect]\n\t)\n\tconst openItemFromDoubleClick = useCallback(\n\t\t(item: FileNode<TMetadata>) => {\n\t\t\tif (isNarrow) return\n\t\t\tif (doubleClickOpenPathRef.current !== item.path) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdoubleClickOpenPathRef.current = null\n\t\t\tcancelPendingSelectedItemUnselect()\n\t\t\tif (item.kind === 'folder') {\n\t\t\t\tvoid browser.open(item)\n\t\t\t} else {\n\t\t\t\tvoid openPreview(item)\n\t\t\t}\n\t\t},\n\t\t[browser, cancelPendingSelectedItemUnselect, isNarrow, openPreview]\n\t)\n\tuseEffect(\n\t\t() => () => {\n\t\t\tcancelPendingSelectedItemUnselect()\n\t\t},\n\t\t[cancelPendingSelectedItemUnselect]\n\t)\n\tconst totalSelectedBytes = useMemo(\n\t\t() => browser.selectedItems.reduce((total, item) => total + (item.size ?? 0), 0),\n\t\t[browser.selectedItems]\n\t)\n\tconst moveKeyboardSelection = useCallback(\n\t\t(key: string, extendSelection: boolean) => {\n\t\t\tconst visibleItems = browser.visibleItems\n\t\t\tif (visibleItems.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst currentPath = browser.focusedPath ?? browser.selectedPaths.at(-1)\n\t\t\tconst currentIndex = visibleItems.findIndex((item) => item.path === currentPath)\n\t\t\tconst currentRow = browser.listRows.find((row) => row.type === 'item' && row.item.path === currentPath)\n\t\t\t// List view follows OS outline conventions: Right expands a folder, Left collapses it or jumps to its parent.\n\t\t\tif (browser.view === 'list' && !extendSelection && currentRow?.type === 'item') {\n\t\t\t\tif (key === 'ArrowRight' && currentRow.item.kind === 'folder' && !currentRow.expanded) {\n\t\t\t\t\tbrowser.expandFolder(currentRow.item.path)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (key === 'ArrowLeft' && currentRow.expanded) {\n\t\t\t\t\tbrowser.collapseFolder(currentRow.item.path)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (key === 'ArrowLeft' && currentRow.depth > 0) {\n\t\t\t\t\tbrowser.selectOnly(getFileBrowserDirname(currentRow.item.path))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst fallbackIndex = key === 'ArrowUp' || key === 'ArrowLeft' || key === 'End' ? visibleItems.length - 1 : 0\n\t\t\tconst nextIndex =\n\t\t\t\tcurrentIndex === -1 ? fallbackIndex : getNextKeyboardIndex(key, currentIndex, visibleItems.length)\n\t\t\tconst next = visibleItems[nextIndex]\n\n\t\t\tif (extendSelection) {\n\t\t\t\tbrowser.selectRange(next.path)\n\t\t\t} else {\n\t\t\t\tbrowser.selectOnly(next.path)\n\t\t\t}\n\t\t},\n\t\t[browser]\n\t)\n\tconst copySelectedItems = useCallback(\n\t\t(paths = browser.selectedPaths) => {\n\t\t\tif (paths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbrowser.copySelection(paths)\n\t\t\tsetClipboardNotice(`Copied ${formatItemCount(paths.length)}`)\n\t\t},\n\t\t[browser]\n\t)\n\tconst cutSelectedItems = useCallback(\n\t\t(paths = browser.selectedPaths) => {\n\t\t\tif (paths.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbrowser.cutSelection(paths)\n\t\t\tsetClipboardNotice(`Cut ${formatItemCount(paths.length)}`)\n\t\t},\n\t\t[browser]\n\t)\n\tconst copyItemPaths = useCallback(async (paths: string[]) => {\n\t\tif (paths.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tawait navigator.clipboard.writeText(paths.join(', '))\n\t\tsetClipboardNotice(paths.length === 1 ? 'Copied path' : `Copied ${paths.length} paths`)\n\t}, [])\n\tconst pasteClipboardInto = useCallback(\n\t\tasync (toDir: string) => {\n\t\t\tconst pastedCount = browser.clipboard?.paths.length ?? 0\n\t\t\tawait browser.pasteInto(toDir)\n\t\t\tif (pastedCount > 0) {\n\t\t\t\tsetClipboardNotice(`Pasted ${formatItemCount(pastedCount)}`)\n\t\t\t}\n\t\t},\n\t\t[browser]\n\t)\n\n\tuseEffect(() => {\n\t\tconst listener = (event: globalThis.KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\tevent.defaultPrevented ||\n\t\t\t\t(event.target instanceof Element && event.target.closest('[role=\"dialog\"], [role=\"menu\"]'))\n\t\t\t)\n\t\t\t\treturn\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tbrowser.clearSelection()\n\t\t\t\tsetMobileSelectionPath(null)\n\t\t\t\tsetToolbarOpen(false)\n\t\t\t\tsetDetailsOpen(false)\n\t\t\t\tsetSelectionActionsOpen(false)\n\t\t\t\tsetInlineRenameItem(null)\n\t\t\t\tsetInlineRenameValue('')\n\t\t\t\tsetInlineRenameError(null)\n\t\t\t\tsetRenameItem(null)\n\t\t\t\tsetRenameError(null)\n\t\t\t\tsetNewFolderError(null)\n\t\t\t\tsetDeleteConfirmOpen(false)\n\t\t\t\tsetMoveDialogOpen(false)\n\t\t\t\tsetBulkFailure(null)\n\t\t\t\tsetContextMenu(null)\n\t\t\t\tsetUploadConflictQueue(null)\n\t\t\t\tsetPreview(null)\n\t\t\t}\n\t\t\tif (\n\t\t\t\tisEditableEventTarget(event.target) ||\n\t\t\t\t(event.target instanceof Element &&\n\t\t\t\t\t(event.target.closest('[data-fb-touch-control]') ||\n\t\t\t\t\t\t(event.key === 'Enter' && event.target.closest('button, a') && !event.target.closest('[data-fb-path]'))))\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (event.key === 'Enter' && isNarrow && mobileSelection) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tconst path =\n\t\t\t\t\tevent.target instanceof Element ? event.target.closest('[data-fb-path]')?.getAttribute('data-fb-path') : null\n\t\t\t\tif (path) browser.toggleSelection(path)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (isKeyboardNavigationKey(event.key)) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tmoveKeyboardSelection(event.key, event.shiftKey)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!readOnly && event.key === 'F2' && browser.capabilities.rename && browser.selectedItems.length === 1) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tconst item = browser.selectedItems[0]\n\t\t\t\tsetRenameItem(null)\n\t\t\t\tsetRenameError(null)\n\t\t\t\tsetInlineRenameItem(item)\n\t\t\t\tsetInlineRenameValue(item.name)\n\t\t\t\tsetInlineRenameError(null)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!readOnly && (event.key === 'Delete' || event.key === 'Backspace') && browser.selectedPaths.length > 0) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetDeleteConfirmOpen(true)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif ((event.metaKey || event.ctrlKey) && !readOnly) {\n\t\t\t\tconst key = event.key.toLowerCase()\n\t\t\t\tif (key === 'c' && browser.capabilities.copy && browser.selectedPaths.length > 0) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tcopySelectedItems()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (key === 'x' && browser.capabilities.move && browser.selectedPaths.length > 0) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tcutSelectedItems()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (key === 'v' && browser.clipboard) {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tvoid pasteClipboardInto(browser.currentPath)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (event.key === 'Enter' && browser.selectedItems.length === 1) {\n\t\t\t\tconst item = browser.selectedItems[0]\n\t\t\t\tif (item.kind === 'folder') {\n\t\t\t\t\tvoid browser.open(item)\n\t\t\t\t} else {\n\t\t\t\t\tvoid openPreview(item)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'a') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tbrowser.selectAllLoaded()\n\t\t\t}\n\t\t}\n\t\tdocument.addEventListener('keydown', listener)\n\t\treturn () => document.removeEventListener('keydown', listener)\n\t}, [\n\t\tbrowser,\n\t\tcopySelectedItems,\n\t\tcutSelectedItems,\n\t\tisNarrow,\n\t\tmobileSelection,\n\t\tmoveKeyboardSelection,\n\t\topenPreview,\n\t\tpasteClipboardInto,\n\t\treadOnly\n\t])\n\n\tuseEffect(() => {\n\t\tif (!browser.focusedPath || rootRef.current?.querySelector('[role=\"dialog\"], [role=\"menu\"]')) {\n\t\t\treturn\n\t\t}\n\n\t\tconst item = rootRef.current?.querySelector<HTMLElement>(\n\t\t\t`[data-fb-path=\"${escapeAttributeSelector(browser.focusedPath)}\"]`\n\t\t)\n\t\titem?.focus()\n\t}, [browser.focusedPath, browser.visibleItems, browser.view])\n\n\tuseEffect(() => {\n\t\tif (!contextMenu) {\n\t\t\treturn\n\t\t}\n\t\tconst close = () => setContextMenu(null)\n\t\tdocument.addEventListener('click', close)\n\t\treturn () => document.removeEventListener('click', close)\n\t}, [contextMenu])\n\n\tuseEffect(() => {\n\t\tif (!clipboardNotice) {\n\t\t\treturn\n\t\t}\n\t\tconst timer = setTimeout(() => setClipboardNotice(null), CLIPBOARD_NOTICE_DURATION_MS)\n\t\treturn () => clearTimeout(timer)\n\t}, [clipboardNotice])\n\n\tuseEffect(() => {\n\t\tfor (const upload of transferSnapshot.uploads) {\n\t\t\tif (upload.status !== 'completed' || !upload.result || refreshedUploadIdsRef.current.has(upload.id)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\trefreshedUploadIdsRef.current.add(upload.id)\n\t\t\tif (getFileBrowserDirname(upload.result.path) === browser.currentPath) {\n\t\t\t\tvoid browser.refresh()\n\t\t\t}\n\t\t}\n\t}, [browser, transferSnapshot.uploads])\n\n\tuseEffect(() => {\n\t\tif (!moveDialogOpen) {\n\t\t\treturn\n\t\t}\n\n\t\tlet cancelled = false\n\n\t\tvoid Promise.resolve()\n\t\t\t.then(async () => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tsetMoveDestinationStatus('loading')\n\t\t\t\tsetMoveDestinationError(null)\n\t\t\t\treturn collectMoveDestinations(adapter, browser.selectedPaths)\n\t\t\t})\n\t\t\t.then((destinations) => {\n\t\t\t\tif (cancelled || destinations.length === 0) {\n\t\t\t\t\tif (!cancelled && destinations.length === 0) {\n\t\t\t\t\t\tsetMoveDestinations([])\n\t\t\t\t\t\tsetMoveDestinationStatus('ready')\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetMoveDestinations(destinations)\n\t\t\t\tsetMoveDestinationStatus('ready')\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetMoveDestinations([])\n\t\t\t\tsetMoveDestinationStatus('error')\n\t\t\t\tsetMoveDestinationError(toErrorMessage(error))\n\t\t\t})\n\n\t\treturn () => {\n\t\t\tcancelled = true\n\t\t}\n\t}, [adapter, browser.selectedPaths, moveDialogOpen])\n\n\tasync function createFolder() {\n\t\tif (!newFolderName.trim()) {\n\t\t\treturn\n\t\t}\n\t\tsetNewFolderError(null)\n\t\ttry {\n\t\t\tawait browser.createFolder(newFolderName)\n\t\t\tsetNewFolderName('')\n\t\t\tsetNewFolderOpen(false)\n\t\t} catch (error) {\n\t\t\tsetNewFolderError(toErrorMessage(error))\n\t\t}\n\t}\n\n\tfunction openRenameDialog(item = browser.selectedItems.at(0)) {\n\t\tif (!item) {\n\t\t\treturn\n\t\t}\n\t\tsetInlineRenameItem(null)\n\t\tsetInlineRenameValue('')\n\t\tsetInlineRenameError(null)\n\t\tsetRenameItem(item)\n\t\tsetRenameValue(item.name)\n\t\tsetRenameError(null)\n\t}\n\n\tasync function renameSelectedItem() {\n\t\tconst nextName = renameValue.trim()\n\t\tif (!renameItem || !nextName) {\n\t\t\treturn\n\t\t}\n\t\tsetRenameError(null)\n\t\ttry {\n\t\t\tawait browser.rename(renameItem.path, nextName)\n\t\t\tsetRenameItem(null)\n\t\t\tsetRenameValue('')\n\t\t} catch (error) {\n\t\t\tsetRenameError(toErrorMessage(error))\n\t\t}\n\t}\n\n\tasync function commitInlineRename() {\n\t\tconst item = inlineRenameItem\n\t\tconst nextName = inlineRenameValue.trim()\n\t\tsetInlineRenameError(null)\n\t\tif (!item || !nextName || nextName === item.name) {\n\t\t\tsetInlineRenameItem(null)\n\t\t\tsetInlineRenameValue('')\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tawait browser.rename(item.path, nextName)\n\t\t\tsetInlineRenameItem(null)\n\t\t\tsetInlineRenameValue('')\n\t\t} catch (error) {\n\t\t\tsetInlineRenameItem(item)\n\t\t\tsetInlineRenameValue(nextName)\n\t\t\tsetInlineRenameError(toErrorMessage(error))\n\t\t}\n\t}\n\n\tfunction cancelInlineRename() {\n\t\tsetInlineRenameItem(null)\n\t\tsetInlineRenameValue('')\n\t\tsetInlineRenameError(null)\n\t}\n\n\tasync function deleteSelectedItems() {\n\t\tsetDeleteConfirmOpen(false)\n\t\ttry {\n\t\t\tawait browser.deleteSelected()\n\t\t} catch (error) {\n\t\t\tif (error instanceof FileBrowserBulkActionError) {\n\t\t\t\tsetBulkFailure(error)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetDeleteConfirmOpen(true)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tfunction openMoveDialog() {\n\t\tif (browser.selectedPaths.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tsetMoveDestination(browser.currentPath)\n\t\tsetMoveDialogOpen(true)\n\t}\n\n\tasync function moveSelectedItems() {\n\t\ttry {\n\t\t\tawait browser.moveSelectedTo(moveDestination)\n\t\t\tsetMoveDialogOpen(false)\n\t\t} catch (error) {\n\t\t\tif (error instanceof FileBrowserBulkActionError) {\n\t\t\t\tsetMoveDialogOpen(false)\n\t\t\t\tsetBulkFailure(error)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tfunction startItemDrag(item: FileNode<TMetadata>, event: DragEvent) {\n\t\tif (readOnly || !browser.capabilities.move) {\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = browser.selectedPaths.includes(item.path) ? browser.selectedPaths : [item.path]\n\t\tdraggedItemPathsRef.current = paths\n\t\tsetDropActive(false)\n\t\tsetFolderDropTargetPath(null)\n\t\tbrowser.setSelection(paths)\n\t\tevent.dataTransfer.effectAllowed = 'move'\n\t\tevent.dataTransfer.setData(FILE_BROWSER_DRAG_MIME, JSON.stringify(paths))\n\t}\n\n\tfunction endItemDrag() {\n\t\tdraggedItemPathsRef.current = []\n\t\tsetDropActive(false)\n\t\tsetFolderDropTargetPath(null)\n\t}\n\n\tfunction getActiveDraggedPaths(dataTransfer: DataTransfer) {\n\t\tconst transferredPaths = getDraggedPaths(dataTransfer)\n\t\treturn transferredPaths.length > 0 ? transferredPaths : draggedItemPathsRef.current\n\t}\n\n\tfunction allowFolderDrop(item: FileNode<TMetadata>, event: DragEvent) {\n\t\tif (readOnly || !browser.capabilities.move || item.kind !== 'folder') {\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = getActiveDraggedPaths(event.dataTransfer)\n\t\tif (\n\t\t\tpaths.length === 0 ||\n\t\t\tpaths.some((path) => item.path === path || item.path.startsWith(`${path}/`)) ||\n\t\t\tpaths.every((path) => getFileBrowserDirname(path) === item.path)\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tevent.dataTransfer.dropEffect = 'move'\n\t\tsetDropActive(false)\n\t\tsetFolderDropTargetPath(item.path)\n\t}\n\n\tasync function moveDraggedItemsToFolder(item: FileNode<TMetadata>, event: DragEvent) {\n\t\tif (readOnly || !browser.capabilities.move || item.kind !== 'folder') {\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = getActiveDraggedPaths(event.dataTransfer)\n\t\tif (paths.every((path) => getFileBrowserDirname(path) === item.path)) {\n\t\t\treturn\n\t\t}\n\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tendItemDrag()\n\t\ttry {\n\t\t\tawait browser.movePathsTo(paths, item.path)\n\t\t} catch (error) {\n\t\t\tif (error instanceof FileBrowserBulkActionError) {\n\t\t\t\tsetBulkFailure(error)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tfunction openItemContextMenu(item: FileNode<TMetadata>, event: MouseEvent) {\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tif (!browser.selectedPaths.includes(item.path)) {\n\t\t\tbrowser.selectOnly(item.path)\n\t\t}\n\t\tsetContextMenu({\n\t\t\ttarget: 'item',\n\t\t\titem,\n\t\t\tx: event.clientX,\n\t\t\ty: event.clientY,\n\t\t\tmode: isNarrow ? 'sheet' : 'context'\n\t\t})\n\t}\n\n\tfunction openItemTouchMenu(item: FileNode<TMetadata>) {\n\t\tif (!browser.selectedPaths.includes(item.path)) {\n\t\t\tbrowser.selectOnly(item.path)\n\t\t}\n\t\tif (isNarrow) {\n\t\t\tsetMobileSelectionPath(browser.currentPath)\n\t\t\treturn\n\t\t}\n\t\tsetContextMenu({\n\t\t\ttarget: 'item',\n\t\t\titem,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tmode: 'sheet'\n\t\t})\n\t}\n\n\tfunction openEmptyContextMenu(event: MouseEvent) {\n\t\tevent.preventDefault()\n\t\tbrowser.clearSelection()\n\t\tsetContextMenu({\n\t\t\ttarget: 'empty',\n\t\t\tx: event.clientX,\n\t\t\ty: event.clientY,\n\t\t\tmode: isNarrow ? 'sheet' : 'context'\n\t\t})\n\t}\n\n\tfunction clearSelectionFromEmptySurface(event: MouseEvent<HTMLElement>) {\n\t\tif (mobileSelection) return\n\t\tif (event.target !== event.currentTarget || hasSelectionModifier(event)) {\n\t\t\treturn\n\t\t}\n\t\tbrowser.clearSelection()\n\t}\n\n\tfunction showAdjacentPreview(direction: -1 | 1) {\n\t\tif (!preview || previewFiles.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst currentIndex = previewFiles.findIndex((item) => item.path === preview.item.path)\n\t\tconst safeIndex = currentIndex >= 0 ? currentIndex : 0\n\t\tconst nextIndex = (safeIndex + direction + previewFiles.length) % previewFiles.length\n\t\tconst next = previewFiles[nextIndex]\n\t\tvoid openPreview(next)\n\t\tbrowser.selectOnly(next.path)\n\t}\n\n\tasync function downloadSelection() {\n\t\tif (!canDownloadSelection) {\n\t\t\treturn\n\t\t}\n\n\t\tif (browser.selectedItems.length === 1 && browser.selectedItems[0].kind === 'file') {\n\t\t\tawait downloadItem(browser.selectedItems[0])\n\t\t\treturn\n\t\t}\n\n\t\tconst paths = browser.selectedPaths\n\t\tawait downloadPaths(paths, totalSelectedBytes)\n\t}\n\n\tasync function downloadItem(item: FileNode<TMetadata>) {\n\t\tif (item.kind === 'file') {\n\t\t\tawait transfers.prepareSingleDownload({\n\t\t\t\tadapter,\n\t\t\t\tpath: item.path,\n\t\t\t\tselectedBytes: item.size ?? 0\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tif (supportsBulkDownload) {\n\t\t\tawait downloadPaths([item.path], item.size ?? 0)\n\t\t}\n\t}\n\n\tasync function downloadPaths(paths: string[], selectedBytes: number) {\n\t\tif (paths.length === 0 || !supportsBulkDownload) {\n\t\t\treturn\n\t\t}\n\n\t\tawait transfers.prepareBulkDownload({\n\t\t\tallowClientZipFallback,\n\t\t\tadapter,\n\t\t\tpaths,\n\t\t\tselectedBytes,\n\t\t\twarnZipSizeBytes\n\t\t})\n\t}\n\n\tasync function uploadInputFiles(files: FileList | null) {\n\t\tif (!files || files.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tawait beginUploadFiles(files)\n\t\tif (uploadInputRef.current) {\n\t\t\tuploadInputRef.current.value = ''\n\t\t}\n\t}\n\n\tasync function beginUploadFiles(files: File[] | FileList) {\n\t\tconst candidates = getFileBrowserUploadCandidates(files)\n\t\tawait beginUploadCandidates(candidates)\n\t}\n\n\tasync function beginUploadDrop(dataTransfer: DataTransfer) {\n\t\tconst candidates = await collectUploadCandidatesFromDataTransfer(dataTransfer)\n\t\tawait beginUploadCandidates(candidates)\n\t}\n\n\tasync function beginUploadCandidates(candidates: FileBrowserUploadCandidate[]) {\n\t\tif (candidates.length === 0) {\n\t\t\treturn\n\t\t}\n\t\tif (uploadPolicy?.maxFilesPerBatch !== undefined && candidates.length > uploadPolicy.maxFilesPerBatch) {\n\t\t\tsetUploadRejections(\n\t\t\t\tcandidates.map((candidate) => ({\n\t\t\t\t\tfileName: candidate.file.name,\n\t\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\t\treasons: [`Batch contains ${candidates.length} files; maximum is ${uploadPolicy.maxFilesPerBatch}`]\n\t\t\t\t}))\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\tconst { acceptedCandidates, rejectedCandidates } = applyUploadPolicy(candidates, uploadPolicy, browser.currentPath)\n\t\tif (rejectedCandidates.length > 0) {\n\t\t\tsetUploadRejections(rejectedCandidates)\n\t\t}\n\t\tif (acceptedCandidates.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst supportedCandidates = rejectUnsupportedFolderUploads(acceptedCandidates)\n\t\tif (supportedCandidates.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst createdFolders = await ensureUploadFolders(supportedCandidates)\n\t\tconst conflictPaths = await findUploadConflictPaths(supportedCandidates)\n\t\tif (conflictPaths.length > 0 && allowedUploadConflictResolutions.length === 0) {\n\t\t\tconst conflicts = new Set(conflictPaths)\n\t\t\tconst nonConflictingCandidates = supportedCandidates.filter(\n\t\t\t\t(candidate) => !conflicts.has(joinUploadRelativePath(browser.currentPath, candidate.relativePath))\n\t\t\t)\n\t\t\tconst conflictingCandidates = supportedCandidates.filter((candidate) =>\n\t\t\t\tconflicts.has(joinUploadRelativePath(browser.currentPath, candidate.relativePath))\n\t\t\t)\n\t\t\tsetUploadRejections((current) => [\n\t\t\t\t...current,\n\t\t\t\t...conflictingCandidates.map((candidate) => ({\n\t\t\t\t\tfileName: candidate.file.name,\n\t\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\t\treasons: ['No upload conflict resolutions are enabled']\n\t\t\t\t}))\n\t\t\t])\n\t\t\tif (nonConflictingCandidates.length > 0) {\n\t\t\t\tconst group = getUploadTransferGroup(browser.currentPath, nonConflictingCandidates, createdFolders)\n\t\t\t\tprocessUploadQueue(nonConflictingCandidates, [], 0, undefined, group)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst group = getUploadTransferGroup(browser.currentPath, supportedCandidates, createdFolders)\n\t\tprocessUploadQueue(supportedCandidates, conflictPaths, 0, undefined, group)\n\t}\n\n\tfunction rejectUnsupportedFolderUploads(candidates: FileBrowserUploadCandidate[]) {\n\t\tif (browser.capabilities.createFolder) {\n\t\t\treturn candidates\n\t\t}\n\n\t\tconst [folderCandidates, flatCandidates] = partitionUploadCandidates(candidates, (candidate) =>\n\t\t\tcandidate.relativePath.includes('/')\n\t\t)\n\t\tif (folderCandidates.length > 0) {\n\t\t\tsetUploadRejections((current) => [\n\t\t\t\t...current,\n\t\t\t\t...folderCandidates.map((candidate) => ({\n\t\t\t\t\tfileName: candidate.file.name,\n\t\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\t\treasons: ['Folder uploads require folder creation support']\n\t\t\t\t}))\n\t\t\t])\n\t\t}\n\t\treturn flatCandidates\n\t}\n\n\tasync function ensureUploadFolders(candidates: FileBrowserUploadCandidate[]) {\n\t\tconst folders = getUploadFolderPaths(candidates)\n\t\tlet createdFolders = 0\n\n\t\tif (!adapter.createFolder) {\n\t\t\tif (folders.length > 0) {\n\t\t\t\tthrow new FileBrowserAdapterError('not_supported', 'Folder uploads require folder creation support')\n\t\t\t}\n\t\t\treturn 0\n\t\t}\n\n\t\tfor (const folder of folders) {\n\t\t\ttry {\n\t\t\t\tawait adapter.createFolder(joinUploadRelativePath(browser.currentPath, folder))\n\t\t\t\tcreatedFolders += 1\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof FileBrowserAdapterError && error.code === 'conflict') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\n\t\tif (createdFolders > 0) {\n\t\t\tawait browser.refresh()\n\t\t}\n\t\treturn createdFolders\n\t}\n\n\tasync function findUploadConflictPaths(candidates: FileBrowserUploadCandidate[]) {\n\t\tconst paths = candidates.map((candidate) => joinUploadRelativePath(browser.currentPath, candidate.relativePath))\n\n\t\tif (adapter.exists) {\n\t\t\ttry {\n\t\t\t\tconst result = await adapter.exists(paths)\n\t\t\t\treturn paths.filter((path) => result[path])\n\t\t\t} catch {\n\t\t\t\t// Fall back to list lookups below.\n\t\t\t}\n\t\t}\n\n\t\tconst existingPaths = new Set(browser.items.map((item) => item.path))\n\t\tconst conflicts: string[] = []\n\t\tfor (const path of paths) {\n\t\t\tif (existingPaths.has(path) || (await uploadPathExistsByListing(path))) {\n\t\t\t\tconflicts.push(path)\n\t\t\t}\n\t\t}\n\t\treturn conflicts\n\t}\n\n\tasync function uploadPathExistsByListing(path: string): Promise<boolean> {\n\t\tconst parentPath = getFileBrowserDirname(path)\n\t\tlet cursor: string | undefined\n\n\t\tdo {\n\t\t\tconst result = await adapter.list(parentPath, { cursor })\n\t\t\tif (result.items.some((item) => item.path === path)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcursor = result.cursor\n\t\t} while (cursor)\n\n\t\treturn false\n\t}\n\n\tfunction processUploadQueue(\n\t\tcandidates: FileBrowserUploadCandidate[],\n\t\tconflictPaths: string[],\n\t\tstartIndex: number,\n\t\tresolution?: FileBrowserUploadConflictResolution,\n\t\tgroup?: UploadTransferGroup\n\t) {\n\t\tconst conflicts = new Set(conflictPaths)\n\n\t\tfor (let index = startIndex; index < candidates.length; index += 1) {\n\t\t\tconst candidate = candidates[index]\n\t\t\tconst path = joinUploadRelativePath(browser.currentPath, candidate.relativePath)\n\n\t\t\tif (conflicts.has(path)) {\n\t\t\t\tif (!resolution) {\n\t\t\t\t\tsetUploadConflictQueue({ candidates, conflictPaths, group, index })\n\t\t\t\t\tsetApplyUploadResolution(false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (resolution !== 'skip') {\n\t\t\t\t\tenqueueUploadTransfer(candidate, resolution, group)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tenqueueUploadTransfer(candidate, undefined, group)\n\t\t\t}\n\t\t}\n\n\t\tsetUploadConflictQueue(null)\n\t\tsetApplyUploadResolution(false)\n\t}\n\n\tfunction resolveUploadConflict(resolution: FileBrowserUploadConflictResolution) {\n\t\tif (!uploadConflictQueue || !allowedUploadConflictResolutions.includes(resolution)) {\n\t\t\treturn\n\t\t}\n\n\t\tconst { candidates, conflictPaths, group, index } = uploadConflictQueue\n\t\tif (applyUploadResolution) {\n\t\t\tprocessUploadQueue(candidates, conflictPaths, index, resolution, group)\n\t\t\treturn\n\t\t}\n\n\t\tconst candidate = candidates[index]\n\t\tif (resolution !== 'skip') {\n\t\t\tenqueueUploadTransfer(candidate, resolution, group)\n\t\t}\n\t\tprocessUploadQueue(candidates, conflictPaths, index + 1, undefined, group)\n\t}\n\n\tfunction enqueueUploadTransfer(\n\t\tcandidate: FileBrowserUploadCandidate,\n\t\tresolution?: FileBrowserUploadConflictResolution,\n\t\tgroup?: UploadTransferGroup\n\t) {\n\t\ttransfers.enqueueUpload({\n\t\t\tadapter,\n\t\t\tdestinationPath: joinUploadRelativePath(browser.currentPath, candidate.relativePath),\n\t\t\tfile: candidate.file,\n\t\t\tgroup,\n\t\t\tonConflict: resolution === 'skip' ? undefined : resolution\n\t\t})\n\t}\n\n\tfunction exitMobileSelection() {\n\t\tbrowser.clearSelection()\n\t\tsetMobileSelectionPath(null)\n\t\tsetSelectionActionsOpen(false)\n\t}\n\n\tconst previewPosition = preview ? previewFiles.findIndex((item) => item.path === preview.item.path) + 1 : 0\n\tconst previewNavButton = `grid size-12 shrink-0 place-items-center rounded-full border border-[var(--fb-border)] bg-[var(--fb-surface)] text-[var(--fb-text)] hover:bg-[var(--fb-surface-2)] disabled:opacity-40 ${FOCUS_RING} ${CONTROL_MOTION}`\n\n\tconst clipboardStatus = clipboardNotice ? (\n\t\t<span\n\t\t\taria-label=\"Clipboard status\"\n\t\t\tclassName={`shrink-0 whitespace-nowrap rounded-full bg-[var(--fb-accent-soft)] px-3 py-1 text-[var(--fb-font-sm)] font-semibold ${ACCENT_INK} ${CONTROL_MOTION}`}\n\t\t\trole=\"status\"\n\t\t>\n\t\t\t{clipboardNotice}\n\t\t</span>\n\t) : null\n\n\tconst secondaryControls = (\n\t\t<div className=\"flex min-w-0 flex-wrap items-center gap-3\">\n\t\t\t<SelectField\n\t\t\t\taria-label=\"Filter files\"\n\t\t\t\tonChange={(event) => browser.setFilterKind(event.target.value as 'all' | 'files' | 'folders')}\n\t\t\t\tvalue={browser.filterKind}\n\t\t\t>\n\t\t\t\t<option value=\"all\">All</option>\n\t\t\t\t<option value=\"folders\">Folders</option>\n\t\t\t\t<option value=\"files\">Files</option>\n\t\t\t</SelectField>\n\t\t\t<SelectField\n\t\t\t\taria-label=\"Sort files\"\n\t\t\t\tonChange={(event) => browser.setSortBy(event.target.value as 'name' | 'modifiedAt' | 'size')}\n\t\t\t\tvalue={browser.sortBy}\n\t\t\t>\n\t\t\t\t<option value=\"name\">Name</option>\n\t\t\t\t<option value=\"modifiedAt\">Modified</option>\n\t\t\t\t<option value=\"size\">Size</option>\n\t\t\t</SelectField>\n\t\t\t<button\n\t\t\t\taria-label=\"Toggle sort direction\"\n\t\t\t\tclassName={toolButton(false)}\n\t\t\t\tonClick={() => browser.setSortDirection((current) => (current === 'asc' ? 'desc' : 'asc'))}\n\t\t\t\ttype=\"button\"\n\t\t\t>\n\t\t\t\t{browser.sortDirection === 'asc' ? (\n\t\t\t\t\t<ArrowUp aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t) : (\n\t\t\t\t\t<ArrowDown aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t)}\n\t\t\t</button>\n\t\t\t<div className=\"flex shrink-0 overflow-hidden rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)]\">\n\t\t\t\t<button\n\t\t\t\t\taria-label=\"Grid view\"\n\t\t\t\t\taria-pressed={browser.view === 'grid'}\n\t\t\t\t\tclassName={segmentButton(browser.view === 'grid')}\n\t\t\t\t\tonClick={() => browser.setView('grid')}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<LayoutGrid aria-hidden=\"true\" className=\"size-4\" strokeWidth={2} />\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\taria-label=\"List view\"\n\t\t\t\t\taria-pressed={browser.view === 'list'}\n\t\t\t\t\tclassName={segmentButton(browser.view === 'list')}\n\t\t\t\t\tonClick={() => browser.setView('list')}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<List aria-hidden=\"true\" className=\"size-4\" strokeWidth={2} />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t{!readOnly && browser.capabilities.createFolder ? (\n\t\t\t\t<button\n\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetToolbarOpen(false)\n\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\tsetNewFolderOpen(true)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<FolderPlus aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\tNew folder\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{isNarrow ? (\n\t\t\t\t<button\n\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\tdisabled={browser.filteredItems.length === 0}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetToolbarOpen(false)\n\t\t\t\t\t\tsetMobileSelectionPath(browser.currentPath)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\tSelect items\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{isNarrow && !readOnly && browser.clipboard ? (\n\t\t\t\t<button\n\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetToolbarOpen(false)\n\t\t\t\t\t\tvoid pasteClipboardInto(browser.currentPath)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\tPaste here\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t</div>\n\t)\n\n\tconst selectionActions = (\n\t\t<ActionBar\n\t\t\tcanCopy={!readOnly && browser.capabilities.copy}\n\t\t\tcanCut={!readOnly && browser.capabilities.move}\n\t\t\tcanDelete={!readOnly}\n\t\t\tcanMove={!readOnly && browser.capabilities.move}\n\t\t\tcanRename={!readOnly && browser.capabilities.rename}\n\t\t\tcanDownload={canDownloadSelection}\n\t\t\titemCount={browser.filteredItems.length}\n\t\t\tonCopy={() => copySelectedItems()}\n\t\t\tonCut={() => cutSelectedItems()}\n\t\t\tonDelete={() => setDeleteConfirmOpen(true)}\n\t\t\tonDownload={() => void downloadSelection()}\n\t\t\tonMove={openMoveDialog}\n\t\t\tonRename={openRenameDialog}\n\t\t\tonSelectAll={browser.selectAllLoaded}\n\t\t\tonSelectNone={browser.clearSelection}\n\t\t\tselectedCount={browser.selectedPaths.length}\n\t\t/>\n\t)\n\n\tconst detailsContent = (\n\t\t<DetailsPanel\n\t\t\tcanDownload={canDownloadSelection}\n\t\t\titem={selected}\n\t\t\tonCopyPath={() => void copyItemPaths(browser.selectedPaths)}\n\t\t\tonDownload={() => void downloadSelection()}\n\t\t\trenderDetailsContent={renderDetailsContent}\n\t\t\tselectedCount={browser.selectedItems.length}\n\t\t\ttotalBytes={totalSelectedBytes}\n\t\t\tsheet={!hasSidebar}\n\t\t/>\n\t)\n\n\treturn (\n\t\t<section\n\t\t\tclassName={`@container/fb relative flex min-h-[min(520px,100svh)] w-full min-w-0 max-w-full overflow-hidden rounded-[calc(var(--fb-radius)+2px)] border border-[var(--fb-border)] bg-[var(--fb-bg)] font-[inherit] text-[length:var(--fb-font)] text-[var(--fb-text)] ${SURFACE_MOTION}${className ? ` ${className}` : ''}`}\n\t\t\tdata-fb-density={density}\n\t\t\tdata-fb-layout={isNarrow ? 'narrow' : hasSidebar ? 'wide' : 'medium'}\n\t\t\tref={rootRef}\n\t\t\tstyle={\n\t\t\t\t{\n\t\t\t\t\t...DENSITY_STYLES[density],\n\t\t\t\t\t...(isNarrow ? { '--fb-control-h': 'calc(var(--fb-gap) * 11)' } : {})\n\t\t\t\t} as CSSProperties\n\t\t\t}\n\t\t\tonDragEnter={(event) => {\n\t\t\t\tif (getActiveDraggedPaths(event.dataTransfer).length > 0) {\n\t\t\t\t\tsetDropActive(false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tevent.preventDefault()\n\t\t\t\tif (!readOnly) {\n\t\t\t\t\tsetDropActive(true)\n\t\t\t\t}\n\t\t\t}}\n\t\t\tonDragLeave={(event) => {\n\t\t\t\tif (event.currentTarget === event.target) {\n\t\t\t\t\tsetDropActive(false)\n\t\t\t\t\tsetFolderDropTargetPath(null)\n\t\t\t\t}\n\t\t\t}}\n\t\t\tonDragOver={(event) => {\n\t\t\t\tif (getActiveDraggedPaths(event.dataTransfer).length > 0) {\n\t\t\t\t\tsetDropActive(false)\n\t\t\t\t\tsetFolderDropTargetPath(null)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tevent.preventDefault()\n\t\t\t}}\n\t\t\tonDrop={(event) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tif (getActiveDraggedPaths(event.dataTransfer).length > 0) {\n\t\t\t\t\tendItemDrag()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetDropActive(false)\n\t\t\t\tif (readOnly) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tvoid beginUploadDrop(event.dataTransfer)\n\t\t\t}}\n\t\t\tonPaste={(event) => {\n\t\t\t\tif (readOnly) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst files = Array.from(event.clipboardData.files).filter((file) => file.type.startsWith('image/'))\n\t\t\t\tif (files.length > 0) {\n\t\t\t\t\tvoid beginUploadFiles(files)\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<div aria-atomic=\"true\" aria-live=\"polite\" className=\"sr-only\" role=\"status\">\n\t\t\t\t{formatScreenReaderStatus({\n\t\t\t\t\tcurrentPath: browser.currentPath,\n\t\t\t\t\titemCount: browser.filteredItems.length,\n\t\t\t\t\trootLabel,\n\t\t\t\t\tselectedCount: browser.selectedPaths.length,\n\t\t\t\t\tstatus: browser.status\n\t\t\t\t})}\n\t\t\t</div>\n\t\t\t<div className=\"flex min-w-0 flex-1 flex-col\">\n\t\t\t\t<input\n\t\t\t\t\taccept={uploadPolicy?.allowedMimeTypes?.length ? uploadPolicy.allowedMimeTypes.join(',') : undefined}\n\t\t\t\t\taria-label=\"Upload files\"\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={(event) => void uploadInputFiles(event.target.files)}\n\t\t\t\t\tref={uploadInputRef}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\tclassName=\"hidden\"\n\t\t\t\t/>\n\t\t\t\t<header\n\t\t\t\t\tclassName={`flex min-h-[var(--fb-header-h)] min-w-0 flex-wrap items-center gap-x-3 gap-y-2.5 border-b border-[var(--fb-border)] px-[var(--fb-pad)] py-3 ${isNarrow ? 'px-4' : ''} ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\t{mobileSelection ? (\n\t\t\t\t\t\t<div className=\"flex w-full min-w-0 items-center gap-[calc(var(--fb-gap)*2)]\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\taria-label=\"Exit selection\"\n\t\t\t\t\t\t\t\tclassName={`${toolButton(false)} border-transparent bg-transparent`}\n\t\t\t\t\t\t\t\tonClick={exitMobileSelection}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<XIcon aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<span className=\"mr-auto whitespace-nowrap text-[17px] font-bold\">\n\t\t\t\t\t\t\t\t{browser.selectedPaths.length} selected\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tclassName={`${barButton('ghost')} font-semibold ${ACCENT_INK}`}\n\t\t\t\t\t\t\t\tonClick={browser.selectAllLoaded}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tSelect all\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<div className={`flex min-w-0 items-center gap-3 ${isNarrow ? 'flex-1' : 'w-full'}`}>\n\t\t\t\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t<Breadcrumbs\n\t\t\t\t\t\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\t\t\t\t\t\tonNavigate={(nextPath) => browser.navigate(nextPath, { source: 'breadcrumb' })}\n\t\t\t\t\t\t\t\t\t\tpath={browser.currentPath}\n\t\t\t\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{clipboardStatus}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{isNarrow ? (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\taria-label=\"Browser options\"\n\t\t\t\t\t\t\t\t\taria-expanded={toolbarOpen}\n\t\t\t\t\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t\t\t\t\t\tclassName={toolButton(false)}\n\t\t\t\t\t\t\t\t\tonClick={() => setToolbarOpen(true)}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<MoreHorizontal aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t\t{mobileSelection ? clipboardStatus : null}\n\t\t\t\t\t{!mobileSelection ? (\n\t\t\t\t\t\t<div className=\"flex w-full min-w-0 flex-wrap items-center gap-3\">\n\t\t\t\t\t\t\t<label className={`relative block min-w-0 ${isNarrow ? 'w-full' : 'min-w-[180px] flex-1'}`}>\n\t\t\t\t\t\t\t\t<Search\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\tclassName=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-[var(--fb-muted)]\"\n\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\taria-label=\"Search files\"\n\t\t\t\t\t\t\t\t\tclassName={`h-[var(--fb-control-h)] min-h-[var(--fb-control-h)] w-full min-w-0 rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] pl-9 pr-3 text-[16px] text-[var(--fb-text)] outline-none placeholder:text-[var(--fb-muted)] focus:border-[var(--fb-accent)] focus:ring-[3px] focus:ring-[color-mix(in_oklch,var(--fb-accent)_15%,transparent)] @min-[40rem]/fb:text-[var(--fb-font)] [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:text-[16px] ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\tonChange={(event) => browser.setSearchQuery(event.target.value)}\n\t\t\t\t\t\t\t\t\tplaceholder=\"Search this folder\"\n\t\t\t\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\t\t\t\tvalue={browser.searchQuery}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t{!isNarrow ? secondaryControls : null}\n\t\t\t\t\t\t\t{!isNarrow && !readOnly ? (\n\t\t\t\t\t\t\t\t<button className={primaryButton()} onClick={() => uploadInputRef.current?.click()} type=\"button\">\n\t\t\t\t\t\t\t\t\t<Upload aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t\tUpload\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</header>\n\n\t\t\t\t{!isNarrow ? selectionActions : null}\n\t\t\t\t{!hasSidebar && !isNarrow && showDetailsPanel ? (\n\t\t\t\t\t<div className=\"flex justify-end px-[var(--fb-pad)] pt-3\">\n\t\t\t\t\t\t<button className={barButton()} onClick={() => setDetailsOpen(true)} type=\"button\">\n\t\t\t\t\t\t\t<Info aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\tDetails\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\n\t\t\t\t{uploadRejections.length > 0 ? (\n\t\t\t\t\t<UploadRejectionAlert onDismiss={() => setUploadRejections([])} rejections={uploadRejections} />\n\t\t\t\t) : null}\n\n\t\t\t\t<div\n\t\t\t\t\tclassName={`relative min-h-0 min-w-0 flex-1 overflow-auto bg-[var(--fb-bg)] px-[var(--fb-pad)] pb-[var(--fb-pad)] pt-1 ${isNarrow ? 'px-3 pt-3' : ''} ${isNarrow && !readOnly && !mobileSelection ? 'pb-[calc(var(--fb-gap)*20)]' : ''} ${SURFACE_MOTION}`}\n\t\t\t\t\tonClick={clearSelectionFromEmptySurface}\n\t\t\t\t\tonContextMenu={openEmptyContextMenu}\n\t\t\t\t>\n\t\t\t\t\t{browser.status === 'loading' && browser.items.length === 0 ? (\n\t\t\t\t\t\t<SkeletonGrid rootLabel={rootLabel} />\n\t\t\t\t\t) : browser.status === 'error' ? (\n\t\t\t\t\t\t<StateMessage\n\t\t\t\t\t\t\ticon={isAccessDeniedError(browser.error) ? 'lock' : 'error'}\n\t\t\t\t\t\t\ttitle={getErrorState(browser.error).title}\n\t\t\t\t\t\t\tvalue={getErrorState(browser.error).value}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : browser.filteredItems.length === 0 ? (\n\t\t\t\t\t\t<StateMessage\n\t\t\t\t\t\t\ticon=\"folder\"\n\t\t\t\t\t\t\ttitle={emptyState ? emptyState.title : 'This folder is empty'}\n\t\t\t\t\t\t\tvalue={emptyState ? emptyState.description : 'Create a folder or upload files to start.'}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : browser.view === 'grid' ? (\n\t\t\t\t\t\t<FileGrid\n\t\t\t\t\t\t\tbrowser={browser}\n\t\t\t\t\t\t\tcanMove={!readOnly && browser.capabilities.move}\n\t\t\t\t\t\t\tfolderDropTargetPath={folderDropTargetPath}\n\t\t\t\t\t\t\tinlineRenameError={inlineRenameError}\n\t\t\t\t\t\t\tinlineRenameLabel={inlineRenameItem?.name ?? ''}\n\t\t\t\t\t\t\tinlineRenameItem={inlineRenameItem}\n\t\t\t\t\t\t\tinlineRenameValue={inlineRenameValue}\n\t\t\t\t\t\t\tonDragStart={startItemDrag}\n\t\t\t\t\t\t\tonDragEnd={endItemDrag}\n\t\t\t\t\t\t\tonFolderDragOver={allowFolderDrop}\n\t\t\t\t\t\t\tonFolderDrop={(item, event) => void moveDraggedItemsToFolder(item, event)}\n\t\t\t\t\t\t\tonEmptyClick={() => browser.clearSelection()}\n\t\t\t\t\t\t\tonInlineRenameCancel={cancelInlineRename}\n\t\t\t\t\t\t\tonInlineRenameChange={(value) => {\n\t\t\t\t\t\t\t\tsetInlineRenameValue(value)\n\t\t\t\t\t\t\t\tsetInlineRenameError(null)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonInlineRenameCommit={() => void commitInlineRename()}\n\t\t\t\t\t\t\tonContextMenu={openItemContextMenu}\n\t\t\t\t\t\t\tonOpenItem={openItemFromDoubleClick}\n\t\t\t\t\t\t\tonSelectItem={selectItemWithEvent}\n\t\t\t\t\t\t\tonTouchMenu={openItemTouchMenu}\n\t\t\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\t\t\tselectionMode={mobileSelection}\n\t\t\t\t\t\t\tonToggleItem={browser.toggleSelection}\n\t\t\t\t\t\t\trenderItemMeta={renderItemMeta}\n\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\tselectedPaths={browser.selectedPaths}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<FileTable\n\t\t\t\t\t\t\tbrowser={browser}\n\t\t\t\t\t\t\tcanMove={!readOnly && browser.capabilities.move}\n\t\t\t\t\t\t\tfolderDropTargetPath={folderDropTargetPath}\n\t\t\t\t\t\t\tinlineRenameError={inlineRenameError}\n\t\t\t\t\t\t\tinlineRenameLabel={inlineRenameItem?.name ?? ''}\n\t\t\t\t\t\t\tinlineRenameItem={inlineRenameItem}\n\t\t\t\t\t\t\tinlineRenameValue={inlineRenameValue}\n\t\t\t\t\t\t\tonDragStart={startItemDrag}\n\t\t\t\t\t\t\tonDragEnd={endItemDrag}\n\t\t\t\t\t\t\tonFolderDragOver={allowFolderDrop}\n\t\t\t\t\t\t\tonFolderDrop={(item, event) => void moveDraggedItemsToFolder(item, event)}\n\t\t\t\t\t\t\tonInlineRenameCancel={cancelInlineRename}\n\t\t\t\t\t\t\tonInlineRenameChange={(value) => {\n\t\t\t\t\t\t\t\tsetInlineRenameValue(value)\n\t\t\t\t\t\t\t\tsetInlineRenameError(null)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonInlineRenameCommit={() => void commitInlineRename()}\n\t\t\t\t\t\t\tonContextMenu={openItemContextMenu}\n\t\t\t\t\t\t\tonOpenItem={openItemFromDoubleClick}\n\t\t\t\t\t\t\tonSelectItem={selectItemWithEvent}\n\t\t\t\t\t\t\tonTouchMenu={openItemTouchMenu}\n\t\t\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\t\t\tselectionMode={mobileSelection}\n\t\t\t\t\t\t\tonToggleItem={browser.toggleSelection}\n\t\t\t\t\t\t\trenderItemMeta={renderItemMeta}\n\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\tselectedPaths={browser.selectedPaths}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{dropActive ? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`pointer-events-none absolute inset-4 z-10 flex flex-col items-center justify-center gap-3.5 rounded-[calc(var(--fb-radius)+6px)] border-2 border-dashed border-[var(--fb-accent)] bg-[color-mix(in_oklch,var(--fb-accent-soft)_92%,var(--fb-surface))] text-center backdrop-blur-[1px] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span className=\"grid size-[72px] place-items-center rounded-full bg-[var(--fb-accent)] text-[var(--fb-surface)]\">\n\t\t\t\t\t\t\t\t<Upload aria-hidden=\"true\" className=\"size-8\" strokeWidth={2} />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span className={`text-[20px] font-bold ${ACCENT_INK}`}>Drop files to upload</span>\n\t\t\t\t\t\t\t<span className=\"text-[var(--fb-font)] text-[var(--fb-muted)]\">Folders keep their structure</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\n\t\t\t\t<footer\n\t\t\t\t\tclassName={`sticky bottom-0 flex min-h-11 min-w-0 flex-wrap items-center justify-between gap-[var(--fb-gap)] border-t border-[var(--fb-border)] bg-[var(--fb-bg)] px-[var(--fb-pad)] py-1 text-[var(--fb-font-sm)] text-[var(--fb-muted)] ${isNarrow ? 'bg-[var(--fb-surface)] px-3' : ''} ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\t{mobileSelection ? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\taria-label=\"Selection actions\"\n\t\t\t\t\t\t\tclassName=\"flex w-full flex-wrap items-center gap-[calc(var(--fb-gap)*2)]\"\n\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\tdisabled={!selected}\n\t\t\t\t\t\t\t\tonClick={() => setSelectionActionsOpen(true)}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MoreHorizontal aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\tActions\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t{showDetailsPanel ? (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\t\tdisabled={!selected}\n\t\t\t\t\t\t\t\t\tonClick={() => setDetailsOpen(true)}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Info aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t\tDetails\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<span>\n\t\t\t\t\t\t{browser.filteredItems.length} items\n\t\t\t\t\t\t{browser.selectedPaths.length ? ` · ${browser.selectedPaths.length} selected` : ''}\n\t\t\t\t\t</span>\n\t\t\t\t\t{isNarrow && !readOnly && !mobileSelection ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label=\"Upload\"\n\t\t\t\t\t\t\tclassName={`${primaryButton()} absolute bottom-[calc(var(--fb-gap)*14)] right-4 rounded-full px-5 shadow-[0_10px_24px_color-mix(in_oklch,var(--fb-accent)_35%,transparent)]`}\n\t\t\t\t\t\t\tonClick={() => uploadInputRef.current?.click()}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Upload aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\tUpload\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{browser.hasMore ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tclassName={`inline-flex min-h-[var(--fb-bar-control-h)] items-center rounded-[calc(var(--fb-radius)-2px)] px-3 font-semibold ${ACCENT_INK} hover:bg-[var(--fb-accent-soft)] ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\tonClick={() => void browser.loadMore()}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tLoad more\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span />\n\t\t\t\t\t)}\n\t\t\t\t</footer>\n\t\t\t</div>\n\n\t\t\t{showDetailsPanel && hasSidebar ? detailsContent : null}\n\t\t\t{showDetailsPanel && !hasSidebar && detailsOpen ? (\n\t\t\t\t<ActionSheet label=\"Details\" onClose={() => setDetailsOpen(false)}>\n\t\t\t\t\t{detailsContent}\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\t\t\t{isNarrow && toolbarOpen ? (\n\t\t\t\t<ActionSheet label=\"Browser options\" onClose={() => setToolbarOpen(false)}>\n\t\t\t\t\t{secondaryControls}\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\t\t\t{mobileSelection && selectionActionsOpen ? (\n\t\t\t\t<ActionSheet label=\"Selected item actions\" onClose={() => setSelectionActionsOpen(false)}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tif ((event.target as Element).closest('button:not(:disabled)')) setSelectionActionsOpen(false)\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{selectionActions}\n\t\t\t\t\t</div>\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\n\t\t\t{contextMenu ? (\n\t\t\t\t<ContextMenu\n\t\t\t\t\tbrowser={browser}\n\t\t\t\t\tcanDownload={canDownloadSelection}\n\t\t\t\t\tmenu={contextMenu}\n\t\t\t\t\tonClose={() => setContextMenu(null)}\n\t\t\t\t\tonDelete={() => setDeleteConfirmOpen(true)}\n\t\t\t\t\tonDownload={() => void downloadSelection()}\n\t\t\t\t\tonMove={openMoveDialog}\n\t\t\t\t\tonNewFolder={() => {\n\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\tsetNewFolderOpen(true)\n\t\t\t\t\t}}\n\t\t\t\t\tonCopy={() => copySelectedItems()}\n\t\t\t\t\tonCopyPath={(item) =>\n\t\t\t\t\t\tvoid copyItemPaths(browser.selectedPaths.includes(item.path) ? browser.selectedPaths : [item.path])\n\t\t\t\t\t}\n\t\t\t\t\tonCut={() => cutSelectedItems()}\n\t\t\t\t\tonPaste={() => void pasteClipboardInto(browser.currentPath)}\n\t\t\t\t\tonRename={openRenameDialog}\n\t\t\t\t\tonUpload={() => uploadInputRef.current?.click()}\n\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t/>\n\t\t\t) : null}\n\n\t\t\t{newFolderOpen ? (\n\t\t\t\t<ResponsiveDialog label=\"New folder\" narrow={isNarrow} onClose={() => setNewFolderOpen(false)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`${DIALOG_SURFACE} max-w-[420px]`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid createFolder()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<h2 className={DIALOG_TITLE}>New folder</h2>\n\t\t\t\t\t\t<label className=\"mt-4 flex flex-col gap-1.5 text-[calc(var(--fb-font)-1px)] font-semibold\">\n\t\t\t\t\t\t\tFolder name\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\taria-invalid={newFolderError ? true : undefined}\n\t\t\t\t\t\t\t\taria-label=\"Folder name\"\n\t\t\t\t\t\t\t\tclassName={textInput(Boolean(newFolderError))}\n\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\tsetNewFolderName(event.target.value)\n\t\t\t\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tvalue={newFolderName}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t{newFolderError ? (\n\t\t\t\t\t\t\t<div className=\"mt-2 text-[calc(var(--fb-font)-1px)] text-[var(--fb-danger)]\" role=\"alert\">\n\t\t\t\t\t\t\t\t{newFolderError}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className={DIALOG_ACTIONS}>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetNewFolderError(null)\n\t\t\t\t\t\t\t\t\tsetNewFolderOpen(false)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={primaryButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tCreate folder\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{renameItem ? (\n\t\t\t\t<ResponsiveDialog label=\"Rename item\" narrow={isNarrow} onClose={() => setRenameItem(null)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`${DIALOG_SURFACE} max-w-[420px]`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid renameSelectedItem()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<h2 className={DIALOG_TITLE}>Rename</h2>\n\t\t\t\t\t\t<label className=\"mt-4 flex flex-col gap-1.5 text-[calc(var(--fb-font)-1px)] font-semibold\">\n\t\t\t\t\t\t\tNew name\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\taria-invalid={renameError ? true : undefined}\n\t\t\t\t\t\t\t\taria-label=\"New name\"\n\t\t\t\t\t\t\t\tclassName={textInput(Boolean(renameError))}\n\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\tsetRenameValue(event.target.value)\n\t\t\t\t\t\t\t\t\tsetRenameError(null)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tvalue={renameValue}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t{renameError ? (\n\t\t\t\t\t\t\t<div className=\"mt-2 text-[calc(var(--fb-font)-1px)] text-[var(--fb-danger)]\" role=\"alert\">\n\t\t\t\t\t\t\t\t{renameError}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className={DIALOG_ACTIONS}>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tclassName={commandButton(false)}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetRenameItem(null)\n\t\t\t\t\t\t\t\t\tsetRenameValue('')\n\t\t\t\t\t\t\t\t\tsetRenameError(null)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={primaryButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tRename item\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{deleteConfirmOpen ? (\n\t\t\t\t<ResponsiveDialog label=\"Delete selected items\" narrow={isNarrow} onClose={() => setDeleteConfirmOpen(false)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`${DIALOG_SURFACE} max-w-[420px]`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid deleteSelectedItems()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"grid size-11 place-items-center rounded-full bg-[var(--fb-danger-soft)] text-[var(--fb-danger)]\">\n\t\t\t\t\t\t\t<Trash2 aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<h2 className={`${DIALOG_TITLE} mt-3.5`}>Delete selected items</h2>\n\t\t\t\t\t\t<p className={DIALOG_BODY}>This removes the selected entries from storage.</p>\n\t\t\t\t\t\t<ul\n\t\t\t\t\t\t\tclassName={`m-0 mt-3 max-h-32 list-none overflow-auto rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-bg)] px-3 py-1.5 text-[calc(var(--fb-font)-1px)] ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{browser.selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t<li className=\"flex min-w-0 items-center gap-2 py-1\" key={item.path}>\n\t\t\t\t\t\t\t\t\t<FileTypeTile item={item} size=\"sm\" />\n\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{item.name}</span>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t<div className={DIALOG_ACTIONS}>\n\t\t\t\t\t\t\t<button className={commandButton(false)} onClick={() => setDeleteConfirmOpen(false)} type=\"button\">\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={dangerButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tDelete selected\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{moveDialogOpen ? (\n\t\t\t\t<ResponsiveDialog label=\"Move selected items\" narrow={isNarrow} onClose={() => setMoveDialogOpen(false)}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={`${DIALOG_SURFACE} max-w-[480px]`}\n\t\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tvoid moveSelectedItems()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<h2 className={DIALOG_TITLE}>Move selected items</h2>\n\t\t\t\t\t\t<p className={`${DIALOG_BODY} mt-1`}>Choose a destination folder from the folder tree.</p>\n\t\t\t\t\t\t<MoveDestinationPicker\n\t\t\t\t\t\t\tcurrentPath={browser.currentPath}\n\t\t\t\t\t\t\tdestinations={moveDestinations}\n\t\t\t\t\t\t\terror={moveDestinationError}\n\t\t\t\t\t\t\tonSelect={setMoveDestination}\n\t\t\t\t\t\t\trootLabel={rootLabel}\n\t\t\t\t\t\t\tselectedPath={moveDestination}\n\t\t\t\t\t\t\tstatus={moveDestinationStatus}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<div className=\"mt-3 truncate text-[var(--fb-font-sm)] text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\tDestination: {moveDestination}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className={DIALOG_ACTIONS}>\n\t\t\t\t\t\t\t<button className={commandButton(false)} onClick={() => setMoveDialogOpen(false)} type=\"button\">\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className={primaryButton()} type=\"submit\">\n\t\t\t\t\t\t\t\tMove here\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\n\t\t\t{bulkFailure ? (\n\t\t\t\t<BulkFailureDialog error={bulkFailure} narrow={isNarrow} onClose={() => setBulkFailure(null)} />\n\t\t\t) : null}\n\n\t\t\t{uploadConflictQueue ? (\n\t\t\t\t<UploadConflictDialog\n\t\t\t\t\tapplyToAll={applyUploadResolution}\n\t\t\t\t\tnarrow={isNarrow}\n\t\t\t\t\tcurrentPath={browser.currentPath}\n\t\t\t\t\tonApplyToAllChange={setApplyUploadResolution}\n\t\t\t\t\tonCancel={() => {\n\t\t\t\t\t\tsetUploadConflictQueue(null)\n\t\t\t\t\t\tsetApplyUploadResolution(false)\n\t\t\t\t\t}}\n\t\t\t\t\tonResolve={(resolution) => resolveUploadConflict(resolution)}\n\t\t\t\t\tqueue={uploadConflictQueue}\n\t\t\t\t\tresolutions={allowedUploadConflictResolutions}\n\t\t\t\t/>\n\t\t\t) : null}\n\n\t\t\t{preview ? (\n\t\t\t\t<ResponsiveDialog label={`Preview ${preview.item.name}`} narrow={isNarrow} onClose={() => setPreview(null)}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={`flex w-[min(1120px,100%)] min-w-0 flex-col overflow-hidden rounded-[calc(var(--fb-radius)+6px)] bg-[var(--fb-surface)] shadow-[0_24px_60px_color-mix(in_oklch,var(--fb-text)_30%,transparent)] ${SURFACE_MOTION}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`flex min-h-[60px] min-w-0 items-center gap-3 border-b border-[var(--fb-border)] py-2.5 pl-6 pr-4 ${isNarrow ? 'pl-4' : ''} ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"flex min-w-0 flex-1 flex-col\">\n\t\t\t\t\t\t\t\t<span className=\"truncate text-[15px] font-bold\">{preview.item.name}</span>\n\t\t\t\t\t\t\t\t<span className=\"truncate text-[var(--fb-font-sm)] text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\t\t\t{previewPosition > 0 ? `${previewPosition} of ${previewFiles.length} · ` : ''}\n\t\t\t\t\t\t\t\t\t{formatBytes(preview.item.size ?? 0)}\n\t\t\t\t\t\t\t\t\t{preview.item.mimeType ? ` · ${preview.item.mimeType}` : ''}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<PreviewOriginalLink preview={preview} />\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t\t\t\t\tclassName={`${toolButton(false)} border-transparent bg-transparent text-[var(--fb-text)]`}\n\t\t\t\t\t\t\t\tonClick={() => setPreview(null)}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<XIcon aria-hidden=\"true\" className=\"size-[18px]\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`flex min-h-[min(420px,55dvh)] min-w-0 items-center justify-center gap-6 bg-[var(--fb-bg)] p-6 ${isNarrow ? 'gap-2 p-3' : ''} ${SURFACE_MOTION}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\taria-label=\"Previous file\"\n\t\t\t\t\t\t\t\tclassName={`${previewNavButton} ${isNarrow ? 'size-10' : ''}`}\n\t\t\t\t\t\t\t\tdisabled={previewFiles.length <= 1}\n\t\t\t\t\t\t\t\tonClick={() => showAdjacentPreview(-1)}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ChevronLeft aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div className=\"flex min-w-0 flex-1 justify-center\">\n\t\t\t\t\t\t\t\t{(preview.item.mimeType?.startsWith('image/') && preview.url) || preview.item.thumbnailUrl ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\talt={preview.item.name}\n\t\t\t\t\t\t\t\t\t\tclassName={`max-h-[min(560px,60dvh)] max-w-full rounded-[var(--fb-radius)] object-contain ${SURFACE_MOTION}`}\n\t\t\t\t\t\t\t\t\t\tsrc={preview.url ?? preview.item.thumbnailUrl}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<div className=\"flex min-w-0 max-w-full flex-col items-center gap-3 text-center\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"block w-[72px]\">\n\t\t\t\t\t\t\t\t\t\t\t<FileTypeTile item={preview.item} size=\"md\" />\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<div className=\"text-[15px] font-bold\">{preview.item.name}</div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\t\t\t\t\t{preview.item.mimeType ?? 'File'}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{preview.status === 'loading' ? (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]\">Loading preview</div>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t{preview.status === 'error' ? (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-[calc(var(--fb-font)-1px)] text-[var(--fb-danger)]\">\n\t\t\t\t\t\t\t\t\t\t\t\t{preview.error ?? 'Could not load preview'}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\taria-label=\"Next file\"\n\t\t\t\t\t\t\t\tclassName={`${previewNavButton} ${isNarrow ? 'size-10' : ''}`}\n\t\t\t\t\t\t\t\tdisabled={previewFiles.length <= 1}\n\t\t\t\t\t\t\t\tonClick={() => showAdjacentPreview(1)}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ChevronRight aria-hidden=\"true\" className=\"size-5\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</ResponsiveDialog>\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\n\ntype BrowserLike<TMetadata = unknown> = UseFileBrowserResult<TMetadata>\n\nfunction joinUploadRelativePath(currentPath: string, relativePath: string) {\n\treturn relativePath\n\t\t.split('/')\n\t\t.filter(Boolean)\n\t\t.reduce((path, part) => joinFileBrowserPath(path, part), currentPath)\n}\n\nfunction getUploadFolderPaths(candidates: FileBrowserUploadCandidate[]) {\n\tconst folders = new Set<string>()\n\n\tfor (const { relativePath } of candidates) {\n\t\tconst parts = relativePath.split('/').filter(Boolean)\n\t\tfor (let index = 1; index < parts.length; index += 1) {\n\t\t\tfolders.add(parts.slice(0, index).join('/'))\n\t\t}\n\t}\n\n\treturn Array.from(folders).sort((a, b) => a.split('/').length - b.split('/').length || a.localeCompare(b))\n}\n\nfunction partitionUploadCandidates(\n\tcandidates: FileBrowserUploadCandidate[],\n\tpredicate: (candidate: FileBrowserUploadCandidate) => boolean\n): [FileBrowserUploadCandidate[], FileBrowserUploadCandidate[]] {\n\tconst matched: FileBrowserUploadCandidate[] = []\n\tconst unmatched: FileBrowserUploadCandidate[] = []\n\n\tfor (const candidate of candidates) {\n\t\tif (predicate(candidate)) {\n\t\t\tmatched.push(candidate)\n\t\t} else {\n\t\t\tunmatched.push(candidate)\n\t\t}\n\t}\n\n\treturn [matched, unmatched]\n}\n\nfunction getUploadTransferGroup(\n\tcurrentPath: string,\n\tcandidates: FileBrowserUploadCandidate[],\n\tcreatedFolders = 0\n): UploadTransferGroup | undefined {\n\tif (getUploadFolderPaths(candidates).length === 0) {\n\t\treturn undefined\n\t}\n\n\tconst topLevelFolders = candidates\n\t\t.map((candidate) => candidate.relativePath.split('/').filter(Boolean)[0])\n\t\t.filter((folder): folder is string => Boolean(folder))\n\tconst uniqueTopLevelFolders = Array.from(new Set(topLevelFolders))\n\tconst name = uniqueTopLevelFolders.length === 1 ? uniqueTopLevelFolders[0] : 'Folder upload'\n\tconst id =\n\t\tuniqueTopLevelFolders.length === 1\n\t\t\t? joinUploadRelativePath(currentPath, name)\n\t\t\t: `${normalizeFileBrowserPath(currentPath)}#folder-upload`\n\n\treturn {\n\t\tid,\n\t\tname,\n\t\ttotalFiles: candidates.length,\n\t\tcreatedFolders\n\t}\n}\n\nasync function collectMoveDestinations<TMetadata>(\n\tadapter: FileBrowserAdapter<TMetadata>,\n\texcludedPaths: string[]\n): Promise<MoveDestination[]> {\n\tconst destinations: MoveDestination[] = []\n\tconst excluded = excludedPaths.map(normalizeFileBrowserPath)\n\n\tasync function collect(path: string, depth: number): Promise<void> {\n\t\tlet cursor: string | undefined\n\t\tdo {\n\t\t\tconst result = await adapter.list(path, { cursor })\n\t\t\tconst folders = result.items\n\t\t\t\t.filter((item) => item.kind === 'folder')\n\t\t\t\t.sort((left, right) =>\n\t\t\t\t\tleft.name.localeCompare(right.name, undefined, {\n\t\t\t\t\t\tnumeric: true,\n\t\t\t\t\t\tsensitivity: 'base'\n\t\t\t\t\t})\n\t\t\t\t)\n\n\t\t\tfor (const folder of folders) {\n\t\t\t\tif (isExcludedDestination(folder.path, excluded)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tdestinations.push({\n\t\t\t\t\tpath: folder.path,\n\t\t\t\t\tname: folder.name,\n\t\t\t\t\tdepth\n\t\t\t\t})\n\t\t\t\tawait collect(folder.path, depth + 1)\n\t\t\t}\n\n\t\t\tcursor = result.cursor\n\t\t} while (cursor)\n\t}\n\n\tawait collect('/', 0)\n\treturn destinations\n}\n\nfunction isExcludedDestination(path: string, excludedPaths: string[]) {\n\tconst normalized = normalizeFileBrowserPath(path)\n\treturn excludedPaths.some((excluded) => normalized === excluded || normalized.startsWith(`${excluded}/`))\n}\n\nfunction applyUploadPolicy(\n\tcandidates: FileBrowserUploadCandidate[],\n\tpolicy: FileBrowserUploadPolicy | undefined,\n\tcurrentPath: string\n) {\n\tif (!policy) {\n\t\treturn { acceptedCandidates: candidates, rejectedCandidates: [] }\n\t}\n\n\tconst acceptedCandidates: FileBrowserUploadCandidate[] = []\n\tconst rejectedCandidates: FileBrowserUploadRejection[] = []\n\tlet acceptedBytes = 0\n\n\tfor (const candidate of candidates) {\n\t\tconst reasons: string[] = []\n\n\t\tif (policy.maxFileSizeBytes !== undefined && candidate.file.size > policy.maxFileSizeBytes) {\n\t\t\treasons.push(`File is larger than ${formatBytes(policy.maxFileSizeBytes)}`)\n\t\t}\n\n\t\tif (policy.allowedMimeTypes?.length && !isAllowedUploadType(candidate.file, policy.allowedMimeTypes)) {\n\t\t\treasons.push(`File type ${candidate.file.type || 'unknown'} is not allowed`)\n\t\t}\n\n\t\tif (policy.remainingQuotaBytes !== undefined && acceptedBytes + candidate.file.size > policy.remainingQuotaBytes) {\n\t\t\treasons.push(`Upload exceeds remaining quota of ${formatBytes(policy.remainingQuotaBytes)}`)\n\t\t}\n\n\t\tconst customReason = policy.validate?.(candidate, {\n\t\t\tacceptedBytes,\n\t\t\tcurrentPath\n\t\t})\n\t\tif (Array.isArray(customReason)) {\n\t\t\treasons.push(...customReason.filter(Boolean))\n\t\t} else if (customReason) {\n\t\t\treasons.push(customReason)\n\t\t}\n\n\t\tif (reasons.length > 0) {\n\t\t\trejectedCandidates.push({\n\t\t\t\tfileName: candidate.file.name,\n\t\t\t\trelativePath: candidate.relativePath,\n\t\t\t\treasons\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tacceptedBytes += candidate.file.size\n\t\tacceptedCandidates.push(candidate)\n\t}\n\n\treturn { acceptedCandidates, rejectedCandidates }\n}\n\nfunction isAllowedUploadType(file: File, allowedMimeTypes: string[]) {\n\treturn allowedMimeTypes.some((allowed) => {\n\t\tif (allowed.endsWith('/*')) {\n\t\t\treturn file.type.startsWith(allowed.slice(0, -1))\n\t\t}\n\t\tif (allowed.startsWith('.')) {\n\t\t\treturn file.name.toLowerCase().endsWith(allowed.toLowerCase())\n\t\t}\n\t\treturn file.type === allowed\n\t})\n}\n\nfunction FileGrid<TMetadata>({\n\tbrowser,\n\tcanMove,\n\tfolderDropTargetPath,\n\tinlineRenameError,\n\tinlineRenameLabel,\n\tinlineRenameItem,\n\tinlineRenameValue,\n\tselectedPaths,\n\tonContextMenu,\n\tonDragEnd,\n\tonDragStart,\n\tonEmptyClick,\n\tonFolderDragOver,\n\tonFolderDrop,\n\tonInlineRenameCancel,\n\tonInlineRenameChange,\n\tonInlineRenameCommit,\n\tonOpenItem,\n\tonSelectItem,\n\tonTouchMenu,\n\tnarrow,\n\tselectionMode,\n\tonToggleItem,\n\trenderItemMeta,\n\trootLabel\n}: {\n\tbrowser: BrowserLike<TMetadata>\n\tcanMove: boolean\n\tfolderDropTargetPath: string | null\n\tinlineRenameError: string | null\n\tinlineRenameLabel: string\n\tinlineRenameItem: FileNode<TMetadata> | null\n\tinlineRenameValue: string\n\tselectedPaths: string[]\n\tonContextMenu: (item: FileNode<TMetadata>, event: MouseEvent) => void\n\tonDragEnd: () => void\n\tonDragStart: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonEmptyClick: () => void\n\tonFolderDragOver: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonFolderDrop: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonInlineRenameCancel: () => void\n\tonInlineRenameChange: (value: string) => void\n\tonInlineRenameCommit: () => void\n\tonOpenItem: (item: FileNode<TMetadata>) => void\n\tonSelectItem: (path: string, event: MouseEvent) => void\n\tonTouchMenu: (item: FileNode<TMetadata>) => void\n\tnarrow: boolean\n\tselectionMode: boolean\n\tonToggleItem: (path: string) => void\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\trootLabel: string\n}) {\n\tconst [gridElement, setGridElement] = useState<HTMLDivElement | null>(null)\n\n\tfunction handleMarqueeSelect(event: OnSelect) {\n\t\tconst inputEvent = event.inputEvent as MouseEvent | KeyboardEvent | undefined\n\t\tconst paths = event.selected\n\t\t\t.map((element) => element.getAttribute('data-fb-path'))\n\t\t\t.filter((path): path is string => Boolean(path))\n\n\t\tbrowser.setSelection(paths, {\n\t\t\tadditive: Boolean(inputEvent?.shiftKey || inputEvent?.metaKey || inputEvent?.ctrlKey)\n\t\t})\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{gridElement && !narrow ? (\n\t\t\t\t<Selecto\n\t\t\t\t\tclassName=\"rounded-[4px] [background:color-mix(in_oklch,var(--fb-accent)_10%,transparent)!important] [border:1.5px_solid_var(--fb-accent)!important]\"\n\t\t\t\t\tcontainer={gridElement}\n\t\t\t\t\tdragContainer={gridElement}\n\t\t\t\t\thitRate={10}\n\t\t\t\t\tonSelect={handleMarqueeSelect}\n\t\t\t\t\tonDragStart={(event) => {\n\t\t\t\t\t\tif (event.inputEvent?.type?.startsWith('touch')) event.stop()\n\t\t\t\t\t}}\n\t\t\t\t\tpreventClickEventOnDrag\n\t\t\t\t\tselectByClick={false}\n\t\t\t\t\tselectableTargets={[\n\t\t\t\t\t\t() => Array.from(gridElement.querySelectorAll<HTMLElement | SVGElement>(\"[data-fb-selectable='true']\"))\n\t\t\t\t\t]}\n\t\t\t\t\tselectFromInside={false}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<div\n\t\t\t\taria-label={rootLabel}\n\t\t\t\tclassName=\"relative grid min-h-full min-w-0 touch-pan-y content-start grid-cols-[repeat(2,minmax(0,1fr))] gap-[calc(var(--fb-grid-gap)-4px)] @min-[40rem]/fb:grid-cols-[repeat(auto-fill,minmax(min(100%,var(--fb-card-min)),1fr))] @min-[40rem]/fb:gap-[var(--fb-grid-gap)]\"\n\t\t\t\tonClick={(event) => {\n\t\t\t\t\tif (!selectionMode && event.target === event.currentTarget && !hasSelectionModifier(event)) {\n\t\t\t\t\t\tonEmptyClick()\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\tref={setGridElement}\n\t\t\t\trole=\"grid\"\n\t\t\t>\n\t\t\t\t{browser.filteredItems.map((item) => (\n\t\t\t\t\t<FileCard\n\t\t\t\t\t\tcanMove={canMove}\n\t\t\t\t\t\tdropTarget={folderDropTargetPath === item.path}\n\t\t\t\t\t\titem={item}\n\t\t\t\t\t\tkey={item.path}\n\t\t\t\t\t\tonOpen={() => onOpenItem(item)}\n\t\t\t\t\t\tonContextMenu={(event) => onContextMenu(item, event)}\n\t\t\t\t\t\tonDragEnd={onDragEnd}\n\t\t\t\t\t\tonDragStart={(event) => onDragStart(item, event)}\n\t\t\t\t\t\tonFolderDragOver={(event) => onFolderDragOver(item, event)}\n\t\t\t\t\t\tonFolderDrop={(event) => onFolderDrop(item, event)}\n\t\t\t\t\t\tinlineRenameError={inlineRenameError}\n\t\t\t\t\t\tinlineRenameLabel={inlineRenameLabel}\n\t\t\t\t\t\tinlineRenameValue={inlineRenameValue}\n\t\t\t\t\t\tisRenaming={inlineRenameItem?.path === item.path}\n\t\t\t\t\t\tonInlineRenameCancel={onInlineRenameCancel}\n\t\t\t\t\t\tonInlineRenameChange={onInlineRenameChange}\n\t\t\t\t\t\tonInlineRenameCommit={onInlineRenameCommit}\n\t\t\t\t\t\tonSelect={(event) => onSelectItem(item.path, event)}\n\t\t\t\t\t\tonTouchMenu={() => onTouchMenu(item)}\n\t\t\t\t\t\tnarrow={narrow}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tonToggle={() => onToggleItem(item.path)}\n\t\t\t\t\t\trenderItemMeta={renderItemMeta}\n\t\t\t\t\t\tselected={selectedPaths.includes(item.path)}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</>\n\t)\n}\n\nfunction FileCard<TMetadata>({\n\tcanMove,\n\tdropTarget,\n\tinlineRenameError,\n\tinlineRenameLabel,\n\tinlineRenameValue,\n\tisRenaming,\n\titem,\n\tselected,\n\tonSelect,\n\tonOpen,\n\tonContextMenu,\n\tonDragEnd,\n\tonDragStart,\n\tonFolderDragOver,\n\tonFolderDrop,\n\tonInlineRenameCancel,\n\tonInlineRenameChange,\n\tonInlineRenameCommit,\n\tonTouchMenu,\n\tnarrow,\n\tselectionMode,\n\tonToggle,\n\trenderItemMeta\n}: {\n\tcanMove: boolean\n\tdropTarget: boolean\n\tinlineRenameError: string | null\n\tinlineRenameLabel: string\n\tinlineRenameValue: string\n\tisRenaming: boolean\n\titem: FileNode<TMetadata>\n\tselected: boolean\n\tonSelect: (event: MouseEvent) => void\n\tonOpen: () => void\n\tonContextMenu: (event: MouseEvent) => void\n\tonDragEnd: () => void\n\tonDragStart: (event: DragEvent) => void\n\tonFolderDragOver: (event: DragEvent) => void\n\tonFolderDrop: (event: DragEvent) => void\n\tonInlineRenameCancel: () => void\n\tonInlineRenameChange: (value: string) => void\n\tonInlineRenameCommit: () => void\n\tonTouchMenu: () => void\n\tnarrow: boolean\n\tselectionMode: boolean\n\tonToggle: () => void\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n}) {\n\tconst longPress = useLongPress(onTouchMenu)\n\n\treturn (\n\t\t<article\n\t\t\taria-selected={selected}\n\t\t\tdata-fb-drop-target={dropTarget ? 'true' : undefined}\n\t\t\tdata-fb-path={item.path}\n\t\t\tdata-fb-selectable=\"true\"\n\t\t\tdraggable={canMove && !narrow}\n\t\t\tclassName={`group relative flex min-h-[var(--fb-card-minh)] min-w-0 cursor-default flex-col gap-1.5 rounded-[calc(var(--fb-radius)+2px)] border-[1.5px] p-[var(--fb-card-pad)] outline-none focus-visible:ring-[3px] focus-visible:ring-[color-mix(in_oklch,var(--fb-accent)_22%,transparent)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--fb-bg)] ${SURFACE_MOTION} ${\n\t\t\t\tdropTarget\n\t\t\t\t\t? 'border-[var(--fb-accent)] bg-[var(--fb-accent-soft)] ring-2 ring-[var(--fb-accent)] ring-offset-2 ring-offset-[var(--fb-bg)]'\n\t\t\t\t\t: selected\n\t\t\t\t\t\t? 'border-[var(--fb-accent)] bg-[color-mix(in_oklch,var(--fb-accent-soft)_70%,var(--fb-surface))]'\n\t\t\t\t\t\t: 'border-[var(--fb-border)] bg-[var(--fb-surface)] hover:border-[var(--fb-border-strong)] hover:shadow-[0_6px_18px_color-mix(in_oklch,var(--fb-text)_7%,transparent)]'\n\t\t\t}`}\n\t\t\tonClick={onSelect}\n\t\t\tonContextMenu={onContextMenu}\n\t\t\tonDoubleClick={onOpen}\n\t\t\tonDragEnd={canMove ? onDragEnd : undefined}\n\t\t\tonDragOver={item.kind === 'folder' ? onFolderDragOver : undefined}\n\t\t\tonDragStart={canMove ? onDragStart : undefined}\n\t\t\tonDrop={item.kind === 'folder' ? onFolderDrop : undefined}\n\t\t\t{...longPress}\n\t\t\trole=\"gridcell\"\n\t\t\ttabIndex={0}\n\t\t>\n\t\t\t{selectionMode ? (\n\t\t\t\t<button\n\t\t\t\t\taria-label={`Select ${item.name}`}\n\t\t\t\t\taria-pressed={selected}\n\t\t\t\t\tclassName=\"absolute left-0 top-0 z-10 grid size-[calc(var(--fb-gap)*11)] place-items-center\"\n\t\t\t\t\tdata-fb-touch-control\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\tonToggle()\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<SelectionMark selected={selected} visibleOnHover={false} />\n\t\t\t\t</button>\n\t\t\t) : (\n\t\t\t\t<span className=\"absolute left-[calc(var(--fb-card-pad)+8px)] top-[calc(var(--fb-card-pad)+8px)] z-[1]\">\n\t\t\t\t\t<SelectionMark selected={selected} />\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t<FileTypeTile item={item} size=\"md\" />\n\t\t\t{isRenaming ? (\n\t\t\t\t<InlineRenameInput\n\t\t\t\t\titem={item}\n\t\t\t\t\terror={inlineRenameError}\n\t\t\t\t\tlabel={inlineRenameLabel}\n\t\t\t\t\tonCancel={onInlineRenameCancel}\n\t\t\t\t\tonChange={onInlineRenameChange}\n\t\t\t\t\tonCommit={onInlineRenameCommit}\n\t\t\t\t\tvalue={inlineRenameValue}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<button\n\t\t\t\t\tclassName={`mt-0.5 min-w-0 truncate rounded-[4px] text-left text-[var(--fb-font)] font-semibold text-[var(--fb-text)] outline-none [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] ${narrow ? 'min-h-[calc(var(--fb-gap)*11)]' : ''} ${CONTROL_MOTION}`}\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\tonSelect(event)\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t{item.name}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t\t<div className=\"flex min-w-0 gap-1 truncate text-[var(--fb-font-sm)] text-[var(--fb-muted)]\">\n\t\t\t\t<span>{item.kind === 'folder' ? 'Folder' : formatBytes(item.size ?? 0)}</span>\n\t\t\t\t{formatShortDate(item.modifiedAt) ? <span>· {formatShortDate(item.modifiedAt)}</span> : null}\n\t\t\t</div>\n\t\t\t<ItemMeta item={item} renderItemMeta={renderItemMeta} view=\"grid\" />\n\t\t</article>\n\t)\n}\n\nfunction ItemMeta<TMetadata>({\n\titem,\n\trenderItemMeta,\n\tview\n}: {\n\titem: FileNode<TMetadata>\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\tview: FileBrowserView\n}) {\n\tif (!renderItemMeta) {\n\t\treturn null\n\t}\n\n\tconst content = renderItemMeta(item, { view })\n\treturn content === null || content === undefined || content === false ? null : (\n\t\t<div\n\t\t\tclassName=\"min-w-0 max-w-full text-[var(--fb-font-sm)] [overflow-wrap:anywhere] [&_*]:max-w-full\"\n\t\t\tdata-fb-item-meta={view}\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t)\n}\n\nfunction InlineRenameInput<TMetadata>({\n\terror,\n\titem,\n\tlabel,\n\tonCancel,\n\tonChange,\n\tonCommit,\n\tvalue\n}: {\n\terror: string | null\n\titem: FileNode<TMetadata>\n\tlabel: string\n\tonCancel: () => void\n\tonChange: (value: string) => void\n\tonCommit: () => void\n\tvalue: string\n}) {\n\treturn (\n\t\t<div className=\"min-w-0\">\n\t\t\t<input\n\t\t\t\taria-label={`Rename ${label || item.name}`}\n\t\t\t\tautoFocus\n\t\t\t\tclassName={`h-8 w-full min-w-0 rounded-[calc(var(--fb-radius)-4px)] border-[1.5px] border-[var(--fb-accent)] bg-[var(--fb-surface)] px-2 text-[calc(var(--fb-font)-1px)] text-[var(--fb-text)] outline-none ring-[3px] ring-[color-mix(in_oklch,var(--fb-accent)_15%,transparent)] [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] [@media(pointer:coarse)]:text-[16px] ${CONTROL_MOTION}`}\n\t\t\t\tonBlur={onCommit}\n\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\tonClick={(event) => event.stopPropagation()}\n\t\t\t\tonDoubleClick={(event) => event.stopPropagation()}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\tonCommit()\n\t\t\t\t\t}\n\t\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\tonCancel()\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\tvalue={value}\n\t\t\t/>\n\t\t\t{error ? (\n\t\t\t\t<div className={`mt-1 text-[var(--fb-font-sm)] text-[var(--fb-danger)] ${SURFACE_MOTION}`} role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t)\n}\n\nfunction FileTable<TMetadata>({\n\tbrowser,\n\tcanMove,\n\tfolderDropTargetPath,\n\tinlineRenameError,\n\tinlineRenameLabel,\n\tinlineRenameItem,\n\tinlineRenameValue,\n\tselectedPaths,\n\tonContextMenu,\n\tonDragEnd,\n\tonDragStart,\n\tonFolderDragOver,\n\tonFolderDrop,\n\tonInlineRenameCancel,\n\tonInlineRenameChange,\n\tonInlineRenameCommit,\n\tonOpenItem,\n\tonSelectItem,\n\tonTouchMenu,\n\tnarrow,\n\tselectionMode,\n\tonToggleItem,\n\trenderItemMeta,\n\trootLabel\n}: {\n\tbrowser: BrowserLike<TMetadata>\n\tcanMove: boolean\n\tfolderDropTargetPath: string | null\n\tinlineRenameError: string | null\n\tinlineRenameLabel: string\n\tinlineRenameItem: FileNode<TMetadata> | null\n\tinlineRenameValue: string\n\tselectedPaths: string[]\n\tonContextMenu: (item: FileNode<TMetadata>, event: MouseEvent) => void\n\tonDragEnd: () => void\n\tonDragStart: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonFolderDragOver: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonFolderDrop: (item: FileNode<TMetadata>, event: DragEvent) => void\n\tonInlineRenameCancel: () => void\n\tonInlineRenameChange: (value: string) => void\n\tonInlineRenameCommit: () => void\n\tonOpenItem: (item: FileNode<TMetadata>) => void\n\tonSelectItem: (path: string, event: MouseEvent) => void\n\tonTouchMenu: (item: FileNode<TMetadata>) => void\n\tnarrow: boolean\n\tselectionMode: boolean\n\tonToggleItem: (path: string) => void\n\trenderItemMeta?: (item: FileNode<TMetadata>, context: { view: FileBrowserView }) => ReactNode\n\trootLabel: string\n}) {\n\tconst disclosureSize = getDisclosureSize(narrow)\n\tconst headCell = `h-10 border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] text-[var(--fb-font-sm)] font-semibold text-[var(--fb-muted)]`\n\tconst bodyCell =\n\t\t'h-[var(--fb-row-h)] border-b border-[var(--fb-border)] px-[var(--fb-cell-x)] py-[calc(var(--fb-cell-y)/2)]'\n\treturn (\n\t\t<table\n\t\t\taria-label={rootLabel}\n\t\t\tclassName={`w-full table-fixed border-separate border-spacing-0 overflow-hidden rounded-[calc(var(--fb-radius)+2px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] text-left ${SURFACE_MOTION}`}\n\t\t>\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th className={headCell}>Name</th>\n\t\t\t\t\t{!narrow ? <th className={`${headCell} w-[140px] text-right`}>Size</th> : null}\n\t\t\t\t\t{!narrow ? <th className={`${headCell} w-[160px] text-right`}>Modified</th> : null}\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t{browser.listRows.map((row) => {\n\t\t\t\t\tif (row.type === 'status') {\n\t\t\t\t\t\treturn <FolderStatusRow browser={browser} key={`${row.parentPath}::status`} narrow={narrow} row={row} />\n\t\t\t\t\t}\n\t\t\t\t\tconst { item, depth, expanded } = row\n\t\t\t\t\tconst isSelected = selectedPaths.includes(item.path)\n\t\t\t\t\tconst isDropTarget = folderDropTargetPath === item.path\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TouchRow\n\t\t\t\t\t\t\taria-selected={isSelected}\n\t\t\t\t\t\t\tdata-fb-drop-target={isDropTarget ? 'true' : undefined}\n\t\t\t\t\t\t\tdata-fb-path={item.path}\n\t\t\t\t\t\t\tclassName={`group outline-none focus-visible:bg-[var(--fb-surface-2)] ${CONTROL_MOTION} ${\n\t\t\t\t\t\t\t\tisDropTarget\n\t\t\t\t\t\t\t\t\t? 'bg-[var(--fb-accent-soft)] ring-2 ring-inset ring-[var(--fb-accent)]'\n\t\t\t\t\t\t\t\t\t: isSelected\n\t\t\t\t\t\t\t\t\t\t? 'bg-[color-mix(in_oklch,var(--fb-accent-soft)_70%,var(--fb-surface))] shadow-[inset_3px_0_0_var(--fb-accent)]'\n\t\t\t\t\t\t\t\t\t\t: 'hover:bg-[color-mix(in_oklch,var(--fb-surface-2)_60%,var(--fb-surface))]'\n\t\t\t\t\t\t\t}`}\n\t\t\t\t\t\t\tdraggable={canMove && !narrow}\n\t\t\t\t\t\t\tonLongPress={() => onTouchMenu(item)}\n\t\t\t\t\t\t\tkey={item.path}\n\t\t\t\t\t\t\tonClick={(event) => onSelectItem(item.path, event)}\n\t\t\t\t\t\t\tonContextMenu={(event) => onContextMenu(item, event)}\n\t\t\t\t\t\t\tonDragEnd={onDragEnd}\n\t\t\t\t\t\t\tonDragOver={(event) => onFolderDragOver(item, event)}\n\t\t\t\t\t\t\tonDragStart={(event) => onDragStart(item, event)}\n\t\t\t\t\t\t\tonDrop={(event) => onFolderDrop(item, event)}\n\t\t\t\t\t\t\tonDoubleClick={() => onOpenItem(item)}\n\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<td className={bodyCell} style={depth > 0 ? { paddingInlineStart: treeIndent(depth) } : undefined}>\n\t\t\t\t\t\t\t\t<div className=\"flex min-w-0 items-center gap-2.5\">\n\t\t\t\t\t\t\t\t\t{selectionMode ? (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\taria-label={`Select ${item.name}`}\n\t\t\t\t\t\t\t\t\t\t\taria-pressed={isSelected}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"-ml-3 grid size-[calc(var(--fb-gap)*11)] shrink-0 place-items-center\"\n\t\t\t\t\t\t\t\t\t\t\tdata-fb-touch-control\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\tonToggleItem(item.path)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<SelectionMark selected={isSelected} visibleOnHover={false} />\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t) : !narrow ? (\n\t\t\t\t\t\t\t\t\t\t<SelectionMark selected={isSelected} />\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t{item.kind === 'folder' ? (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\taria-expanded={expanded}\n\t\t\t\t\t\t\t\t\t\t\taria-label={`${expanded ? 'Collapse' : 'Expand'} ${item.name}`}\n\t\t\t\t\t\t\t\t\t\t\tclassName={`grid shrink-0 place-items-center rounded-[calc(var(--fb-radius)-4px)] text-[var(--fb-muted)] hover:bg-[var(--fb-surface-2)] hover:text-[var(--fb-text)] ${FOCUS_RING} ${disclosureSize} ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\t\t\tdata-fb-touch-control\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\tbrowser.toggleFolder(item.path)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonDoubleClick={(event) => event.stopPropagation()}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<ChevronRight\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={`size-3.5 transition-transform duration-150 ease-out motion-reduce:transition-none ${expanded ? 'rotate-90' : ''}`}\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={2.5}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\" className={`shrink-0 ${disclosureSize}`} />\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t<FileTypeTile item={item} size=\"sm\" />\n\t\t\t\t\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t{inlineRenameItem?.path === item.path ? (\n\t\t\t\t\t\t\t\t\t\t\t<InlineRenameInput\n\t\t\t\t\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\t\t\t\t\terror={inlineRenameError}\n\t\t\t\t\t\t\t\t\t\t\t\tlabel={inlineRenameLabel}\n\t\t\t\t\t\t\t\t\t\t\t\tonCancel={onInlineRenameCancel}\n\t\t\t\t\t\t\t\t\t\t\t\tonChange={onInlineRenameChange}\n\t\t\t\t\t\t\t\t\t\t\t\tonCommit={onInlineRenameCommit}\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={inlineRenameValue}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={`block max-w-full truncate rounded-[4px] text-left text-[var(--fb-font)] font-medium outline-none [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)] ${narrow ? 'min-h-[calc(var(--fb-gap)*6)]' : ''} ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\t\tonSelectItem(item.path, event)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{item.name}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t<ItemMeta item={item} renderItemMeta={renderItemMeta} view=\"list\" />\n\t\t\t\t\t\t\t\t\t\t{narrow ? (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex flex-wrap gap-x-3 text-[var(--fb-font-sm)] text-[var(--fb-muted)]\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span>{item.kind === 'folder' ? 'Folder' : formatBytes(item.size ?? 0)}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t{item.modifiedAt ? <span>{new Date(item.modifiedAt).toLocaleDateString()}</span> : null}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t{!narrow ? (\n\t\t\t\t\t\t\t\t<td className={`${bodyCell} text-right text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]`}>\n\t\t\t\t\t\t\t\t\t{item.kind === 'folder' ? 'Folder' : formatBytes(item.size ?? 0)}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{!narrow ? (\n\t\t\t\t\t\t\t\t<td className={`${bodyCell} text-right text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]`}>\n\t\t\t\t\t\t\t\t\t{item.modifiedAt ? new Date(item.modifiedAt).toLocaleDateString() : '—'}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</TouchRow>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t</tbody>\n\t\t</table>\n\t)\n}\n\nfunction treeIndent(depth: number) {\n\treturn `calc(var(--fb-cell-x) + 18px * ${depth})`\n}\n\nfunction getDisclosureSize(narrow: boolean) {\n\treturn `size-5 [@media(pointer:coarse)]:size-[calc(var(--fb-gap)*11)] ${narrow ? 'size-[calc(var(--fb-gap)*11)]' : ''}`\n}\n\nfunction FolderStatusRow<TMetadata>({\n\tbrowser,\n\tnarrow,\n\trow\n}: {\n\tbrowser: BrowserLike<TMetadata>\n\tnarrow: boolean\n\trow: Extract<FileBrowserListRow<TMetadata>, { type: 'status' }>\n}) {\n\tconst linkButton = `rounded-[4px] font-semibold ${ACCENT_INK} hover:underline ${FOCUS_RING} ${CONTROL_MOTION}`\n\treturn (\n\t\t<tr data-fb-status-for={row.parentPath}>\n\t\t\t<td\n\t\t\t\tclassName=\"h-11 border-b border-[var(--fb-border)] bg-[color-mix(in_oklch,var(--fb-surface-2)_40%,var(--fb-surface))] px-[var(--fb-cell-x)] text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]\"\n\t\t\t\tcolSpan={narrow ? 1 : 3}\n\t\t\t\tstyle={{ paddingInlineStart: treeIndent(row.depth) }}\n\t\t\t>\n\t\t\t\t<div className=\"flex min-w-0 items-center gap-2\">\n\t\t\t\t\t{/* Same width as the item-row chevron so the status lines up with the child icons. */}\n\t\t\t\t\t<span aria-hidden=\"true\" className={`shrink-0 ${getDisclosureSize(narrow)}`} />\n\t\t\t\t\t{row.status === 'loading' ? (\n\t\t\t\t\t\t<span className=\"inline-flex items-center gap-2\" role=\"status\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\tclassName=\"size-3.5 animate-spin rounded-full border-2 border-[var(--fb-accent-soft)] border-t-[var(--fb-accent)] motion-reduce:animate-none\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\tLoading…\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : row.status === 'empty' ? (\n\t\t\t\t\t\t<span>Empty folder</span>\n\t\t\t\t\t) : row.status === 'more' ? (\n\t\t\t\t\t\t<button className={linkButton} onClick={() => browser.loadMoreFolder(row.parentPath)} type=\"button\">\n\t\t\t\t\t\t\tLoad more\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span className=\"text-[var(--fb-danger)]\">\n\t\t\t\t\t\t\t{row.error?.message ?? 'Could not load folder'}{' '}\n\t\t\t\t\t\t\t<button className={linkButton} onClick={() => browser.expandFolder(row.parentPath)} type=\"button\">\n\t\t\t\t\t\t\t\tRetry\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</td>\n\t\t</tr>\n\t)\n}\n\nfunction TouchRow({ onLongPress, ...props }: React.ComponentProps<'tr'> & { onLongPress: () => void }) {\n\tconst longPress = useLongPress(onLongPress)\n\treturn <tr {...props} {...longPress} />\n}\n\nfunction ContextMenu<TMetadata>({\n\tbrowser,\n\tcanDownload,\n\tmenu,\n\tonClose,\n\tonDelete,\n\tonDownload,\n\tonCopy,\n\tonCopyPath,\n\tonCut,\n\tonMove,\n\tonNewFolder,\n\tonPaste,\n\tonRename,\n\tonUpload,\n\treadOnly\n}: {\n\tbrowser: BrowserLike<TMetadata>\n\tcanDownload: boolean\n\tmenu: ContextMenuState<TMetadata>\n\tonClose: () => void\n\tonDelete: () => void\n\tonDownload: () => void\n\tonCopy: () => void\n\tonCopyPath: (item: FileNode<TMetadata>) => void\n\tonCut: () => void\n\tonMove: () => void\n\tonNewFolder: () => void\n\tonPaste: () => void\n\tonRename: (item?: FileNode<TMetadata>) => void\n\tonUpload: () => void\n\treadOnly: boolean\n}) {\n\tconst isItemMenu = menu.target === 'item'\n\tconst isSheet = menu.mode === 'sheet'\n\tconst menuRef = useRef<HTMLDivElement>(null)\n\tconst [position, setPosition] = useState({ left: menu.x, top: menu.y })\n\n\tuseEffect(() => {\n\t\tif (isSheet) return\n\t\tconst element = menuRef.current\n\t\tconst previousFocus = document.activeElement\n\t\tconst reposition = () => {\n\t\t\tconst gap = element ? (Number.parseFloat(getComputedStyle(element).paddingLeft) || 0) * 2 : 0\n\t\t\tconst rect = element?.getBoundingClientRect()\n\t\t\tsetPosition({\n\t\t\t\tleft: Math.max(gap, Math.min(menu.x, document.documentElement.clientWidth - (rect?.width ?? 0) - gap)),\n\t\t\t\ttop: Math.max(gap, Math.min(menu.y, window.innerHeight - (rect?.height ?? 0) - gap))\n\t\t\t})\n\t\t}\n\t\treposition()\n\t\telement?.querySelector<HTMLElement>('button')?.focus()\n\t\twindow.addEventListener('resize', reposition)\n\t\treturn () => {\n\t\t\twindow.removeEventListener('resize', reposition)\n\t\t\tif (previousFocus instanceof HTMLElement && previousFocus.isConnected)\n\t\t\t\tpreviousFocus.focus({ preventScroll: true })\n\t\t}\n\t}, [menu.x, menu.y, isSheet])\n\n\tfunction run(action: () => void) {\n\t\taction()\n\t\tonClose()\n\t}\n\n\tconst content = (\n\t\t<div\n\t\t\taria-label={isItemMenu ? 'Item actions' : 'Folder actions'}\n\t\t\tclassName={`flex flex-col bg-[var(--fb-surface)] text-[var(--fb-font)] text-[var(--fb-text)] ${SURFACE_MOTION} ${\n\t\t\t\tisSheet\n\t\t\t\t\t? 'w-full'\n\t\t\t\t\t: 'fixed z-[60] max-h-[calc(100dvh-var(--fb-gap)*4)] min-w-[200px] max-w-[calc(100%-var(--fb-gap)*4)] overflow-y-auto rounded-[calc(var(--fb-radius)+2px)] border border-[var(--fb-border)] p-1.5 shadow-[0_12px_32px_color-mix(in_oklch,var(--fb-text)_12%,transparent)]'\n\t\t\t}`}\n\t\t\tdata-fb-menu={isSheet ? 'sheet' : 'context'}\n\t\t\trole=\"menu\"\n\t\t\tref={menuRef}\n\t\t\tstyle={isSheet ? undefined : position}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key === 'Escape' || (event.key === 'Tab' && !isSheet)) {\n\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\tonClose()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return\n\t\t\t\tevent.preventDefault()\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tconst buttons = Array.from(event.currentTarget.querySelectorAll<HTMLButtonElement>('button'))\n\t\t\t\tconst index = buttons.indexOf(document.activeElement as HTMLButtonElement)\n\t\t\t\tconst next =\n\t\t\t\t\tevent.key === 'Home'\n\t\t\t\t\t\t? 0\n\t\t\t\t\t\t: event.key === 'End'\n\t\t\t\t\t\t\t? buttons.length - 1\n\t\t\t\t\t\t\t: (index + (event.key === 'ArrowDown' ? 1 : -1) + buttons.length) % buttons.length\n\t\t\t\tbuttons[next]?.focus()\n\t\t\t}}\n\t\t>\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.rename ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(() => onRename(menu.item))}>Rename</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.move ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(onMove)}>Move</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.copy ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(onCopy)}>Copy</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu && !readOnly && browser.capabilities.move ? (\n\t\t\t\t<ContextMenuButton onClick={() => run(onCut)}>Cut</ContextMenuButton>\n\t\t\t) : null}\n\t\t\t{isItemMenu ? (\n\t\t\t\t<>\n\t\t\t\t\t<ContextMenuButton onClick={() => run(() => onCopyPath(menu.item))}>\n\t\t\t\t\t\t{browser.selectedPaths.includes(menu.item.path) && browser.selectedPaths.length > 1\n\t\t\t\t\t\t\t? 'Copy paths'\n\t\t\t\t\t\t\t: 'Copy path'}\n\t\t\t\t\t</ContextMenuButton>\n\t\t\t\t\t{canDownload ? <ContextMenuButton onClick={() => run(onDownload)}>Download</ContextMenuButton> : null}\n\t\t\t\t\t{!readOnly ? <div aria-hidden=\"true\" className=\"mx-1.5 my-1 h-px bg-[var(--fb-border)]\" /> : null}\n\t\t\t\t\t{!readOnly ? (\n\t\t\t\t\t\t<ContextMenuButton\n\t\t\t\t\t\t\tdanger\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tonDelete()\n\t\t\t\t\t\t\t\tonClose()\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t</ContextMenuButton>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t{!readOnly ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{browser.capabilities.createFolder ? (\n\t\t\t\t\t\t\t\t<ContextMenuButton onClick={() => run(onNewFolder)}>New folder</ContextMenuButton>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<ContextMenuButton onClick={() => run(onUpload)}>Upload</ContextMenuButton>\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{!readOnly && browser.clipboard ? (\n\t\t\t\t\t\t<ContextMenuButton onClick={() => run(onPaste)}>Paste here</ContextMenuButton>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t)\n\treturn isSheet ? (\n\t\t<ActionSheet label={isItemMenu ? 'Item actions' : 'Folder actions'} onClose={onClose}>\n\t\t\t{content}\n\t\t</ActionSheet>\n\t) : (\n\t\tcontent\n\t)\n}\n\nfunction ContextMenuButton({ children, danger, onClick }: { children: string; danger?: boolean; onClick: () => void }) {\n\treturn (\n\t\t<button\n\t\t\tclassName={`flex min-h-9 w-full items-center rounded-[calc(var(--fb-radius)-2px)] px-2.5 text-left outline-none ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\t\t\tdanger\n\t\t\t\t\t? 'text-[var(--fb-danger)] hover:bg-[var(--fb-danger-soft)] focus:bg-[var(--fb-danger-soft)]'\n\t\t\t\t\t: 'hover:bg-[color-mix(in_oklch,var(--fb-accent-soft)_70%,var(--fb-surface))] focus:bg-[color-mix(in_oklch,var(--fb-accent-soft)_70%,var(--fb-surface))]'\n\t\t\t}`}\n\t\t\tonClick={onClick}\n\t\t\trole=\"menuitem\"\n\t\t\ttype=\"button\"\n\t\t>\n\t\t\t{children}\n\t\t</button>\n\t)\n}\n\nfunction UploadConflictDialog({\n\tapplyToAll,\n\tnarrow,\n\tcurrentPath,\n\tonApplyToAllChange,\n\tonCancel,\n\tonResolve,\n\tqueue,\n\tresolutions\n}: {\n\tapplyToAll: boolean\n\tnarrow: boolean\n\tcurrentPath: string\n\tonApplyToAllChange: (value: boolean) => void\n\tonCancel: () => void\n\tonResolve: (resolution: FileBrowserUploadConflictResolution) => void\n\tqueue: UploadConflictQueue\n\tresolutions: readonly FileBrowserUploadConflictResolution[]\n}) {\n\tconst candidate = queue.candidates[queue.index]\n\tconst path = joinUploadRelativePath(currentPath, candidate.relativePath)\n\tconst conflictIndex = queue.conflictPaths.indexOf(path) + 1\n\n\treturn (\n\t\t<ResponsiveDialog label=\"File conflict\" narrow={narrow} onClose={onCancel}>\n\t\t\t<div className={`${DIALOG_SURFACE} max-w-[480px]`}>\n\t\t\t\t<div className=\"flex items-baseline justify-between gap-3\">\n\t\t\t\t\t<h2 className={DIALOG_TITLE}>File conflict</h2>\n\t\t\t\t\t<span className=\"shrink-0 text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]\">\n\t\t\t\t\t\tConflict {conflictIndex} of {queue.conflictPaths.length}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t<p className={DIALOG_BODY}>{candidate.relativePath} already exists in this folder.</p>\n\t\t\t\t<div className=\"mt-4 flex min-w-0 flex-col gap-1 rounded-[var(--fb-radius)] border-[1.5px] border-[var(--fb-accent)] bg-[color-mix(in_oklch,var(--fb-accent-soft)_70%,var(--fb-surface))] p-3\">\n\t\t\t\t\t<span className={`text-[var(--fb-font-sm)] ${ACCENT_INK}`}>Uploading</span>\n\t\t\t\t\t<span className=\"truncate text-[var(--fb-font)] font-semibold\">{candidate.file.name}</span>\n\t\t\t\t\t<span className=\"text-[var(--fb-font-sm)] text-[var(--fb-muted)]\">{formatBytes(candidate.file.size)}</span>\n\t\t\t\t</div>\n\t\t\t\t<label className=\"mt-4 flex min-h-[calc(var(--fb-gap)*11)] items-center gap-2.5 text-[var(--fb-font)] @min-[40rem]/fb:min-h-0\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tchecked={applyToAll}\n\t\t\t\t\t\tclassName=\"size-[18px] accent-[var(--fb-accent)]\"\n\t\t\t\t\t\tonChange={(event) => onApplyToAllChange(event.target.checked)}\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t/>\n\t\t\t\t\tApply to all conflicts\n\t\t\t\t</label>\n\t\t\t\t<div\n\t\t\t\t\tclassName={`mt-6 flex flex-wrap justify-end gap-2 ${narrow ? 'flex-col [&>button]:w-full [&>button]:justify-center' : ''}`}\n\t\t\t\t>\n\t\t\t\t\t<button\n\t\t\t\t\t\tclassName={`${commandButton(false)} border-transparent bg-transparent text-[var(--fb-muted)]`}\n\t\t\t\t\t\tonClick={onCancel}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\tCancel\n\t\t\t\t\t</button>\n\t\t\t\t\t{resolutions.map((resolution) => (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tclassName={resolution === 'keep-both' ? primaryButton() : commandButton(false)}\n\t\t\t\t\t\t\tkey={resolution}\n\t\t\t\t\t\t\tonClick={() => onResolve(resolution)}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{formatUploadConflictResolution(resolution)}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</ResponsiveDialog>\n\t)\n}\n\nfunction BulkFailureDialog({\n\terror,\n\tnarrow,\n\tonClose\n}: {\n\terror: FileBrowserBulkActionError\n\tnarrow: boolean\n\tonClose: () => void\n}) {\n\tconst completedCount = error.succeededPaths.length\n\n\treturn (\n\t\t<ResponsiveDialog label=\"Partial bulk failure\" narrow={narrow} onClose={onClose}>\n\t\t\t<div className={`${DIALOG_SURFACE} max-w-[440px]`}>\n\t\t\t\t<div className=\"flex items-center gap-2.5\">\n\t\t\t\t\t<span aria-hidden=\"true\" className=\"size-2.5 shrink-0 rounded-full bg-[var(--fb-warn)]\" />\n\t\t\t\t\t<h2 className={DIALOG_TITLE}>Partial bulk failure</h2>\n\t\t\t\t</div>\n\t\t\t\t<p className={DIALOG_BODY}>\n\t\t\t\t\t{completedCount} of {error.totalCount} completed\n\t\t\t\t</p>\n\t\t\t\t<ul\n\t\t\t\t\tclassName={`m-0 mt-3 max-h-40 list-none overflow-auto rounded-[var(--fb-radius)] bg-[var(--fb-warn-soft)] px-3 py-2 text-[calc(var(--fb-font)-1px)] ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\t{error.failures.map((failure) => (\n\t\t\t\t\t\t<li className=\"flex min-w-0 flex-wrap justify-between gap-x-3 py-1\" key={failure.path}>\n\t\t\t\t\t\t\t<span className=\"min-w-0 truncate font-semibold\">\n\t\t\t\t\t\t\t\t{failure.path.split('/').filter(Boolean).at(-1) ?? failure.path}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span className=\"text-[color-mix(in_oklch,var(--fb-warn)_75%,var(--fb-text))]\">{failure.message}</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t\t<div className=\"mt-6 flex justify-end\">\n\t\t\t\t\t<button className={primaryButton()} onClick={onClose} type=\"button\">\n\t\t\t\t\t\tOK\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</ResponsiveDialog>\n\t)\n}\n\nfunction MoveDestinationPicker({\n\tcurrentPath,\n\tdestinations,\n\terror,\n\tonSelect,\n\trootLabel,\n\tselectedPath,\n\tstatus\n}: {\n\tcurrentPath: string\n\tdestinations: MoveDestination[]\n\terror: string | null\n\tonSelect: (path: string) => void\n\trootLabel: string\n\tselectedPath: string\n\tstatus: MoveDestinationStatus\n}) {\n\treturn (\n\t\t<div\n\t\t\tclassName={`mt-4 flex max-h-72 flex-col gap-px overflow-auto rounded-[var(--fb-radius)] border border-[var(--fb-border)] p-1.5 ${SURFACE_MOTION}`}\n\t\t>\n\t\t\t<MoveDestinationButton\n\t\t\t\tactive={selectedPath === currentPath}\n\t\t\t\tlabel=\"Current folder\"\n\t\t\t\tonClick={() => onSelect(currentPath)}\n\t\t\t\tpath={currentPath}\n\t\t\t/>\n\t\t\t<MoveDestinationButton active={selectedPath === '/'} label={rootLabel} onClick={() => onSelect('/')} path=\"/\" />\n\t\t\t{status === 'loading' ? (\n\t\t\t\t<div className=\"px-2.5 py-3 text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]\">Loading folders</div>\n\t\t\t) : null}\n\t\t\t{status === 'error' ? (\n\t\t\t\t<div className=\"px-2.5 py-3 text-[calc(var(--fb-font)-1px)] text-[var(--fb-danger)]\">\n\t\t\t\t\t{error ?? 'Could not load folders'}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{status === 'ready' && destinations.length === 0 ? (\n\t\t\t\t<div className=\"px-2.5 py-3 text-[calc(var(--fb-font)-1px)] text-[var(--fb-muted)]\">No folders available.</div>\n\t\t\t) : null}\n\t\t\t{destinations.map((destination) => (\n\t\t\t\t<MoveDestinationButton\n\t\t\t\t\tactive={selectedPath === destination.path}\n\t\t\t\t\tdepth={destination.depth}\n\t\t\t\t\tkey={destination.path}\n\t\t\t\t\tlabel={destination.name}\n\t\t\t\t\tonClick={() => onSelect(destination.path)}\n\t\t\t\t\tpath={destination.path}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t)\n}\n\nfunction MoveDestinationButton({\n\tactive,\n\tdepth = 0,\n\tlabel,\n\tonClick,\n\tpath\n}: {\n\tactive: boolean\n\tdepth?: number\n\tlabel: string\n\tonClick: () => void\n\tpath: string\n}) {\n\treturn (\n\t\t<button\n\t\t\taria-label={`Move destination ${path}`}\n\t\t\tclassName={`flex min-h-[34px] w-full min-w-0 items-center gap-2 rounded-[calc(var(--fb-radius)-2px)] pr-2 text-left text-[var(--fb-font)] ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\t\t\tactive ? `bg-[var(--fb-accent-soft)] font-semibold ${ACCENT_INK}` : 'hover:bg-[var(--fb-surface-2)]'\n\t\t\t}`}\n\t\t\tonClick={onClick}\n\t\t\tstyle={{ paddingLeft: `min(40%, calc(8px + 18px * ${depth}))` }}\n\t\t\ttype=\"button\"\n\t\t>\n\t\t\t<Folder\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tclassName={`size-4 shrink-0 fill-current ${active ? 'text-[var(--fb-accent)]' : 'text-[var(--fb-folder)]'}`}\n\t\t\t\tstrokeWidth={0}\n\t\t\t/>\n\t\t\t<span className=\"truncate\">{label}</span>\n\t\t</button>\n\t)\n}\n\nfunction ActionBar({\n\tselectedCount,\n\titemCount,\n\tcanRename,\n\tcanMove,\n\tcanCopy,\n\tcanCut,\n\tcanDelete,\n\tcanDownload,\n\tonRename,\n\tonMove,\n\tonCopy,\n\tonCut,\n\tonDelete,\n\tonDownload,\n\tonSelectAll,\n\tonSelectNone\n}: {\n\tselectedCount: number\n\titemCount: number\n\tcanRename: boolean\n\tcanMove: boolean\n\tcanCopy: boolean\n\tcanCut: boolean\n\tcanDelete: boolean\n\tcanDownload: boolean\n\tonRename: () => void\n\tonMove: () => void\n\tonCopy: () => void\n\tonCut: () => void\n\tonDelete: () => void\n\tonDownload: () => void\n\tonSelectAll: () => void\n\tonSelectNone: () => void\n}) {\n\tconst hasSelection = selectedCount > 0\n\n\treturn (\n\t\t<div\n\t\t\taria-label=\"Selection actions\"\n\t\t\tclassName={`flex min-h-[var(--fb-bar-h)] min-w-0 flex-wrap items-center gap-2 px-[var(--fb-pad)] py-2 text-[calc(var(--fb-font)-1px)] ${SURFACE_MOTION}`}\n\t\t\trole=\"toolbar\"\n\t\t>\n\t\t\t<span className={`mr-1 whitespace-nowrap font-semibold ${hasSelection ? ACCENT_INK : 'text-[var(--fb-muted)]'}`}>\n\t\t\t\t{selectedCount} selected\n\t\t\t</span>\n\t\t\t{hasSelection && canDownload ? (\n\t\t\t\t<button className={barButton()} onClick={onDownload} type=\"button\">\n\t\t\t\t\t<Download aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tDownload\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canRename && selectedCount === 1 ? (\n\t\t\t\t<button className={barButton()} onClick={() => onRename()} type=\"button\">\n\t\t\t\t\t<Pencil aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tRename\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canMove ? (\n\t\t\t\t<button className={barButton()} onClick={onMove} type=\"button\">\n\t\t\t\t\t<FolderInput aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tMove\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canCopy ? (\n\t\t\t\t<button className={barButton()} onClick={onCopy} type=\"button\">\n\t\t\t\t\t<CopyIcon aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tCopy\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canCut ? (\n\t\t\t\t<button className={barButton()} onClick={onCut} type=\"button\">\n\t\t\t\t\t<Scissors aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tCut\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{hasSelection && canDelete ? (\n\t\t\t\t<button className={barButton('danger')} onClick={onDelete} type=\"button\">\n\t\t\t\t\t<Trash2 aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tDelete\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t<span className=\"ml-auto flex items-center gap-1\">\n\t\t\t\t<button className={barButton('ghost')} disabled={itemCount === 0} onClick={onSelectAll} type=\"button\">\n\t\t\t\t\t<CheckSquare aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tSelect all\n\t\t\t\t</button>\n\t\t\t\t<button className={barButton('ghost')} disabled={!hasSelection} onClick={onSelectNone} type=\"button\">\n\t\t\t\t\t<XIcon aria-hidden=\"true\" className=\"size-3.5\" />\n\t\t\t\t\tSelect none\n\t\t\t\t</button>\n\t\t\t</span>\n\t\t</div>\n\t)\n}\n\nfunction Breadcrumbs({\n\tpath,\n\tonNavigate,\n\trootLabel,\n\tnarrow\n}: {\n\tpath: string\n\tonNavigate: (path: string) => Promise<void>\n\trootLabel: string\n\tnarrow: boolean\n}) {\n\tconst [ancestorsOpen, setAncestorsOpen] = useState(false)\n\tconst [fit, setFit] = useState<BreadcrumbFit | null>(null)\n\tconst listRef = useRef<HTMLDivElement>(null)\n\tconst measureRef = useRef<HTMLDivElement>(null)\n\tconst menuRef = useRef<HTMLSpanElement>(null)\n\tconst parts = path.split('/').filter(Boolean)\n\tconst crumbs: BreadcrumbCrumb[] = [{ label: rootLabel, path: '/' }].concat(\n\t\tparts.map((part, index) => ({\n\t\t\tlabel: part,\n\t\t\tpath: `/${parts.slice(0, index + 1).join('/')}`\n\t\t}))\n\t)\n\tconst layout = fit ? getFittedBreadcrumbs(crumbs, fit) : getFallbackBreadcrumbs(crumbs, narrow)\n\n\t// Show as much of the path as the row can hold: measure every crumb off-screen, then keep the root plus\n\t// as many trailing folders as fit, collapsing only the middle.\n\tuseLayoutEffect(() => {\n\t\tconst list = listRef.current\n\t\tconst measurer = measureRef.current\n\t\tif (!list || !measurer) return\n\t\tconst measure = () => {\n\t\t\tconst available = list.clientWidth\n\t\t\tif (available <= 0) return\n\t\t\tconst items = Array.from(measurer.querySelectorAll<HTMLElement>('[data-fb-crumb-measure]'))\n\t\t\tconst ellipsis = measurer.querySelector<HTMLElement>('[data-fb-crumb-ellipsis]')\n\t\t\tconst widths = items.map((item) => item.getBoundingClientRect().width + BREADCRUMB_GAP_PX)\n\t\t\tconst next = fitBreadcrumbs(widths, (ellipsis?.getBoundingClientRect().width ?? 0) + BREADCRUMB_GAP_PX, available)\n\t\t\tsetFit((current) => (current?.lead === next.lead && current.tail === next.tail ? current : next))\n\t\t}\n\t\tmeasure()\n\t\tif (typeof ResizeObserver === 'undefined') return\n\t\tconst observer = new ResizeObserver(() => measure())\n\t\tobserver.observe(list)\n\t\treturn () => observer.disconnect()\n\t}, [path, rootLabel])\n\n\tuseEffect(() => {\n\t\tif (!ancestorsOpen || narrow) return\n\t\tmenuRef.current?.querySelector<HTMLElement>('[role=\"menuitem\"]')?.focus()\n\t\tconst close = (event: PointerEvent) => {\n\t\t\tif (!menuRef.current?.contains(event.target as Node)) setAncestorsOpen(false)\n\t\t}\n\t\tdocument.addEventListener('pointerdown', close)\n\t\treturn () => document.removeEventListener('pointerdown', close)\n\t}, [ancestorsOpen, narrow])\n\n\tfunction navigateFromMenu(nextPath: string) {\n\t\tsetAncestorsOpen(false)\n\t\tvoid onNavigate(nextPath)\n\t}\n\n\tconst crumbText = `rounded-[calc(var(--fb-radius)-4px)] px-0.5 py-1 [@media(pointer:coarse)]:min-h-[calc(var(--fb-gap)*11)]`\n\n\treturn (\n\t\t<nav aria-label=\"Breadcrumb\" className=\"flex min-w-0 max-w-full items-center gap-1 text-[var(--fb-font)]\">\n\t\t\t{narrow && parts.length > 0 ? (\n\t\t\t\t<button\n\t\t\t\t\taria-label=\"Parent folder\"\n\t\t\t\t\tclassName={`${toolButton(false)} -ml-2 border-transparent bg-transparent text-[var(--fb-text)]`}\n\t\t\t\t\tonClick={() => void onNavigate(getFileBrowserDirname(path))}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<ChevronLeft aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t<div className=\"relative flex min-w-0 flex-1 items-center gap-1.5\" ref={listRef}>\n\t\t\t\t<div\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName=\"pointer-events-none invisible absolute left-0 top-0 flex h-0 items-center gap-1.5 overflow-hidden whitespace-nowrap\"\n\t\t\t\t\tref={measureRef}\n\t\t\t\t>\n\t\t\t\t\t{crumbs.map((crumb, index) => (\n\t\t\t\t\t\t<span className=\"flex shrink-0 items-center gap-1.5\" data-fb-crumb-measure key={crumb.path}>\n\t\t\t\t\t\t\t{index > 0 ? <ChevronRight className=\"size-3.5 shrink-0\" strokeWidth={2} /> : null}\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName={`${crumbText} block max-w-[240px] truncate ${index === crumbs.length - 1 ? 'font-semibold' : ''}`}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{crumb.label}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t))}\n\t\t\t\t\t<span className=\"flex shrink-0 items-center gap-1.5\" data-fb-crumb-ellipsis>\n\t\t\t\t\t\t<ChevronRight className=\"size-3.5 shrink-0\" strokeWidth={2} />\n\t\t\t\t\t\t<span className=\"inline-flex h-[26px] min-w-[26px] px-1.5\">…</span>\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t{layout.map((crumb, index) => (\n\t\t\t\t\t<span className=\"flex min-w-0 shrink-0 items-center gap-1.5 last:shrink last:grow\" key={crumb.key}>\n\t\t\t\t\t\t{index > 0 ? (\n\t\t\t\t\t\t\t<ChevronRight aria-hidden=\"true\" className=\"size-3.5 shrink-0 text-[var(--fb-muted)]\" strokeWidth={2} />\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{crumb.kind === 'collapsed' ? (\n\t\t\t\t\t\t\t<span className=\"relative inline-flex\" ref={menuRef}>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\taria-expanded={ancestorsOpen}\n\t\t\t\t\t\t\t\t\taria-haspopup={narrow ? 'dialog' : 'menu'}\n\t\t\t\t\t\t\t\t\taria-label=\"Collapsed breadcrumb\"\n\t\t\t\t\t\t\t\t\tclassName={`inline-flex h-[26px] min-w-[26px] items-center justify-center rounded-[calc(var(--fb-radius)-4px)] px-1.5 text-[calc(var(--fb-font)-1px)] hover:text-[var(--fb-text)] ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\t\t\t\t\t\t\t\t\tancestorsOpen && !narrow\n\t\t\t\t\t\t\t\t\t\t\t? `bg-[var(--fb-accent-soft)] ${ACCENT_INK}`\n\t\t\t\t\t\t\t\t\t\t\t: 'bg-[var(--fb-surface-2)] text-[var(--fb-muted)]'\n\t\t\t\t\t\t\t\t\t}`}\n\t\t\t\t\t\t\t\t\tonClick={() => setAncestorsOpen((open) => !open)}\n\t\t\t\t\t\t\t\t\ttitle={`${crumb.hidden.length} hidden ${crumb.hidden.length === 1 ? 'folder' : 'folders'}`}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t…\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t{ancestorsOpen && !narrow ? (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\taria-label=\"Hidden folders\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"absolute left-0 top-[calc(100%+6px)] z-50 flex max-h-[min(360px,60dvh)] w-max min-w-[200px] max-w-[min(420px,80vw)] flex-col overflow-y-auto rounded-[calc(var(--fb-radius)+2px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-1.5 shadow-[0_12px_32px_color-mix(in_oklch,var(--fb-text)_12%,transparent)]\"\n\t\t\t\t\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\t\t\t\t\tif (event.key === 'Escape' || event.key === 'Tab') {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\tsetAncestorsOpen(false)\n\t\t\t\t\t\t\t\t\t\t\t\tif (event.key === 'Escape') menuRef.current?.querySelector<HTMLElement>('button')?.focus()\n\t\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (!['ArrowDown', 'ArrowUp'].includes(event.key)) return\n\t\t\t\t\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\tconst items = Array.from(event.currentTarget.querySelectorAll<HTMLElement>('[role=\"menuitem\"]'))\n\t\t\t\t\t\t\t\t\t\t\tconst index = items.indexOf(document.activeElement as HTMLElement)\n\t\t\t\t\t\t\t\t\t\t\titems[(index + (event.key === 'ArrowDown' ? 1 : -1) + items.length) % items.length]?.focus()\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\trole=\"menu\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{crumb.hidden.map((hidden, depth) => (\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={`flex min-h-9 w-full min-w-0 items-center gap-2 rounded-[calc(var(--fb-radius)-2px)] pr-2.5 text-left outline-none hover:bg-[color-mix(in_oklch,var(--fb-accent-soft)_70%,var(--fb-surface))] focus:bg-[color-mix(in_oklch,var(--fb-accent-soft)_70%,var(--fb-surface))] ${CONTROL_MOTION}`}\n\t\t\t\t\t\t\t\t\t\t\t\tkey={hidden.path}\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => navigateFromMenu(hidden.path)}\n\t\t\t\t\t\t\t\t\t\t\t\trole=\"menuitem\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{ paddingLeft: `calc(10px + 12px * ${Math.min(depth, 6)})` }}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={hidden.label}\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<Folder\n\t\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-4 shrink-0 fill-current text-[var(--fb-folder)]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={0}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{hidden.label}</span>\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\taria-current={index === layout.length - 1 ? 'page' : undefined}\n\t\t\t\t\t\t\t\tclassName={`${crumbText} min-w-0 truncate hover:text-[var(--fb-text)] ${FOCUS_RING} ${CONTROL_MOTION} ${\n\t\t\t\t\t\t\t\t\tindex === layout.length - 1\n\t\t\t\t\t\t\t\t\t\t? 'font-semibold text-[var(--fb-text)]'\n\t\t\t\t\t\t\t\t\t\t: 'max-w-[240px] text-[var(--fb-muted)]'\n\t\t\t\t\t\t\t\t}`}\n\t\t\t\t\t\t\t\tonClick={() => void onNavigate(crumb.path)}\n\t\t\t\t\t\t\t\ttitle={crumb.label}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{crumb.label}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</span>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t\t{ancestorsOpen && narrow ? (\n\t\t\t\t<ActionSheet label=\"Folder path\" onClose={() => setAncestorsOpen(false)}>\n\t\t\t\t\t<div className=\"flex min-w-0 flex-col\">\n\t\t\t\t\t\t{crumbs.map((crumb) => (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tkey={crumb.path}\n\t\t\t\t\t\t\t\tclassName={`${commandButton(false)} my-[var(--fb-gap)] block w-full truncate text-left`}\n\t\t\t\t\t\t\t\tonClick={() => navigateFromMenu(crumb.path)}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{crumb.label}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</ActionSheet>\n\t\t\t) : null}\n\t\t</nav>\n\t)\n}\n\nconst BREADCRUMB_GAP_PX = 6\n\ntype BreadcrumbCrumb = {\n\tlabel: string\n\tpath: string\n}\n\ntype BreadcrumbFit = {\n\tlead: number\n\ttail: number\n}\n\ntype VisibleBreadcrumbCrumb =\n\t| (BreadcrumbCrumb & {\n\t\t\tkind: 'crumb'\n\t\t\tkey: string\n\t })\n\t| {\n\t\t\tkind: 'collapsed'\n\t\t\tkey: string\n\t\t\thidden: BreadcrumbCrumb[]\n\t }\n\n// widths include the separator and gap each crumb brings; lead/tail count crumbs kept at each end.\nfunction fitBreadcrumbs(widths: number[], ellipsisWidth: number, available: number): BreadcrumbFit {\n\tconst count = widths.length\n\tif (widths.reduce((total, width) => total + width, 0) <= available) return { lead: count, tail: 0 }\n\tlet used = widths[0] + ellipsisWidth + widths[count - 1]\n\tlet tail = 1\n\twhile (tail < count - 2 && used + widths[count - 1 - tail] <= available) {\n\t\tused += widths[count - 1 - tail]\n\t\ttail += 1\n\t}\n\tlet lead = 1\n\twhile (lead + tail < count - 1 && used + widths[lead] <= available) {\n\t\tused += widths[lead]\n\t\tlead += 1\n\t}\n\treturn { lead, tail }\n}\n\nfunction getFittedBreadcrumbs(crumbs: BreadcrumbCrumb[], fit: BreadcrumbFit): VisibleBreadcrumbCrumb[] {\n\tconst toVisible = (crumb: BreadcrumbCrumb) => ({ ...crumb, kind: 'crumb' as const, key: crumb.path })\n\tif (fit.lead + fit.tail >= crumbs.length) return crumbs.map(toVisible)\n\treturn [\n\t\t...crumbs.slice(0, fit.lead).map(toVisible),\n\t\t{ kind: 'collapsed', key: 'collapsed', hidden: crumbs.slice(fit.lead, crumbs.length - fit.tail) },\n\t\t...crumbs.slice(crumbs.length - fit.tail).map(toVisible)\n\t]\n}\n\n// Used before layout can be measured (first paint, non-DOM environments).\nfunction getFallbackBreadcrumbs(crumbs: BreadcrumbCrumb[], narrow: boolean): VisibleBreadcrumbCrumb[] {\n\tif (narrow && crumbs.length > 1) {\n\t\treturn [\n\t\t\t{ kind: 'collapsed', key: 'collapsed', hidden: crumbs.slice(0, -1) },\n\t\t\t{ ...crumbs[crumbs.length - 1], kind: 'crumb', key: crumbs[crumbs.length - 1].path }\n\t\t]\n\t}\n\treturn crumbs.length <= 4\n\t\t? getFittedBreadcrumbs(crumbs, { lead: crumbs.length, tail: 0 })\n\t\t: getFittedBreadcrumbs(crumbs, { lead: 2, tail: 2 })\n}\n\nfunction DetailsPanel<TMetadata>({\n\tcanDownload,\n\titem,\n\tonCopyPath,\n\tonDownload,\n\trenderDetailsContent,\n\tselectedCount,\n\ttotalBytes,\n\tsheet\n}: {\n\tcanDownload: boolean\n\titem: FileNode<TMetadata> | null\n\tonCopyPath: () => void\n\tonDownload: () => void\n\trenderDetailsContent?: (item: FileNode<TMetadata>, defaultContent: ReactNode) => ReactNode\n\tselectedCount: number\n\ttotalBytes: number\n\tsheet: boolean\n}) {\n\tconst panelClass = `flex min-w-0 max-w-full shrink-0 flex-col gap-4 bg-[var(--fb-surface)] [overflow-wrap:anywhere] [&_*]:max-w-full ${SURFACE_MOTION} ${\n\t\tsheet ? 'w-full' : 'w-[var(--fb-panel-w)] border-l border-[var(--fb-border)] p-[var(--fb-panel-pad)]'\n\t}`\n\tconst eyebrow = sheet ? null : (\n\t\t<div className=\"text-[calc(var(--fb-font)-1px)] font-semibold text-[var(--fb-muted)]\">Details</div>\n\t)\n\tconst fieldList = 'm-0 grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-2.5 text-[calc(var(--fb-font)-1px)]'\n\tconst panelButton = `${commandButton(false)} w-full`\n\tif (!item) {\n\t\treturn (\n\t\t\t<aside aria-label=\"Details\" className={panelClass}>\n\t\t\t\t{eyebrow}\n\t\t\t\t<div className=\"flex flex-1 flex-col items-center justify-center gap-3 text-center\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={`grid h-[150px] w-full place-items-center rounded-[var(--fb-radius)] bg-[var(--fb-surface-2)] text-[var(--fb-muted)] ${SURFACE_MOTION}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Info aria-hidden=\"true\" className=\"size-10\" strokeWidth={1.5} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<h2 className=\"m-0 text-[var(--fb-font)] font-semibold\">No item selected</h2>\n\t\t\t\t</div>\n\t\t\t</aside>\n\t\t)\n\t}\n\n\tif (selectedCount > 1) {\n\t\treturn (\n\t\t\t<aside aria-label=\"Details\" className={panelClass}>\n\t\t\t\t{eyebrow}\n\t\t\t\t<div\n\t\t\t\t\tclassName={`grid h-[150px] place-items-center rounded-[var(--fb-radius)] bg-[var(--fb-accent-soft)] ${ACCENT_INK} ${SURFACE_MOTION}`}\n\t\t\t\t>\n\t\t\t\t\t<CopyIcon aria-hidden=\"true\" className=\"size-10\" strokeWidth={1.5} />\n\t\t\t\t</div>\n\t\t\t\t<h2 className=\"m-0 text-[16px] font-bold\">{formatItemCount(selectedCount)} selected</h2>\n\t\t\t\t<dl className={fieldList}>\n\t\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Total size</dt>\n\t\t\t\t\t<dd className=\"m-0 font-medium\">{formatBytes(totalBytes)}</dd>\n\t\t\t\t</dl>\n\t\t\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t\t\t{canDownload ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label={`Download ${formatItemCount(selectedCount)}`}\n\t\t\t\t\t\t\tclassName={panelButton}\n\t\t\t\t\t\t\tonClick={onDownload}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Download aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\t\tDownload\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<button\n\t\t\t\t\t\taria-label={`Copy ${formatItemCount(selectedCount)} paths`}\n\t\t\t\t\t\tclassName={panelButton}\n\t\t\t\t\t\tonClick={onCopyPath}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<CopyIcon aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\tCopy paths\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</aside>\n\t\t)\n\t}\n\n\tconst defaultContent = (\n\t\t<>\n\t\t\t<FileTypeTile item={item} size=\"lg\" />\n\t\t\t<h2 className=\"m-0 truncate text-[16px] font-bold\">{item.name}</h2>\n\t\t\t<dl className={fieldList}>\n\t\t\t\t{item.kind === 'file' ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Size</dt>\n\t\t\t\t\t\t<dd className=\"m-0 font-medium\">{formatBytes(item.size ?? 0)}</dd>\n\t\t\t\t\t</>\n\t\t\t\t) : null}\n\t\t\t\t{item.modifiedAt ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Modified</dt>\n\t\t\t\t\t\t<dd className=\"m-0 font-medium\">{new Date(item.modifiedAt).toLocaleDateString()}</dd>\n\t\t\t\t\t</>\n\t\t\t\t) : null}\n\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Type</dt>\n\t\t\t\t<dd className=\"m-0 font-medium\">{item.kind === 'file' && item.mimeType ? item.mimeType : item.kind}</dd>\n\t\t\t\t<dt className=\"text-[var(--fb-muted)]\">Path</dt>\n\t\t\t\t<dd className=\"m-0 font-medium [overflow-wrap:anywhere]\">{item.path}</dd>\n\t\t\t</dl>\n\t\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t\t{canDownload ? (\n\t\t\t\t\t<button aria-label={`Download ${item.name}`} className={panelButton} onClick={onDownload} type=\"button\">\n\t\t\t\t\t\t<Download aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\t\tDownload\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t\t<button aria-label={`Copy path of ${item.name}`} className={panelButton} onClick={onCopyPath} type=\"button\">\n\t\t\t\t\t<CopyIcon aria-hidden=\"true\" className=\"size-4\" />\n\t\t\t\t\tCopy path\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</>\n\t)\n\n\treturn (\n\t\t<aside aria-label=\"Details\" className={panelClass}>\n\t\t\t{eyebrow}\n\t\t\t{renderDetailsContent ? renderDetailsContent(item, defaultContent) : defaultContent}\n\t\t</aside>\n\t)\n}\n\nfunction PreviewOriginalLink<TMetadata>({ preview }: { preview: PreviewState<TMetadata> }) {\n\tif (!preview.url) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<a\n\t\t\taria-label={`Open original ${preview.item.name}`}\n\t\t\tclassName={`${primaryButton()} no-underline`}\n\t\t\thref={preview.url}\n\t\t\trel=\"noreferrer\"\n\t\t\ttarget=\"_blank\"\n\t\t>\n\t\t\tOpen original\n\t\t</a>\n\t)\n}\n\nfunction SkeletonGrid({ rootLabel }: { rootLabel: string }) {\n\treturn (\n\t\t<div\n\t\t\taria-label={rootLabel}\n\t\t\tclassName=\"grid min-w-0 grid-cols-[repeat(2,minmax(0,1fr))] gap-[calc(var(--fb-grid-gap)-4px)] @min-[40rem]/fb:grid-cols-[repeat(auto-fill,minmax(min(100%,var(--fb-card-min)),1fr))] @min-[40rem]/fb:gap-[var(--fb-grid-gap)]\"\n\t\t\trole=\"grid\"\n\t\t>\n\t\t\t{Array.from({ length: 10 }, (_, index) => (\n\t\t\t\t<div\n\t\t\t\t\tclassName={`flex min-h-[var(--fb-card-minh)] animate-pulse flex-col gap-2 rounded-[calc(var(--fb-radius)+2px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-[var(--fb-card-pad)] motion-reduce:animate-none ${SURFACE_MOTION}`}\n\t\t\t\t\tkey={index}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"h-[var(--fb-thumb-h)] rounded-[calc(var(--fb-radius)-2px)] bg-[var(--fb-surface-2)]\" />\n\t\t\t\t\t<div className=\"mt-1 h-2.5 w-4/5 rounded-full bg-[var(--fb-surface-2)]\" />\n\t\t\t\t\t<div className=\"h-2 w-1/2 rounded-full bg-[color-mix(in_oklch,var(--fb-surface-2)_60%,var(--fb-surface))]\" />\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t)\n}\n\nfunction StateMessage({\n\ticon,\n\ttitle,\n\tvalue\n}: {\n\ticon: 'folder' | 'error' | 'lock'\n\ttitle: ReactNode\n\tvalue?: ReactNode\n}) {\n\treturn (\n\t\t<div\n\t\t\tclassName={`grid min-h-[min(320px,50svh)] min-w-0 place-items-center rounded-[calc(var(--fb-radius)+4px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-6 text-center [overflow-wrap:anywhere] [&_*]:max-w-full ${SURFACE_MOTION}`}\n\t\t>\n\t\t\t<div className=\"flex max-w-[340px] flex-col items-center gap-3\">\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName={`grid size-16 place-items-center ${\n\t\t\t\t\t\ticon === 'folder'\n\t\t\t\t\t\t\t? `rounded-[16px] ${FILE_TONE_CLASSES.folder}`\n\t\t\t\t\t\t\t: icon === 'lock'\n\t\t\t\t\t\t\t\t? 'rounded-full bg-[var(--fb-warn-soft)] text-[color-mix(in_oklch,var(--fb-warn)_80%,var(--fb-text))]'\n\t\t\t\t\t\t\t\t: 'rounded-full bg-[var(--fb-danger-soft)] text-[var(--fb-danger)]'\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t{icon === 'folder' ? (\n\t\t\t\t\t\t<Folder className=\"size-[30px] fill-current\" strokeWidth={0} />\n\t\t\t\t\t) : icon === 'lock' ? (\n\t\t\t\t\t\t<Lock className=\"size-[26px]\" strokeWidth={2} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<CircleAlert className=\"size-7\" strokeWidth={2} />\n\t\t\t\t\t)}\n\t\t\t\t</span>\n\t\t\t\t<div className=\"text-[17px] font-bold\">{title}</div>\n\t\t\t\t{value === undefined ? null : (\n\t\t\t\t\t<div className=\"text-[var(--fb-font)] leading-relaxed text-[var(--fb-muted)]\">{value}</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction UploadRejectionAlert({\n\tonDismiss,\n\trejections\n}: {\n\tonDismiss: () => void\n\trejections: FileBrowserUploadRejection[]\n}) {\n\treturn (\n\t\t<div\n\t\t\taria-label=\"Upload rejected\"\n\t\t\tclassName=\"mx-[var(--fb-pad)] mb-2 min-w-0 rounded-[calc(var(--fb-radius)+2px)] border border-[var(--fb-border)] bg-[var(--fb-surface)] p-4 text-[calc(var(--fb-font)-1px)] text-[var(--fb-text)] [overflow-wrap:anywhere]\"\n\t\t\trole=\"alert\"\n\t\t>\n\t\t\t<div className=\"flex items-start gap-3\">\n\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t<div className=\"text-[var(--fb-font)] font-bold\">Upload rejected</div>\n\t\t\t\t\t<ul className=\"m-0 mt-2 flex list-none flex-col gap-2 p-0\">\n\t\t\t\t\t\t{rejections.map((rejection) => (\n\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\tclassName=\"flex min-w-0 flex-col gap-0.5 rounded-[calc(var(--fb-radius)-2px)] bg-[var(--fb-danger-soft)] px-2.5 py-2\"\n\t\t\t\t\t\t\t\tkey={rejection.relativePath}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"font-semibold\">{rejection.relativePath}</span>\n\t\t\t\t\t\t\t\t<span className=\"text-[color-mix(in_oklch,var(--fb-danger)_80%,var(--fb-text))]\">\n\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\t{rejection.reasons.join('; ')}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<button aria-label=\"Dismiss upload rejection\" className={barButton()} onClick={onDismiss} type=\"button\">\n\t\t\t\t\tDismiss\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction selectWithEvent<TMetadata>(\n\tbrowser: BrowserLike<TMetadata>,\n\tpath: string,\n\tevent: MouseEvent | KeyboardEvent,\n\toptions: {\n\t\tcancelPendingSelectedItemUnselect: () => void\n\t\tscheduleSelectedItemUnselect: (path: string) => void\n\t}\n) {\n\tif ('shiftKey' in event && event.shiftKey) {\n\t\toptions.cancelPendingSelectedItemUnselect()\n\t\tbrowser.selectRange(path)\n\t} else if ('metaKey' in event && (event.metaKey || event.ctrlKey)) {\n\t\toptions.cancelPendingSelectedItemUnselect()\n\t\tbrowser.toggleSelection(path)\n\t} else if (browser.selectedPaths.length === 1 && browser.selectedPaths[0] === path) {\n\t\toptions.scheduleSelectedItemUnselect(path)\n\t} else {\n\t\toptions.cancelPendingSelectedItemUnselect()\n\t\tbrowser.selectOnly(path)\n\t}\n}\n\nfunction hasSelectionModifier(event: MouseEvent | KeyboardEvent): boolean {\n\treturn Boolean('shiftKey' in event && (event.shiftKey || event.metaKey || event.ctrlKey))\n}\n\nfunction isKeyboardNavigationKey(key: string) {\n\treturn ['ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'End', 'Home'].includes(key)\n}\n\nfunction getNextKeyboardIndex(key: string, currentIndex: number, length: number) {\n\tif (key === 'Home') {\n\t\treturn 0\n\t}\n\tif (key === 'End') {\n\t\treturn length - 1\n\t}\n\tif (key === 'ArrowUp' || key === 'ArrowLeft') {\n\t\treturn Math.max(0, currentIndex - 1)\n\t}\n\treturn Math.min(length - 1, currentIndex + 1)\n}\n\nfunction escapeAttributeSelector(value: string) {\n\tif (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n\t\treturn CSS.escape(value)\n\t}\n\n\treturn value.replace(/[\"\\\\]/g, '\\\\$&')\n}\n\nfunction getDraggedPaths(dataTransfer: DataTransfer) {\n\tif (typeof dataTransfer.getData !== 'function') {\n\t\treturn []\n\t}\n\n\tconst raw = dataTransfer.getData(FILE_BROWSER_DRAG_MIME)\n\tif (!raw) {\n\t\treturn []\n\t}\n\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown\n\t\tif (!Array.isArray(parsed)) {\n\t\t\treturn []\n\t\t}\n\t\treturn parsed.filter((path): path is string => typeof path === 'string').map(normalizeFileBrowserPath)\n\t} catch {\n\t\treturn []\n\t}\n}\n\nfunction getErrorState(error: Error | null) {\n\tif (isAccessDeniedError(error)) {\n\t\treturn {\n\t\t\ttitle: 'Access denied',\n\t\t\tvalue: error?.message ?? 'You do not have access to this folder.'\n\t\t}\n\t}\n\n\treturn {\n\t\ttitle: 'Could not load this folder',\n\t\tvalue: error?.message ?? 'Unknown error'\n\t}\n}\n\nfunction isAccessDeniedError(error: Error | null) {\n\tif (!error) {\n\t\treturn false\n\t}\n\n\tconst metadata = error as Error & {\n\t\tcode?: unknown\n\t\tstatus?: unknown\n\t\tstatusCode?: unknown\n\t}\n\treturn (\n\t\tmetadata.status === 403 ||\n\t\tmetadata.statusCode === 403 ||\n\t\tmetadata.code === 'access_denied' ||\n\t\tmetadata.code === 'forbidden' ||\n\t\tmetadata.code === 'permission_denied'\n\t)\n}\n\nfunction toErrorMessage(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error)\n}\n\nfunction isEditableEventTarget(target: EventTarget | null): boolean {\n\tif (!(target instanceof HTMLElement)) {\n\t\treturn false\n\t}\n\n\treturn target.isContentEditable || ['INPUT', 'SELECT', 'TEXTAREA'].includes(target.tagName)\n}\n\nfunction formatBytes(bytes: number) {\n\tif (bytes < 1024) {\n\t\treturn `${bytes} B`\n\t}\n\tconst kib = bytes / 1024\n\tif (kib < 1024) {\n\t\treturn `${kib.toFixed(1)} KB`\n\t}\n\treturn `${(kib / 1024).toFixed(1)} MB`\n}\n\nfunction formatItemCount(count: number) {\n\treturn `${count} ${count === 1 ? 'item' : 'items'}`\n}\n\nfunction normalizeUploadConflictResolutions(resolutions: readonly FileBrowserUploadConflictResolution[]) {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\tresolutions.filter((resolution) =>\n\t\t\t\tDEFAULT_UPLOAD_CONFLICT_RESOLUTIONS.includes(resolution as (typeof DEFAULT_UPLOAD_CONFLICT_RESOLUTIONS)[number])\n\t\t\t)\n\t\t)\n\t)\n}\n\nfunction formatUploadConflictResolution(resolution: FileBrowserUploadConflictResolution) {\n\tif (resolution === 'keep-both') {\n\t\treturn 'Keep both'\n\t}\n\treturn resolution === 'replace' ? 'Replace' : 'Skip'\n}\n\nfunction canDownloadItems<TMetadata>(items: FileNode<TMetadata>[], supportsBulkDownload: boolean) {\n\treturn items.length === 1 && items[0].kind === 'file' ? true : items.length > 0 && supportsBulkDownload\n}\n\nfunction formatScreenReaderStatus({\n\tcurrentPath,\n\titemCount,\n\trootLabel,\n\tselectedCount,\n\tstatus\n}: {\n\tcurrentPath: string\n\titemCount: number\n\trootLabel: string\n\tselectedCount: number\n\tstatus: string\n}) {\n\tconst folderName = currentPath === '/' ? rootLabel : (currentPath.split('/').filter(Boolean).at(-1) ?? rootLabel)\n\treturn `${folderName} ${status}. ${itemCount} ${itemCount === 1 ? 'item' : 'items'}. ${selectedCount} selected.`\n}\n\nconst FOCUS_RING =\n\t'outline-none focus-visible:ring-[3px] focus-visible:ring-[color-mix(in_oklch,var(--fb-accent)_22%,transparent)]'\n\nfunction toolButton(active: boolean) {\n\treturn `inline-flex h-[var(--fb-control-h)] min-w-[var(--fb-control-h)] items-center justify-center gap-1.5 rounded-[var(--fb-radius)] border px-2.5 text-[var(--fb-font)] font-medium disabled:opacity-45 ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\tactive\n\t\t\t? `border-[var(--fb-accent)] bg-[var(--fb-accent-soft)] ${ACCENT_INK}`\n\t\t\t: 'border-[var(--fb-border)] bg-[var(--fb-surface)] text-[var(--fb-muted)] hover:bg-[var(--fb-surface-2)] hover:text-[var(--fb-text)]'\n\t}`\n}\n\nfunction segmentButton(active: boolean) {\n\treturn `inline-flex h-[calc(var(--fb-control-h)-2px)] w-11 items-center justify-center ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\tactive\n\t\t\t? `bg-[var(--fb-accent-soft)] ${ACCENT_INK}`\n\t\t\t: 'bg-transparent text-[var(--fb-muted)] hover:bg-[var(--fb-surface-2)] hover:text-[var(--fb-text)]'\n\t}`\n}\n\nfunction commandButton(active: boolean) {\n\treturn `inline-flex h-[var(--fb-control-h)] items-center justify-center gap-2 rounded-[var(--fb-radius)] border px-3.5 text-[var(--fb-font)] font-semibold disabled:cursor-not-allowed disabled:opacity-45 ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\tactive\n\t\t\t? `border-[var(--fb-accent)] bg-[var(--fb-accent-soft)] ${ACCENT_INK}`\n\t\t\t: 'border-[var(--fb-border)] bg-[var(--fb-surface)] text-[var(--fb-text)] hover:bg-[var(--fb-surface-2)]'\n\t}`\n}\n\nfunction barButton(tone: 'default' | 'danger' | 'ghost' = 'default') {\n\treturn `inline-flex h-[var(--fb-bar-control-h)] items-center gap-1.5 rounded-[calc(var(--fb-radius)-2px)] px-3 text-[calc(var(--fb-font)-1px)] disabled:cursor-not-allowed disabled:opacity-45 ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION} ${\n\t\ttone === 'ghost'\n\t\t\t? 'border border-transparent bg-transparent text-[var(--fb-muted)] hover:text-[var(--fb-text)]'\n\t\t\t: tone === 'danger'\n\t\t\t\t? 'border border-[color-mix(in_oklch,var(--fb-danger)_25%,var(--fb-border))] bg-[var(--fb-surface)] text-[var(--fb-danger)] hover:bg-[var(--fb-danger-soft)]'\n\t\t\t\t: 'border border-[var(--fb-border)] bg-[var(--fb-surface)] text-[var(--fb-text)] hover:bg-[var(--fb-surface-2)]'\n\t}`\n}\n\nfunction primaryButton() {\n\treturn `inline-flex h-[var(--fb-control-h)] items-center justify-center gap-2 rounded-[var(--fb-radius)] border border-transparent bg-[var(--fb-accent)] px-4 text-[var(--fb-font)] font-semibold text-[var(--fb-surface)] hover:bg-[color-mix(in_oklch,var(--fb-accent)_88%,var(--fb-text))] disabled:cursor-not-allowed disabled:opacity-45 ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION}`\n}\n\nfunction dangerButton() {\n\treturn `inline-flex h-[var(--fb-control-h)] items-center justify-center gap-2 rounded-[var(--fb-radius)] border border-transparent bg-[var(--fb-danger)] px-4 text-[var(--fb-font)] font-semibold text-[var(--fb-surface)] hover:bg-[color-mix(in_oklch,var(--fb-danger)_88%,var(--fb-text))] ${FOCUS_RING} ${TOUCH_CONTROL} ${CONTROL_MOTION}`\n}\n\n// Native select arrows sit flush against the edge and differ per browser, so the chevron is drawn by us.\nfunction SelectField(props: React.ComponentProps<'select'>) {\n\treturn (\n\t\t<span className=\"relative inline-flex min-w-0 max-w-full shrink-0\">\n\t\t\t<select {...props} className={selectInput()} />\n\t\t\t<ChevronDown\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tclassName=\"pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-[var(--fb-muted)]\"\n\t\t\t\tstrokeWidth={2}\n\t\t\t/>\n\t\t</span>\n\t)\n}\n\nfunction selectInput() {\n\treturn `h-[var(--fb-control-h)] min-w-0 max-w-full appearance-none rounded-[var(--fb-radius)] border border-[var(--fb-border)] bg-[var(--fb-surface)] pl-3 pr-9 text-[var(--fb-font)] font-medium text-[var(--fb-text)] outline-none focus:border-[var(--fb-accent)] focus:ring-[3px] focus:ring-[color-mix(in_oklch,var(--fb-accent)_15%,transparent)] [@media(pointer:coarse)]:text-[16px] ${TOUCH_CONTROL} ${CONTROL_MOTION}`\n}\n\nfunction textInput(invalid = false) {\n\treturn `h-[max(var(--fb-control-h),calc(var(--fb-gap)*10))] w-full min-w-0 rounded-[var(--fb-radius)] border bg-[var(--fb-surface)] px-3 text-[16px] text-[var(--fb-text)] outline-none @min-[40rem]/fb:text-[var(--fb-font)] ${CONTROL_MOTION} ${\n\t\tinvalid\n\t\t\t? 'border-[1.5px] border-[var(--fb-danger)] ring-[3px] ring-[color-mix(in_oklch,var(--fb-danger)_12%,transparent)]'\n\t\t\t: 'border-[var(--fb-border)] focus:border-[1.5px] focus:border-[var(--fb-accent)] focus:ring-[3px] focus:ring-[color-mix(in_oklch,var(--fb-accent)_15%,transparent)]'\n\t}`\n}\n\nconst DIALOG_SURFACE = `w-full min-w-0 rounded-[calc(var(--fb-radius)+6px)] bg-[var(--fb-surface)] p-[calc(var(--fb-gap)*6)] shadow-[0_24px_60px_color-mix(in_oklch,var(--fb-text)_28%,transparent)] ${SURFACE_MOTION}`\nconst DIALOG_TITLE = 'm-0 text-[17px] font-bold leading-snug'\nconst DIALOG_BODY = 'mt-2 text-[var(--fb-font)] leading-relaxed text-[var(--fb-muted)]'\nconst DIALOG_ACTIONS = 'mt-6 flex flex-wrap justify-end gap-2'\n\ntype FileTone = 'folder' | 'danger' | 'ok' | 'accent' | 'warn' | 'neutral'\n\nconst FILE_TONE_CLASSES: Record<FileTone, string> = {\n\tfolder:\n\t\t'bg-[color-mix(in_oklch,var(--fb-folder)_22%,var(--fb-surface))] text-[color-mix(in_oklch,var(--fb-folder)_70%,var(--fb-text))]',\n\tdanger: 'bg-[var(--fb-danger-soft)] text-[var(--fb-danger)]',\n\tok: 'bg-[var(--fb-ok-soft)] text-[var(--fb-ok)]',\n\taccent: `bg-[var(--fb-accent-soft)] ${ACCENT_INK}`,\n\twarn: 'bg-[var(--fb-warn-soft)] text-[color-mix(in_oklch,var(--fb-warn)_80%,var(--fb-text))]',\n\tneutral: 'bg-[var(--fb-surface-2)] text-[var(--fb-muted)]'\n}\n\nconst ARCHIVE_EXTENSIONS = new Set(['zip', 'rar', '7z', 'tar', 'gz', 'tgz', 'bz2', 'xz'])\n\nfunction getFileExtension(name: string) {\n\tconst dot = name.lastIndexOf('.')\n\treturn dot > 0 ? name.slice(dot + 1).toLowerCase() : ''\n}\n\nfunction getFileTone<TMetadata>(item: FileNode<TMetadata>): FileTone {\n\tif (item.kind === 'folder') return 'folder'\n\tconst mime = item.mimeType ?? ''\n\tconst extension = getFileExtension(item.name)\n\tif (mime === 'application/pdf' || extension === 'pdf') return 'danger'\n\tif (mime.startsWith('image/')) return 'ok'\n\tif (mime.startsWith('video/') || mime.startsWith('audio/')) return 'accent'\n\tif (ARCHIVE_EXTENSIONS.has(extension) || /zip|compressed|x-tar/.test(mime)) return 'warn'\n\treturn 'neutral'\n}\n\nfunction getFileBadge<TMetadata>(item: FileNode<TMetadata>) {\n\treturn getFileExtension(item.name).slice(0, 4).toUpperCase() || 'FILE'\n}\n\nfunction FileTypeTile<TMetadata>({ item, size }: { item: FileNode<TMetadata>; size: 'sm' | 'md' | 'lg' }) {\n\tconst box =\n\t\tsize === 'sm'\n\t\t\t? 'size-8 rounded-[calc(var(--fb-radius)-2px)] text-[9px]'\n\t\t\t: size === 'md'\n\t\t\t\t? 'h-[var(--fb-thumb-h)] w-full rounded-[calc(var(--fb-radius)-2px)] text-[13px]'\n\t\t\t\t: 'h-[150px] w-full rounded-[var(--fb-radius)] text-[15px]'\n\tconst icon = size === 'sm' ? 'size-4' : 'size-10'\n\treturn (\n\t\t<span\n\t\t\taria-hidden=\"true\"\n\t\t\tclassName={`grid shrink-0 place-items-center overflow-hidden font-bold tracking-[0.06em] ${box} ${FILE_TONE_CLASSES[getFileTone(item)]} ${CONTROL_MOTION}`}\n\t\t>\n\t\t\t{item.kind === 'folder' ? (\n\t\t\t\t<Folder className={`${icon} fill-current`} strokeWidth={0} />\n\t\t\t) : item.thumbnailUrl && size !== 'sm' ? (\n\t\t\t\t<img alt=\"\" className=\"size-full object-cover\" draggable={false} loading=\"lazy\" src={item.thumbnailUrl} />\n\t\t\t) : (\n\t\t\t\tgetFileBadge(item)\n\t\t\t)}\n\t\t</span>\n\t)\n}\n\nfunction SelectionMark({ selected, visibleOnHover = true }: { selected: boolean; visibleOnHover?: boolean }) {\n\treturn (\n\t\t<span\n\t\t\taria-hidden=\"true\"\n\t\t\tclassName={`grid size-[18px] shrink-0 place-items-center rounded-[5px] text-[var(--fb-surface)] ${CONTROL_MOTION} ${\n\t\t\t\tselected\n\t\t\t\t\t? 'bg-[var(--fb-accent)]'\n\t\t\t\t\t: `border-[1.5px] border-[var(--fb-border-strong)] bg-[var(--fb-surface)] ${visibleOnHover ? 'opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100' : ''}`\n\t\t\t}`}\n\t\t>\n\t\t\t{selected ? <Check className=\"size-3\" strokeWidth={3.5} /> : null}\n\t\t</span>\n\t)\n}\n\nfunction formatShortDate(value: string | undefined) {\n\tif (!value) return null\n\tconst date = new Date(value)\n\treturn Number.isNaN(date.getTime()) ? null : date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })\n}\n"],"x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"mappings":"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"}