@brftech/filex-core 0.4.0 → 0.4.2
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/{ArchiveViewer-Dgvl43gn.js → ArchiveViewer-B_0IQExT.js} +2 -2
- package/dist/{ArchiveViewer-Dgvl43gn.js.map → ArchiveViewer-B_0IQExT.js.map} +1 -1
- package/dist/{CsvViewer-gWO5pc8F.js → CsvViewer-maMfUy5i.js} +2 -2
- package/dist/{CsvViewer-gWO5pc8F.js.map → CsvViewer-maMfUy5i.js.map} +1 -1
- package/dist/{DrawioViewer-DUAlRIAb.js → DrawioViewer-DP_pXI00.js} +2 -2
- package/dist/{DrawioViewer-DUAlRIAb.js.map → DrawioViewer-DP_pXI00.js.map} +1 -1
- package/dist/{EpubViewer-DIXzuQWK.js → EpubViewer-DSaqGnVx.js} +2 -2
- package/dist/{EpubViewer-DIXzuQWK.js.map → EpubViewer-DSaqGnVx.js.map} +1 -1
- package/dist/{IpynbViewer-CJ-6pU_Z.js → IpynbViewer-BmdBanF1.js} +2 -2
- package/dist/{IpynbViewer-CJ-6pU_Z.js.map → IpynbViewer-BmdBanF1.js.map} +1 -1
- package/dist/{MermaidViewer-CyQQDyRb.js → MermaidViewer-Drlkl0Z5.js} +2 -2
- package/dist/{MermaidViewer-CyQQDyRb.js.map → MermaidViewer-Drlkl0Z5.js.map} +1 -1
- package/dist/{PsdViewer-ChfaXVgN.js → PsdViewer-gftUJrsm.js} +2 -2
- package/dist/{PsdViewer-ChfaXVgN.js.map → PsdViewer-gftUJrsm.js.map} +1 -1
- package/dist/{TiffViewer-CsfD-NG6.js → TiffViewer-0Uv0-Lxh.js} +2 -2
- package/dist/{TiffViewer-CsfD-NG6.js.map → TiffViewer-0Uv0-Lxh.js.map} +1 -1
- package/dist/{Viewer3D-BQ2XYmkN.js → Viewer3D-Gu3kUpxV.js} +2 -2
- package/dist/{Viewer3D-BQ2XYmkN.js.map → Viewer3D-Gu3kUpxV.js.map} +1 -1
- package/dist/filex-core.js +1 -1
- package/dist/filex-core.umd.cjs +29 -29
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/{index-PnhGunSA.js → index-BLocdbmc.js} +2632 -2611
- package/dist/index-BLocdbmc.js.map +1 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/FileExplorer.vue +7 -0
- package/src/components/GridView.vue +23 -0
- package/src/styles/base.css +17 -1
- package/dist/index-PnhGunSA.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-PnhGunSA.js","sources":["../src/types/FileNode.ts","../src/composables/useFileApi.ts","../src/composables/useUploadChunked.ts","../src/composables/useSelection.ts","../src/composables/useKeyboardShortcuts.ts","../src/locales/tr.ts","../src/locales/en.ts","../src/locales/index.ts","../src/composables/useLocale.ts","../src/composables/usePendingOps.ts","../src/lib/realtime.ts","../src/composables/useRealtime.ts","../src/composables/useThumbs.ts","../src/composables/useMonacoLoader.ts","../src/components/PresenceBar.vue","../src/components/ContextMenu.vue","../src/components/Toolbar.vue","../src/components/TagPicker.vue","../src/components/RecentlyOpened.vue","../src/components/Breadcrumb.vue","../src/lib/fileIcons.ts","../src/lib/snippet.ts","../src/components/StarButton.vue","../src/components/ListView.vue","../src/components/GridView.vue","../src/components/UploadProgress.vue","../src/components/PendingOpsTray.vue","../src/components/InspectorPanel.vue","../src/components/CommandPalette.vue","../src/modals/Modal.vue","../src/components/ShortcutsHelp.vue","../src/modals/NewFolderModal.vue","../src/modals/RenameModal.vue","../src/modals/DeleteConfirmModal.vue","../src/modals/ShareModal.vue","../src/modals/PreviewModal.vue","../src/modals/ConvertModal.vue","../src/modals/PermissionsModal.vue","../src/FileExplorer.vue"],"sourcesContent":["/**\n * FileNode — node shape returned by the manager endpoint.\n *\n * Backend `?q=index` (or `GET /api/files/manager?action=index`) returns:\n * { adapter, storages, dirname, files: FileNode[] }\n */\nexport interface FileNode {\n /** DB node ID — needed by the per-user meta routes (starred, tags,\n * recently-opened). Backend's projectFileNodes() emits it for every\n * row; only client-synthesized rows (e.g. multi-storage virtual\n * folders) lack one. */\n id?: number;\n /** Full adapter-qualified path: `local://receipts/2024/invoice.pdf` */\n path: string;\n /** Relative basename: `invoice.pdf` */\n basename: string;\n /** Adapter-stripped relative path: `receipts/2024/invoice.pdf` */\n relativePath?: string;\n /** `file` or `dir` */\n type: 'file' | 'dir';\n /** Extension (lowercased, no dot). Empty string = no extension. */\n extension?: string;\n /** Bytes. 0 = directory. */\n size?: number;\n /** Unix ms (backend \"last_modified\"). */\n last_modified?: number;\n /** MIME. */\n mime_type?: string;\n /** Optional thumbnail URL (backend may inline). */\n thumb_url?: string | null;\n /** Visibility: private | public. */\n visibility?: 'private' | 'public';\n /** File count for directories. */\n count?: number;\n /** Client-side tag (localStorage or backend). */\n starred?: boolean;\n /** Hex color tag. */\n color?: string | null;\n /** Server-side trash marker. */\n trashed?: boolean;\n /** RBAC effective level for the current user on this entry (backend\n * projectFileNodes emits it when a storage has RBAC on). '' / undefined =\n * ACL not enforced. Used to gate edit/manage affordances client-side. */\n perm?: 'none' | 'viewer' | 'editor' | 'owner';\n /** Generic — any additional fields the backend wants to inline. */\n [k: string]: unknown;\n}\n\nexport interface ShareInfo {\n uuid: string;\n url: string;\n password_pin?: string | null;\n expires_at?: string | null;\n max_downloads?: number | null;\n downloads?: number;\n created_at?: string;\n}\n\nexport interface UploadLimits {\n max_upload_mb: number;\n}\n\nexport type ExternalServiceState = 'ok' | 'error' | 'disabled' | 'unknown';\n\nexport interface ExternalServiceStatus {\n enabled: boolean;\n state: ExternalServiceState;\n url?: string;\n last_check?: string;\n detail?: string;\n}\n\nexport interface Capabilities {\n ffmpeg?: boolean;\n ghostscript?: boolean;\n libreoffice?: boolean;\n onlyoffice_url?: string | null;\n drawio_url?: string | null;\n convert_url?: string | null;\n max_chunk_mb?: number;\n upload_limit_mb?: number;\n external?: {\n onlyoffice?: ExternalServiceStatus;\n drawio?: ExternalServiceStatus;\n mermaid?: ExternalServiceStatus;\n };\n}\n\n/** Single source of truth for \"is the IdP/editor/diagram service ready?\".\n * A capability is usable only when both flags say so — `enabled=true` but\n * `state='error'` means an operator turned it on but a probe just failed,\n * and we'd rather hide the entry than offer a button that 500s on click.\n */\nexport function isExternalUsable(s: ExternalServiceStatus | undefined): boolean {\n return !!s && s.enabled && s.state === 'ok';\n}\n\nexport interface UploadInitResponse {\n uploadId: string;\n parts: Array<{ partNumber: number; presignedUrl: string }>;\n expiresAt: string;\n s3Key?: string;\n}\n\nexport interface UploadFinalizeResponse {\n s3Key: string;\n url?: string;\n}\n\nexport interface ArchiveEntry {\n name: string;\n size: number;\n isDir: boolean;\n lastModified?: number;\n}\n\nexport type ViewMode = 'list' | 'grid';\n\nexport interface ClipboardState {\n mode: 'cut' | 'copy' | null;\n items: FileNode[];\n sourcePath: string | null;\n}\n\n/** A soft-deleted node as returned by the filex trash listing endpoint. */\nexport interface TrashEntry {\n id: number;\n storage_id: number;\n storage_name?: string;\n path: string;\n name: string;\n size: number;\n mime?: string;\n deleted_at: string;\n ttl_days?: number | null;\n}\n","/**\n * useFileApi — backend wrapper for the manager + ancillary endpoints.\n *\n * Two URL strategies, picked at construction time:\n *\n * 1. NEW (RESTful): caller passes `apiBase: 'https://files.example.com'`.\n * The manager endpoint becomes `${apiBase}/api/files/manager` and\n * every action uses `?action=…&path=…` as a query parameter (still\n * Vuefinder-compatible — the same `?q=…` convention is accepted by\n * the new Go backend, but `action` is the canonical name in v0.1+).\n *\n * 2. LEGACY (Vuefinder-compat): caller passes `endpoint:\n * '/api/files/manager'` (and the rest of the per-route fields).\n * Used by `@brftech/file-explorer` 0.1.0 embedders that have a\n * Laravel/Filament backend already.\n *\n * Per-route fields (`uploadInit`, `shareCreate`, …) ALWAYS win over\n * the auto-derived `apiBase` URL — lets the caller mix and match.\n *\n * Auth normalisation is centralised here. The component code never\n * thinks about CSRF vs Bearer vs Basic — it just calls `index(path)`.\n */\n\nimport type { ExplorerConfig, AuthConfig, EndpointMap } from '../types/ExplorerConfig';\nimport type {\n FileNode,\n ShareInfo,\n UploadLimits,\n Capabilities,\n ArchiveEntry,\n TrashEntry,\n} from '../types/FileNode';\n\n/** Server-side PendingOp DTO (mirror of Modules\\FishApp\\Models\\PendingOp::toApiArray). */\nexport interface PendingOpDto {\n id: number;\n op_type: 'copy' | 'move' | 'delete';\n status: 'pending' | 'running' | 'done' | 'error';\n progress_total: number;\n progress_done: number;\n target_path: string | null;\n source_dir: string | null;\n source_count: number;\n error_message: string | null;\n started_at: string | null;\n finished_at: string | null;\n created_at: string | null;\n}\n\nexport interface ManagerResponse {\n adapter: string;\n storages: string[];\n dirname: string;\n read_only: boolean;\n /** RBAC effective level for the current user on this directory ('' when ACL\n * is not enforced on the storage). Gates the folder-level write actions. */\n perm?: 'none' | 'viewer' | 'editor' | 'owner';\n files: FileNode[];\n}\n\n/** A single ACL grant row (RBAC permissions panel). */\nexport interface Grant {\n id: number;\n storage_id: number;\n path_prefix: string;\n user_id: number;\n level: 'viewer' | 'editor' | 'owner';\n user_email?: string;\n user_display_name?: string;\n inherited?: boolean;\n}\n\nexport interface PermissionsResponse {\n path: string;\n storage_rbac: boolean;\n direct: Grant[];\n inherited: Grant[];\n effective: string;\n}\n\nexport interface ResolveEmailResponse {\n found: boolean;\n user?: { id: number; email: string; display_name: string; role: string };\n}\n\nexport interface UserSuggestion {\n id: number;\n email: string;\n display_name: string;\n role: string;\n}\n\n/* === koru:k1 — version history (inspector panel) === */\n\n/** Mirrors backend `model.NodeVersion` (GET /api/files/versions?node_id=…). */\nexport interface NodeVersion {\n id: number;\n node_id: number;\n version_n: number;\n storage_key?: string;\n size: number;\n etag?: string;\n created_at: string;\n}\nexport interface UserSearchResponse {\n users: UserSuggestion[];\n}\n\nexport interface InviteResponse {\n mode: 'granted' | 'user_created' | 'shared';\n user_id?: number;\n url?: string;\n temp_password?: string;\n emailed: boolean;\n}\n\n/* === bul:s3 — global search (GET /api/files/search) === */\n\nexport type GlobalSearchScope = 'name' | 'content' | 'all';\n\n/**\n * One hit from the dedicated files-search endpoint. The backend returns raw\n * node rows (`{results: [...]}`), so `path` is the IN-STORAGE relative path\n * (no `adapter://` prefix) and the storage comes back as a numeric\n * `storage_id`. `snippet`/`matched` are the v0.2 \"Bul\" contract additions —\n * older backends simply omit them, so every consumer must stay\n * undefined-safe.\n */\nexport interface GlobalSearchHit {\n id?: number;\n storage_id?: number;\n name?: string;\n path?: string;\n /** `file` | `dir` (backend NodeType). */\n type?: string;\n size?: number;\n mime?: string;\n /** Plain-text content snippet; matches wrapped in «» (never HTML). */\n snippet?: string;\n /** Where the hit matched: name | content | both. */\n matched?: 'name' | 'content' | 'both';\n [k: string]: unknown;\n}\n\n/**\n * Resolve a Vuefinder-compatible endpoint map from the user's config.\n * Either `apiBase` is set (auto-derive everything) or each route is\n * supplied explicitly (legacy). Mixed mode works too — explicit fields\n * trump the derived URL.\n */\nexport function resolveEndpoints(config: ExplorerConfig): EndpointMap {\n // `apiBase: ''` (empty string) is a *valid* relative-root prefix —\n // it produces URLs like `/api/files/copy`. Treat only `undefined`\n // as \"no apiBase, legacy explicit-only mode\". Falsy boolean checks\n // would silently drop relative-root callers and leave every derived\n // endpoint null → \"endpoint not configured\" UI dead-ends.\n const base =\n config.apiBase != null ? config.apiBase.replace(/\\/+$/, '') : null;\n\n function derive(path: string | undefined, autoSegment: string): string | null {\n if (path) return path;\n if (base === null) return null;\n return `${base}${autoSegment}`;\n }\n\n // Manager URL is mandatory — pick the explicit `endpoint` first, then\n // fall back to `${apiBase}/api/files/manager`.\n const manager =\n config.endpoint ??\n (base !== null ? `${base}/api/files/manager` : null);\n\n if (!manager) {\n throw new Error(\n \"[@brftech/filex-core] config requires either `apiBase` or `endpoint`\",\n );\n }\n\n return {\n manager,\n uploadInit: derive(config.uploadInit, '/api/files/upload/init'),\n uploadFinalize: derive(config.uploadFinalize, '/api/files/upload/finalize'),\n uploadAbort: derive(config.uploadAbort, '/api/files/upload/abort'),\n shareCreate: derive(config.shareCreate, '/api/files/share'),\n shareList: derive(config.shareList, '/api/files/share'),\n shareDelete: derive(config.shareDelete, '/api/files/share/{uuid}'),\n limits: derive(config.limits, '/api/files/limits'),\n capabilities: derive(config.capabilities, '/api/files/capabilities'),\n archiveList: derive(config.archiveList, '/api/files/archive/list'),\n archiveExtract: derive(config.archiveExtract, '/api/files/archive/extract'),\n archiveAdd: derive(config.archiveAdd, '/api/files/archive/add'),\n copy: derive(config.copy, '/api/files/copy'),\n moveAsync: derive(config.moveAsync, '/api/files/move'),\n deleteAsync: derive(config.deleteAsync, '/api/files/delete'),\n opsList: derive(config.opsList, '/api/files/ops'),\n opsShow: derive(config.opsShow, '/api/files/ops/{id}'),\n onlyOfficeConfig: derive(config.onlyOfficeConfig, '/api/files/onlyoffice/config'),\n saveText: derive(config.saveText, '/api/files/save-text'),\n restore: derive(config.restore, '/api/files/restore'),\n // filex trash: list soft-deleted nodes + restore one by node id.\n trashList: derive(config.trashList, '/api/files/manager/trash'),\n trashRestore: derive(config.trashRestore, '/api/files/manager/restore'),\n };\n}\n\n/**\n * Resolve a possibly-async bearer token to a string. Caller passes\n * `auth.token` here so the auth header is fresh on every request.\n */\nasync function resolveToken(t: string | (() => string | Promise<string>)): Promise<string> {\n if (typeof t === 'function') {\n const out = t();\n return out instanceof Promise ? await out : out;\n }\n return t;\n}\n\n/**\n * Normalise the legacy `{type: 'bearer'}` shape to the modern\n * `{kind: 'bearer'}` discriminator. Lets us write a single auth-header\n * builder downstream.\n */\nfunction normalizeAuth(auth: AuthConfig | undefined): { kind: 'bearer'; token: string | (() => string | Promise<string>) }\n | { kind: 'csrf'; csrf: string }\n | { kind: 'basic'; user: string; pass: string }\n | { kind: 'none' } {\n if (!auth) return { kind: 'none' };\n if ('kind' in auth) return auth;\n // Legacy shape — translate.\n if (auth.type === 'bearer') return { kind: 'bearer', token: auth.token };\n if (auth.type === 'csrf') return { kind: 'csrf', csrf: auth.csrf };\n return { kind: 'none' };\n}\n\nexport function useFileApi(config: ExplorerConfig) {\n const endpoints = resolveEndpoints(config);\n const authConf = normalizeAuth(config.auth);\n\n async function authHeaders(extra: Record<string, string> = {}): Promise<Record<string, string>> {\n const h: Record<string, string> = { Accept: 'application/json', ...extra };\n if (authConf.kind === 'bearer') {\n const token = await resolveToken(authConf.token);\n if (token) h.Authorization = `Bearer ${token}`;\n } else if (authConf.kind === 'csrf') {\n h['X-CSRF-TOKEN'] = authConf.csrf;\n h['X-Requested-With'] = 'XMLHttpRequest';\n } else if (authConf.kind === 'basic') {\n const creds = btoa(`${authConf.user}:${authConf.pass}`);\n h.Authorization = `Basic ${creds}`;\n }\n return h;\n }\n\n /**\n * Sync auth-header builder for callers that need headers in a\n * non-async context (XMLHttpRequest, OnlyOffice config endpoint\n * post-mounted PreviewModal). Function-token bearers are *resolved\n * lazily* via the async path; here we just include the cached value\n * if any. Component code should prefer the async `authHeaders()` —\n * this is a defensive escape hatch.\n */\n function authHeadersSync(extra: Record<string, string> = {}): Record<string, string> {\n const h: Record<string, string> = { Accept: 'application/json', ...extra };\n if (authConf.kind === 'bearer' && typeof authConf.token === 'string') {\n h.Authorization = `Bearer ${authConf.token}`;\n } else if (authConf.kind === 'csrf') {\n h['X-CSRF-TOKEN'] = authConf.csrf;\n h['X-Requested-With'] = 'XMLHttpRequest';\n } else if (authConf.kind === 'basic') {\n const creds = btoa(`${authConf.user}:${authConf.pass}`);\n h.Authorization = `Basic ${creds}`;\n }\n return h;\n }\n\n function credentialsMode(): RequestCredentials {\n return authConf.kind === 'csrf' ? 'include' : 'same-origin';\n }\n\n // Map an HTTP status to a short, human-readable message in the explorer's\n // locale. The raw JSON body is attached as `.detail` for debugging but never\n // shown in the toast (Burak: \"404/403 falan verince ham json görüyorum\").\n function statusMessage(status: number): string {\n const tr = (config.locale ?? 'tr') !== 'en';\n const m: Record<number, [string, string]> = {\n 400: ['Geçersiz istek', 'Bad request'],\n 401: ['Oturum gerekli, tekrar giriş yapın', 'Sign-in required'],\n 403: ['Bu işlem için yetkiniz yok', 'You are not allowed to do this'],\n 404: ['Bulunamadı', 'Not found'],\n 409: ['Zaten var / çakışma', 'Already exists / conflict'],\n 413: ['Dosya çok büyük', 'File too large'],\n 415: ['Bu dosya türü desteklenmiyor', 'Unsupported file type'],\n 422: ['Geçersiz veri', 'Invalid data'],\n 429: ['Çok fazla istek, biraz bekleyin', 'Too many requests'],\n 500: ['Sunucu hatası', 'Server error'],\n 501: ['Bu işlem desteklenmiyor', 'Not supported'],\n 503: ['Servis şu an kullanılamıyor', 'Service unavailable'],\n };\n const e = m[status];\n if (e) return tr ? e[0] : e[1];\n return tr ? `Hata (${status})` : `Error (${status})`;\n }\n\n async function jsonFetch<T>(url: string, init: RequestInit = {}): Promise<T> {\n const headers = {\n ...(await authHeaders()),\n ...((init.headers as Record<string, string> | undefined) ?? {}),\n };\n const res = await fetch(url, {\n ...init,\n headers,\n credentials: credentialsMode(),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n const err = new Error(statusMessage(res.status)) as Error & { status?: number; detail?: string };\n err.status = res.status;\n err.detail = text.slice(0, 300);\n throw err;\n }\n return res.json() as Promise<T>;\n }\n\n // --------------------------------------------------------------------\n // Permissions (RBAC) — derived from the manager endpoint by swapping the\n // trailing `/manager` for `/permissions`. Owner/admin only (backend gated).\n // --------------------------------------------------------------------\n function permissionsUrl(sub = ''): string {\n const base = endpoints.manager.replace(/\\/manager(\\?.*)?$/, '/permissions');\n return base + sub;\n }\n async function listPermissions(path: string): Promise<PermissionsResponse> {\n return jsonFetch<PermissionsResponse>(permissionsUrl() + '?path=' + encodeURIComponent(path));\n }\n async function resolveEmail(email: string): Promise<ResolveEmailResponse> {\n return jsonFetch<ResolveEmailResponse>(permissionsUrl('/resolve') + '?email=' + encodeURIComponent(email));\n }\n async function searchUsers(q: string): Promise<UserSearchResponse> {\n return jsonFetch<UserSearchResponse>(permissionsUrl('/users') + '?q=' + encodeURIComponent(q));\n }\n async function addPermission(body: { path: string; user_id: number; level: string; is_dir?: boolean }): Promise<unknown> {\n return jsonFetch(permissionsUrl(), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });\n }\n async function updatePermission(id: number, level: string): Promise<unknown> {\n return jsonFetch(permissionsUrl('/' + id), { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ level }) });\n }\n async function deletePermission(id: number): Promise<unknown> {\n return jsonFetch(permissionsUrl('/' + id), { method: 'DELETE' });\n }\n async function invitePermission(body: { path: string; email: string; level: string; create_user?: boolean; role?: string; is_dir?: boolean; locale?: string }): Promise<InviteResponse> {\n return jsonFetch<InviteResponse>(permissionsUrl('/invite'), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });\n }\n async function shareMail(body: { path: string; email?: string; emails?: string[]; url: string; pin?: string | null; expires_days?: number; locale?: string; is_dir?: boolean; size?: number; mode?: string }): Promise<{ emailed: boolean; sent?: string[]; failed?: string[] }> {\n return jsonFetch<{ emailed: boolean; sent?: string[]; failed?: string[] }>(permissionsUrl('/share-mail'), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });\n }\n\n // --------------------------------------------------------------------\n // Manager contract — supports both `?q=action` (legacy) and\n // `?action=action` (new) by emitting BOTH. Backends recognising one\n // ignore the other; new backends prefer `action`.\n // --------------------------------------------------------------------\n\n function qs(params: Record<string, string | number | boolean | undefined>): string {\n const sp = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n sp.set(k, String(v));\n }\n return sp.toString();\n }\n\n function managerUrl(action: string, params: Record<string, string | number | boolean | undefined> = {}): string {\n const sep = endpoints.manager.includes('?') ? '&' : '?';\n return `${endpoints.manager}${sep}${qs({ q: action, action, ...params })}`;\n }\n\n async function index(path: string): Promise<ManagerResponse> {\n return jsonFetch<ManagerResponse>(managerUrl('index', { path }));\n }\n\n async function search(path: string, filter: string): Promise<ManagerResponse> {\n return jsonFetch<ManagerResponse>(managerUrl('search', { path, filter }));\n }\n\n /* === bul:s3 — global \"search everywhere\" ===\n * Derived from the manager endpoint by swapping `/manager` for `/search`\n * (same trick permissionsUrl uses), so embedded proxies that forward the\n * whole /api/files/* subtree keep working. Errors and legacy backends\n * degrade to an empty result list — the palette just shows nothing. */\n async function globalSearch(\n query: string,\n opts: { limit?: number; scope?: GlobalSearchScope } = {},\n ): Promise<GlobalSearchHit[]> {\n const base = endpoints.manager.replace(/\\/manager(\\?.*)?$/, '/search');\n const sep = base.includes('?') ? '&' : '?';\n const url = `${base}${sep}${qs({ q: query, limit: opts.limit, scope: opts.scope })}`;\n const data = await jsonFetch<{ results?: GlobalSearchHit[] | null }>(url);\n return Array.isArray(data?.results) ? data.results : [];\n }\n\n async function subfolders(path: string): Promise<{ folders: FileNode[] }> {\n return jsonFetch<{ folders: FileNode[] }>(managerUrl('subfolders', { path }));\n }\n\n async function newFolder(path: string, name: string): Promise<ManagerResponse> {\n return jsonFetch<ManagerResponse>(managerUrl('newfolder'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, name }),\n });\n }\n\n async function rename(path: string, item: string, name: string): Promise<ManagerResponse> {\n return jsonFetch<ManagerResponse>(managerUrl('rename'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, item, name }),\n });\n }\n\n async function move(path: string, items: string[], target: string): Promise<ManagerResponse> {\n return jsonFetch<ManagerResponse>(managerUrl('move'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, item: target, items: items.map((p) => ({ path: p })) }),\n });\n }\n\n async function deleteItems(path: string, items: string[]): Promise<ManagerResponse> {\n return jsonFetch<ManagerResponse>(managerUrl('delete'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, items: items.map((p) => ({ path: p })) }),\n });\n }\n\n /** Server-side recursive copy (async — returns a PendingOp). */\n async function copy(source: string[], target: string): Promise<{ op: PendingOpDto }> {\n if (!endpoints.copy) throw new Error('copy endpoint not configured');\n return jsonFetch(endpoints.copy, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ source, target }),\n });\n }\n\n async function moveAsync(source: string[], target: string, sourceDir?: string): Promise<{ op: PendingOpDto }> {\n if (!endpoints.moveAsync) throw new Error('moveAsync endpoint not configured');\n return jsonFetch(endpoints.moveAsync, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ source, target, sourceDir }),\n });\n }\n\n async function deleteAsync(source: string[], sourceDir?: string): Promise<{ op: PendingOpDto }> {\n if (!endpoints.deleteAsync) throw new Error('deleteAsync endpoint not configured');\n return jsonFetch(endpoints.deleteAsync, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ source, sourceDir }),\n });\n }\n\n async function restore(source: string[]): Promise<{ ok: boolean; restored: number }> {\n if (!endpoints.restore) throw new Error('restore endpoint not configured');\n return jsonFetch(endpoints.restore, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ source }),\n });\n }\n\n /** filex trash listing — soft-deleted nodes across (or within) storages. */\n async function listTrash(storageName?: string): Promise<{ entries: TrashEntry[]; total: number }> {\n if (!endpoints.trashList) throw new Error('trashList endpoint not configured');\n const base = endpoints.trashList;\n const sep = base.includes('?') ? '&' : '?';\n const url = storageName ? `${base}${sep}storage=${encodeURIComponent(storageName)}` : base;\n return jsonFetch<{ entries: TrashEntry[]; total: number }>(url);\n }\n\n /**\n * Restore soft-deleted nodes by their node id. The filex backend restores\n * one node per call (`POST {node_id}`), so we fan out and tally successes.\n */\n async function restoreIds(ids: number[]): Promise<{ restored: number }> {\n const url = endpoints.trashRestore;\n if (!url) throw new Error('trashRestore endpoint not configured');\n let restored = 0;\n for (const id of ids) {\n try {\n await jsonFetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ node_id: id }),\n });\n restored++;\n } catch {\n /* skip individual failures; report the count that succeeded */\n }\n }\n return { restored };\n }\n\n /**\n * Legacy in-band multipart upload (small files / chunked endpoint\n * absent). XMLHttpRequest because fetch doesn't expose upload\n * progress on most browsers.\n */\n async function uploadMultipart(\n path: string,\n files: File[],\n onProgress?: (p: number) => void,\n ): Promise<ManagerResponse> {\n const fd = new FormData();\n fd.append('path', path);\n for (const f of files) {\n fd.append('file[]', f, f.name);\n }\n const headers = await authHeaders();\n return new Promise<ManagerResponse>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('POST', managerUrl('upload'));\n for (const [k, v] of Object.entries(headers)) {\n if (k === 'Content-Type') continue;\n xhr.setRequestHeader(k, v);\n }\n xhr.withCredentials = credentialsMode() === 'include';\n xhr.upload.onprogress = (ev) => {\n if (onProgress && ev.lengthComputable) {\n onProgress(Math.round((ev.loaded / ev.total) * 100));\n }\n };\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (e) {\n reject(e);\n }\n } else {\n reject(new Error(`${xhr.status} ${xhr.statusText}: ${xhr.responseText.slice(0, 200)}`));\n }\n };\n xhr.onerror = () => reject(new Error('Network error'));\n xhr.send(fd);\n });\n }\n\n function downloadUrl(path: string): string {\n return managerUrl('download', { path });\n }\n\n function previewUrl(path: string): string {\n return managerUrl('preview', { path });\n }\n\n /**\n * Fetch a file body with the configured auth headers + credentials,\n * returning the raw blob plus a normalized object URL viewers can mount\n * directly. Used by the rich viewers (3D, EPUB, PDF, PSD, TIFF, …) which\n * need an `ArrayBuffer` or a `Blob`-backed `objectURL` rather than the\n * relative preview URL.\n *\n * Caller is responsible for revoking `url` (`URL.revokeObjectURL(url)`)\n * once the viewer unmounts to avoid leaking the blob.\n */\n async function fetchBlob(\n path: string,\n ): Promise<{ url: string; blob: Blob; mime: string }> {\n const headers = await authHeaders();\n const res = await fetch(previewUrl(path), {\n headers,\n credentials: credentialsMode(),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(\n `${res.status} ${res.statusText}${text ? ' — ' + text.slice(0, 200) : ''}`,\n );\n }\n const blob = await res.blob();\n const mime = blob.type || res.headers.get('content-type') || '';\n const url = URL.createObjectURL(blob);\n return { url, blob, mime };\n }\n\n /**\n * Like `fetchBlob` but returns the raw bytes — viewers that need\n * binary parsing (utif, ag-psd, pdfjs-dist) get the buffer directly\n * without the extra `Blob → arrayBuffer` round trip.\n */\n async function fetchArrayBuffer(path: string): Promise<ArrayBuffer> {\n const headers = await authHeaders();\n const res = await fetch(previewUrl(path), {\n headers,\n credentials: credentialsMode(),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(\n `${res.status} ${res.statusText}${text ? ' — ' + text.slice(0, 200) : ''}`,\n );\n }\n return res.arrayBuffer();\n }\n\n // --------------------------------------------------------------------\n // Peripheral endpoints\n // --------------------------------------------------------------------\n\n async function limits(): Promise<UploadLimits> {\n if (!endpoints.limits) return { max_upload_mb: 1024 };\n return jsonFetch<UploadLimits>(endpoints.limits);\n }\n\n async function capabilities(): Promise<Capabilities> {\n if (!endpoints.capabilities) {\n return {\n ffmpeg: false,\n ghostscript: false,\n libreoffice: false,\n max_chunk_mb: 5,\n upload_limit_mb: 1024,\n onlyoffice_url: config.onlyOfficeBase ?? null,\n drawio_url: config.drawioBase ?? null,\n convert_url: config.convertBase ?? null,\n };\n }\n return jsonFetch<Capabilities>(endpoints.capabilities);\n }\n\n async function createShare(payload: {\n path: string;\n password?: boolean;\n expires_at?: string | null;\n max_downloads?: number | null;\n // File-drop (public upload link) — kind:'drop' mints an upload link into a\n // folder instead of a download link; drop_settings carries the caps.\n kind?: string;\n max_uploads?: number | null;\n drop_settings?: Record<string, unknown> | null;\n }): Promise<{ share: ShareInfo & { url: string; path: string; filename: string; kind?: string } }> {\n if (!endpoints.shareCreate) throw new Error('shareCreate endpoint not configured');\n return jsonFetch(endpoints.shareCreate, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n }\n\n async function listShares(path: string): Promise<{ shares: ShareInfo[] }> {\n if (!endpoints.shareList) return { shares: [] };\n const sep = endpoints.shareList.includes('?') ? '&' : '?';\n return jsonFetch(`${endpoints.shareList}${sep}path=${encodeURIComponent(path)}`);\n }\n\n async function revokeShare(uuid: string): Promise<{ success: boolean }> {\n if (!endpoints.shareDelete) throw new Error('shareDelete endpoint not configured');\n const url = endpoints.shareDelete.replace('{uuid}', encodeURIComponent(uuid));\n return jsonFetch(url, { method: 'DELETE' });\n }\n\n async function archiveList(path: string): Promise<{ entries: ArchiveEntry[] }> {\n if (!endpoints.archiveList) throw new Error('archiveList endpoint not configured');\n const raw = await jsonFetch<{ entries: Array<{ name: string; size: number; is_dir: boolean; mtime?: number }> }>(\n endpoints.archiveList,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path }),\n },\n );\n return {\n entries: raw.entries.map((e) => ({\n name: e.name,\n size: e.size,\n isDir: e.is_dir,\n lastModified: e.mtime,\n })),\n };\n }\n\n async function archiveExtract(path: string, members?: string[]): Promise<{ keys: string[]; count: number }> {\n if (!endpoints.archiveExtract) throw new Error('archiveExtract endpoint not configured');\n return jsonFetch(endpoints.archiveExtract, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, members }),\n });\n }\n\n async function archiveAdd(path: string, files: Array<{ name: string; source: string }>): Promise<{ path: string }> {\n if (!endpoints.archiveAdd) throw new Error('archiveAdd endpoint not configured');\n return jsonFetch(endpoints.archiveAdd, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, files }),\n });\n }\n\n /* === koru:k1 — version history (inspector panel) ===\n * Derived from the manager endpoint by swapping `/manager` for `/versions`\n * (same trick permissionsUrl/globalSearch use) so embedded proxies that\n * forward the whole /api/files/* subtree keep working.\n * GET /api/files/versions?node_id=N → {versions, node_id}\n * POST /api/files/versions/restore → {node_id, version_id, snapshot_current}\n * POST /api/files/versions/snapshot → {node_id} (may not exist on older backends)\n */\n function versionsUrl(sub = ''): string {\n const base = endpoints.manager.replace(/\\/manager(\\?.*)?$/, '/versions');\n return base + sub;\n }\n async function listVersions(nodeId: number): Promise<NodeVersion[]> {\n const data = await jsonFetch<{ versions?: NodeVersion[] | null }>(\n versionsUrl() + '?node_id=' + encodeURIComponent(String(nodeId)),\n );\n return Array.isArray(data?.versions) ? data.versions : [];\n }\n async function restoreVersion(\n nodeId: number,\n versionId: number,\n snapshotCurrent = true,\n ): Promise<void> {\n await jsonFetch(versionsUrl('/restore'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n node_id: nodeId,\n version_id: versionId,\n snapshot_current: snapshotCurrent,\n }),\n });\n }\n async function snapshotVersion(nodeId: number): Promise<void> {\n await jsonFetch(versionsUrl('/snapshot'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ node_id: nodeId }),\n });\n }\n /* === /koru:k1 === */\n\n // Mint a short-lived WebSocket auth ticket for the realtime layer. Derived\n // from the manager URL (so it flows through the same host proxy) and uses the\n // same auth/creds as every other call. Returns null on any failure (a backend\n // without the endpoint, a network error) so the caller falls back to polling.\n async function wsTicket(): Promise<{ ticket: string; ws_url: string } | null> {\n const url = endpoints.manager.replace(/\\/manager(\\?.*)?$/, '/ws-ticket');\n try {\n return await jsonFetch<{ ticket: string; ws_url: string }>(url, { method: 'POST' });\n } catch {\n return null;\n }\n }\n\n return {\n // Realtime\n wsTicket,\n // Manager\n index,\n search,\n globalSearch /* bul:s3 */,\n subfolders,\n newFolder,\n rename,\n move,\n copy,\n moveAsync,\n deleteAsync,\n deleteItems,\n restore,\n listTrash,\n restoreIds,\n uploadMultipart,\n downloadUrl,\n previewUrl,\n fetchBlob,\n fetchArrayBuffer,\n // Peripheral\n limits,\n capabilities,\n createShare,\n listShares,\n revokeShare,\n archiveList,\n archiveExtract,\n archiveAdd,\n // Version history (koru:k1 inspector)\n listVersions,\n restoreVersion,\n snapshotVersion,\n // Permissions (RBAC panel)\n listPermissions,\n resolveEmail,\n searchUsers,\n addPermission,\n updatePermission,\n deletePermission,\n invitePermission,\n shareMail,\n // Internals (exposed for useUploadChunked + PreviewModal)\n endpoints,\n authHeaders,\n authHeadersSync,\n credentialsMode,\n jsonFetch,\n };\n}\n\nexport type FileApi = ReturnType<typeof useFileApi>;\n","/**\n * useUploadChunked — S3 multipart upload orchestrator for the browser.\n *\n * Contract (matches the standard /api/files/upload/{init,finalize,abort}):\n * 1. POST init {path, filename, size, mime}\n * → {uploadId, parts: [{partNumber, presignedUrl}], chunkBytes, totalParts}\n * 2. For each part: PUT <presignedUrl> <chunk bytes>, collect ETag header\n * 3. POST finalize {uploadId, parts: [{partNumber, etag}]}\n * → {s3Key, url, size}\n * Abort path: POST abort {uploadId} any time.\n *\n * We parallelize up to `parallelChunks` uploads (default 4). Progress is\n * reported as an aggregate percentage across all parts — individual part\n * percentages are tracked internally and summed.\n */\n\nimport type { ExplorerConfig } from '../types/ExplorerConfig';\nimport type { FileApi } from './useFileApi';\nimport type { UploadInitResponse, UploadFinalizeResponse } from '../types/FileNode';\n\nexport interface UploadJob {\n id: string; // local uuid\n file: File;\n path: string;\n uploadId?: string;\n totalBytes: number;\n uploadedBytes: number;\n percent: number;\n status: 'pending' | 'initializing' | 'uploading' | 'finalizing' | 'done' | 'error' | 'aborted';\n error?: string;\n cancel(): void;\n}\n\nexport interface UploadOptions {\n path: string;\n file: File;\n chunkSize?: number;\n parallelChunks?: number;\n onProgress?: (job: UploadJob) => void;\n onDone?: (job: UploadJob, result: UploadFinalizeResponse) => void;\n onError?: (job: UploadJob, err: Error) => void;\n}\n\nexport function useUploadChunked(config: ExplorerConfig, api: FileApi) {\n const DEFAULT_CHUNK = config.chunkSize ?? 5 * 1024 * 1024;\n const DEFAULT_PARALLEL = Math.max(1, Math.min(8, config.parallelChunks ?? 4));\n\n async function uploadFile(opts: UploadOptions): Promise<UploadFinalizeResponse> {\n const chunkSize = opts.chunkSize ?? DEFAULT_CHUNK;\n const parallel = opts.parallelChunks ?? DEFAULT_PARALLEL;\n\n const job: UploadJob = {\n id: crypto.randomUUID(),\n file: opts.file,\n path: opts.path,\n totalBytes: opts.file.size,\n uploadedBytes: 0,\n percent: 0,\n status: 'initializing',\n cancel: () => {}, // rebound below\n };\n\n let cancelled = false;\n const aborters: AbortController[] = [];\n job.cancel = () => {\n cancelled = true;\n for (const a of aborters) a.abort();\n };\n\n function report() {\n job.percent =\n job.totalBytes > 0\n ? Math.min(100, Math.round((job.uploadedBytes / job.totalBytes) * 100))\n : 0;\n opts.onProgress?.(job);\n }\n\n try {\n if (!api.endpoints.uploadInit) throw new Error('uploadInit not configured');\n // 1) init\n const init = await api.jsonFetch<UploadInitResponse & { chunkBytes?: number; totalParts?: number }>(\n api.endpoints.uploadInit,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n path: opts.path,\n filename: opts.file.name,\n size: opts.file.size,\n mime: opts.file.type || 'application/octet-stream',\n }),\n },\n );\n job.uploadId = init.uploadId;\n job.status = 'uploading';\n report();\n\n const actualChunk = init.chunkBytes ?? chunkSize;\n void actualChunk; // referenced below — keep TS happy with `chunkSize` shadow\n const partProgress = new Map<number, number>();\n\n // 2) upload parts in parallel windows\n const completed: Array<{ partNumber: number; etag: string }> = [];\n let cursor = 0;\n\n async function uploadPart(entry: { partNumber: number; presignedUrl: string }): Promise<void> {\n const idx = entry.partNumber - 1;\n const start = idx * (init.chunkBytes ?? chunkSize);\n const end = Math.min(start + (init.chunkBytes ?? chunkSize), opts.file.size);\n const blob = opts.file.slice(start, end);\n\n const ctl = new AbortController();\n aborters.push(ctl);\n\n await new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('PUT', entry.presignedUrl);\n xhr.upload.onprogress = (ev) => {\n if (ev.lengthComputable) {\n const prev = partProgress.get(entry.partNumber) ?? 0;\n const delta = ev.loaded - prev;\n partProgress.set(entry.partNumber, ev.loaded);\n job.uploadedBytes += delta;\n report();\n }\n };\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n const etag = (xhr.getResponseHeader('ETag') || xhr.getResponseHeader('etag') || '').trim();\n if (!etag) {\n reject(new Error('Missing ETag on S3 response'));\n return;\n }\n // Top off in case the last progress event under-reported.\n const blobSize = end - start;\n const prev = partProgress.get(entry.partNumber) ?? 0;\n if (prev < blobSize) {\n job.uploadedBytes += blobSize - prev;\n partProgress.set(entry.partNumber, blobSize);\n }\n completed.push({ partNumber: entry.partNumber, etag });\n resolve();\n } else {\n reject(\n new Error(`S3 PUT ${entry.partNumber} → ${xhr.status}: ${xhr.responseText.slice(0, 200)}`),\n );\n }\n };\n xhr.onerror = () => reject(new Error(`S3 PUT ${entry.partNumber} network error`));\n xhr.onabort = () => reject(new DOMException('Aborted', 'AbortError'));\n ctl.signal.addEventListener('abort', () => xhr.abort());\n xhr.send(blob);\n });\n }\n\n /**\n * Wrap `uploadPart` in a tiny exponential-backoff retry so a\n * single hiccup on the edge (intermittent TCP RST, transient\n * 5xx) doesn't kill the whole multipart session. Counter is\n * per-part — a flaky one doesn't burn the budget for healthy\n * neighbours. We DON'T retry user cancellations or AbortError.\n */\n const MAX_RETRIES = 2;\n async function uploadPartWithRetry(\n entry: { partNumber: number; presignedUrl: string },\n attempt = 0,\n ): Promise<void> {\n try {\n await uploadPart(entry);\n } catch (err) {\n if (cancelled) throw err;\n const e = err instanceof Error ? err : new Error(String(err));\n if (e.name === 'AbortError') throw e;\n if (attempt >= MAX_RETRIES) throw e;\n\n // Roll back any partial uploadedBytes so progress doesn't\n // double-count after the retry succeeds.\n const leaked = partProgress.get(entry.partNumber) ?? 0;\n if (leaked > 0) {\n job.uploadedBytes = Math.max(0, job.uploadedBytes - leaked);\n partProgress.delete(entry.partNumber);\n report();\n }\n\n // Exponential backoff with jitter — 500ms, 1s, 1.5s …\n const delay = 500 * (attempt + 1) + Math.floor(Math.random() * 250);\n await new Promise((r) => setTimeout(r, delay));\n return uploadPartWithRetry(entry, attempt + 1);\n }\n }\n\n async function worker() {\n while (!cancelled && cursor < init.parts.length) {\n const entry = init.parts[cursor++];\n await uploadPartWithRetry(entry);\n }\n }\n\n const workers: Promise<void>[] = [];\n for (let i = 0; i < parallel; i++) {\n workers.push(worker());\n }\n await Promise.all(workers);\n\n if (cancelled) {\n throw new DOMException('Aborted by user', 'AbortError');\n }\n\n // 3) finalize\n if (!api.endpoints.uploadFinalize) throw new Error('uploadFinalize not configured');\n job.status = 'finalizing';\n completed.sort((a, b) => a.partNumber - b.partNumber);\n const final = await api.jsonFetch<UploadFinalizeResponse>(api.endpoints.uploadFinalize, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ uploadId: init.uploadId, parts: completed }),\n });\n\n job.status = 'done';\n job.uploadedBytes = job.totalBytes;\n job.percent = 100;\n report();\n opts.onDone?.(job, final);\n return final;\n } catch (err) {\n const asError = err instanceof Error ? err : new Error(String(err));\n job.status = asError.name === 'AbortError' ? 'aborted' : 'error';\n job.error = asError.message;\n report();\n\n // Best-effort server-side cleanup\n if (job.uploadId && api.endpoints.uploadAbort && job.status === 'aborted') {\n try {\n await api.jsonFetch(api.endpoints.uploadAbort, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ uploadId: job.uploadId }),\n });\n } catch {\n /* swallow — DB row will expire, S3 TTL handles orphan parts */\n }\n }\n\n opts.onError?.(job, asError);\n throw asError;\n }\n }\n\n return { uploadFile };\n}\n","/**\n * useSelection — multi-select state with Ctrl/Shift semantics.\n *\n * click(path, {ctrl, shift})\n * no-mod → replace selection with [path]\n * ctrl → toggle path in selection\n * shift → range select from anchor to path\n */\n\nimport { ref, computed } from 'vue';\nimport type { FileNode } from '../types/FileNode';\n\nexport function useSelection(items: () => FileNode[]) {\n const selected = ref<Set<string>>(new Set());\n const anchor = ref<string | null>(null);\n\n function click(path: string, mod: { ctrl?: boolean; shift?: boolean } = {}) {\n if (mod.shift && anchor.value) {\n const list = items();\n const aIdx = list.findIndex((n) => n.path === anchor.value);\n const bIdx = list.findIndex((n) => n.path === path);\n if (aIdx === -1 || bIdx === -1) {\n selected.value = new Set([path]);\n anchor.value = path;\n return;\n }\n const [lo, hi] = aIdx < bIdx ? [aIdx, bIdx] : [bIdx, aIdx];\n const next = new Set<string>();\n for (let i = lo; i <= hi; i++) next.add(list[i].path);\n selected.value = next;\n return;\n }\n\n if (mod.ctrl) {\n const next = new Set(selected.value);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n selected.value = next;\n anchor.value = path;\n return;\n }\n\n selected.value = new Set([path]);\n anchor.value = path;\n }\n\n function clear() {\n selected.value = new Set();\n anchor.value = null;\n }\n\n function selectAll() {\n selected.value = new Set(items().map((n) => n.path));\n }\n\n function has(path: string): boolean {\n return selected.value.has(path);\n }\n\n function add(path: string) {\n const next = new Set(selected.value);\n next.add(path);\n selected.value = next;\n }\n\n function remove(path: string) {\n const next = new Set(selected.value);\n next.delete(path);\n selected.value = next;\n }\n\n const size = computed(() => selected.value.size);\n const isEmpty = computed(() => selected.value.size === 0);\n\n const nodes = computed(() => {\n const list = items();\n return list.filter((n) => selected.value.has(n.path));\n });\n\n return { selected, anchor, click, clear, selectAll, has, add, remove, size, isEmpty, nodes };\n}\n","/**\n * useKeyboardShortcuts — binds FileExplorer's keyboard affordances.\n *\n * Activated whenever the explorer is mounted (only one instance per\n * page is expected). Skips events that originate inside form controls\n * so the user can type filenames in the search box, modals, etc.\n */\n\nimport { onMounted, onBeforeUnmount, type Ref } from 'vue';\n\nexport interface ShortcutHandlers {\n onDelete?: () => void;\n onRename?: () => void; // F2\n onSelectAll?: () => void; // Ctrl+A\n onCut?: () => void; // Ctrl+X\n onCopy?: () => void; // Ctrl+C\n onPaste?: () => void; // Ctrl+V\n onOpen?: () => void; // Enter\n onClose?: () => void; // Escape\n onFocusSearch?: () => void; // /\n onDuplicate?: () => void; // Ctrl+D\n onPathJump?: () => void; // Cmd+K / Ctrl+K\n onGoUp?: () => void; // Alt+Up / Backspace (when nothing selected)\n onShowHelp?: () => void; // ? (Shift+/ on most layouts)\n onToggleInspector?: () => void; // i (koru:k1 details panel)\n hasSelection?: () => boolean; // disambiguates Backspace\n}\n\n/**\n * SHORTCUTS — the single source of truth for the shortcut cheat-sheet\n * (ShortcutsHelp.vue). Only shortcuts actually wired by FileExplorer are\n * listed; labels/groups resolve through the locale catalogue so the help\n * dialog stays tr/en aware. `keys` entries are display combos — each one\n * renders as its own <kbd>, alternatives joined visually with \"/\".\n */\nexport interface ShortcutDef {\n keys: string[];\n labelKey: string;\n groupKey: string;\n}\n\nexport const SHORTCUTS: ShortcutDef[] = [\n // Navigation\n { keys: ['Ctrl+K'], labelKey: 'shortcuts.palette', groupKey: 'shortcuts.group.nav' },\n { keys: ['/'], labelKey: 'shortcuts.search', groupKey: 'shortcuts.group.nav' },\n { keys: ['Alt+↑', 'Backspace'], labelKey: 'shortcuts.go_up', groupKey: 'shortcuts.group.nav' },\n { keys: ['Enter'], labelKey: 'shortcuts.open', groupKey: 'shortcuts.group.nav' },\n { keys: ['Esc'], labelKey: 'shortcuts.close', groupKey: 'shortcuts.group.nav' },\n { keys: ['I'], labelKey: 'shortcuts.inspector', groupKey: 'shortcuts.group.nav' } /* koru:k1 */,\n { keys: ['?'], labelKey: 'shortcuts.help', groupKey: 'shortcuts.group.nav' },\n // Selection\n { keys: ['Ctrl+A'], labelKey: 'shortcuts.select_all', groupKey: 'shortcuts.group.selection' },\n // File operations\n { keys: ['F2'], labelKey: 'shortcuts.rename', groupKey: 'shortcuts.group.file' },\n { keys: ['Del'], labelKey: 'shortcuts.delete', groupKey: 'shortcuts.group.file' },\n { keys: ['Ctrl+X'], labelKey: 'shortcuts.cut', groupKey: 'shortcuts.group.file' },\n { keys: ['Ctrl+C'], labelKey: 'shortcuts.copy', groupKey: 'shortcuts.group.file' },\n { keys: ['Ctrl+V'], labelKey: 'shortcuts.paste', groupKey: 'shortcuts.group.file' },\n];\n\nexport function useKeyboardShortcuts(rootEl: Ref<HTMLElement | null>, handlers: ShortcutHandlers) {\n function onKey(e: KeyboardEvent) {\n const root = rootEl.value;\n if (!root) return;\n\n // Skip when the event originates inside a form control — don't\n // want `Delete` while editing a filename, `/` while typing in the\n // search box, etc. Escape always goes through so modals can close.\n const target = e.target as HTMLElement | null;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable)\n ) {\n if (e.key !== 'Escape') return;\n }\n\n const ctrl = e.ctrlKey || e.metaKey;\n\n switch (e.key) {\n case 'Delete':\n if (handlers.onDelete) {\n e.preventDefault();\n handlers.onDelete();\n }\n break;\n case 'Backspace':\n // Backspace = delete when something is selected (file-manager\n // convention), parent-dir navigation otherwise. Without this\n // disambiguation Backspace was firing onDelete with an empty\n // selection and nothing happened, leaving users wondering why\n // the obvious 'go back' key did nothing.\n if (handlers.hasSelection?.() && handlers.onDelete) {\n e.preventDefault();\n handlers.onDelete();\n } else if (handlers.onGoUp) {\n e.preventDefault();\n handlers.onGoUp();\n }\n break;\n case 'F2':\n if (handlers.onRename) {\n e.preventDefault();\n handlers.onRename();\n }\n break;\n case 'Enter':\n if (handlers.onOpen) {\n handlers.onOpen();\n }\n break;\n case 'Escape':\n if (handlers.onClose) {\n handlers.onClose();\n }\n break;\n case '/':\n if (handlers.onFocusSearch && !ctrl) {\n e.preventDefault();\n handlers.onFocusSearch();\n }\n break;\n case '?':\n if (handlers.onShowHelp && !ctrl && !e.altKey) {\n e.preventDefault();\n handlers.onShowHelp();\n }\n break;\n case 'a':\n case 'A':\n if (ctrl && handlers.onSelectAll) {\n e.preventDefault();\n handlers.onSelectAll();\n }\n break;\n case 'x':\n case 'X':\n if (ctrl && handlers.onCut) {\n e.preventDefault();\n handlers.onCut();\n }\n break;\n case 'c':\n case 'C':\n if (ctrl && handlers.onCopy) {\n e.preventDefault();\n handlers.onCopy();\n }\n break;\n case 'v':\n case 'V':\n if (ctrl && handlers.onPaste) {\n e.preventDefault();\n handlers.onPaste();\n }\n break;\n case 'd':\n case 'D':\n if (ctrl && handlers.onDuplicate) {\n e.preventDefault();\n handlers.onDuplicate();\n }\n break;\n /* koru:k1 — plain `i` toggles the inspector (details) panel. Ctrl+I /\n Alt+I stay untouched so browser/OS combos keep working. */\n case 'i':\n case 'I':\n if (!ctrl && !e.altKey && handlers.onToggleInspector) {\n e.preventDefault();\n handlers.onToggleInspector();\n }\n break;\n case 'k':\n case 'K':\n if (ctrl && handlers.onPathJump) {\n e.preventDefault();\n handlers.onPathJump();\n }\n break;\n case 'ArrowUp':\n // Alt+Up = parent dir (matches Finder / Files / Explorer).\n if (e.altKey && handlers.onGoUp) {\n e.preventDefault();\n handlers.onGoUp();\n }\n break;\n }\n }\n\n onMounted(() => window.addEventListener('keydown', onKey));\n onBeforeUnmount(() => window.removeEventListener('keydown', onKey));\n}\n","/** Turkish UI strings. */\nexport const tr: Record<string, string> = {\n 'toolbar.new_folder': 'Yeni Klasör',\n 'toolbar.upload': 'Yükle',\n 'toolbar.search': 'Ara',\n 'toolbar.search.placeholder': 'Dosya adı…',\n 'toolbar.view.list': 'Liste',\n 'toolbar.view.grid': 'Izgara',\n 'toolbar.refresh': 'Yenile',\n 'toolbar.go_up': 'Üst Klasör',\n\n 'ctx.open': 'Aç',\n 'ctx.preview': 'Önizle',\n 'ctx.download': 'İndir',\n 'ctx.convert': 'Dönüştür',\n 'ctx.rename': 'Yeniden Adlandır',\n 'ctx.delete': 'Sil',\n 'ctx.delete_perm': 'Kalıcı Olarak Sil',\n 'ctx.restore': 'Geri Getir',\n 'ctx.share': 'Paylaş',\n 'ctx.move': 'Taşı',\n 'ctx.copy': 'Kopyala',\n 'ctx.cut': 'Kes',\n 'ctx.paste': 'Yapıştır',\n 'ctx.info': 'Bilgi',\n 'ctx.duplicate': 'Kopyasını Oluştur',\n 'ctx.new_file': 'Yeni Dosya',\n\n 'modal.delete.title': 'Silinsin mi?',\n 'modal.delete.message': '{count} öğe çöpe atılacak.',\n 'modal.delete.confirm': 'Çöpe At',\n 'modal.delete.cancel': 'Vazgeç',\n\n 'modal.rename.title': 'Yeniden Adlandır',\n 'modal.rename.save': 'Kaydet',\n 'modal.rename.cancel': 'Vazgeç',\n\n 'modal.newfolder.title': 'Yeni Klasör',\n 'modal.newfolder.placeholder': 'Klasör adı',\n 'modal.newfolder.create': 'Oluştur',\n 'modal.newfolder.cancel': 'Vazgeç',\n\n 'modal.share.title': 'Paylaşım Linki',\n 'modal.share.pin': 'PIN koruması',\n 'modal.share.expires': 'Son kullanma',\n 'modal.share.max_downloads': 'İndirme limiti',\n 'modal.share.create': 'Paylaş',\n 'modal.share.cancel': 'Vazgeç',\n 'modal.share.copy': 'Kopyala',\n 'modal.share.url_copied': 'Link kopyalandı',\n 'modal.share.pin_copied': 'PIN kopyalandı',\n 'modal.share.cli_copied': 'CLI komutu kopyalandı',\n\n 'upload.progress': 'Yükleniyor',\n 'upload.done': 'Tamamlandı',\n 'upload.error': 'Hata',\n 'upload.aborted': 'İptal edildi',\n 'upload.cancel': 'İptal',\n\n 'empty.folder': 'Bu klasör boş',\n 'empty.search': 'Sonuç bulunamadı',\n 'loading': 'Yükleniyor…',\n\n 'notFound.title': 'Klasör bulunamadı',\n 'notFound.desc': 'Bu klasör mevcut değil, taşınmış ya da erişim yetkiniz yok.',\n 'notFound.goRoot': 'Kök klasöre dön',\n\n 'col.name': 'Ad',\n 'col.size': 'Boyut',\n 'col.modified': 'Tarih',\n 'col.type': 'Tür',\n\n 'unit.bytes': 'B',\n 'unit.kb': 'KB',\n 'unit.mb': 'MB',\n 'unit.gb': 'GB',\n 'unit.tb': 'TB',\n\n 'breadcrumb.root': 'Kök',\n 'breadcrumb.copy_path': 'Yolu Kopyala',\n 'breadcrumb.go_to_path': 'Yola Git',\n 'breadcrumb.path_placeholder': 'fileman/foo/bar',\n\n 'ops.copy': 'Kopyalanıyor',\n 'ops.move': 'Taşınıyor',\n 'ops.delete': 'Siliniyor',\n 'ops.queued': 'sırada',\n 'ops.done': 'tamamlandı',\n 'ops.error': 'hata',\n\n 'node.trash': 'Çöp Kutusu',\n\n // ——— Zengin önizleyici chrome ———\n 'viewer.open_in_new_tab': 'Yeni Sekmede Aç',\n 'viewer.loading': 'Yükleniyor…',\n 'viewer.failed_to_load': 'Dosya yüklenemedi',\n 'viewer.peer_not_installed': 'Bu dosya tipi için opsiyonel kütüphane kurulu değil. Peer dependency yükle veya İndir düğmesini kullan.',\n 'viewer.format_unsupported_3d': 'Bu 3B format tarayıcı önizlemesinde desteklenmiyor (model-viewer yalnızca .glb / .gltf / .usdz okur). Lütfen indirip yerel bir araçta açın.',\n 'viewer.zoom_in': 'Yakınlaştır',\n 'viewer.zoom_out': 'Uzaklaştır',\n 'viewer.fit_width': 'Sayfa genişliğine sığdır',\n 'viewer.next_page': 'Sonraki sayfa',\n 'viewer.prev_page': 'Önceki sayfa',\n 'viewer.page_n_of_m': 'Sayfa {n} / {m}',\n 'viewer.tags': 'Etiketler',\n 'viewer.layers': 'Katmanlar',\n 'viewer.toc': 'İçindekiler',\n 'viewer.font_smaller': 'Yazıyı küçült',\n 'viewer.font_larger': 'Yazıyı büyüt',\n 'viewer.search': 'Ara',\n 'viewer.download': 'İndir',\n 'viewer.saving': 'Kaydediliyor…',\n 'viewer.save': 'Kaydet (Ctrl+S)',\n 'viewer.saved': 'Kaydedildi',\n 'viewer.save_error': 'Hata',\n 'viewer.editor_loading': 'Editör yükleniyor…',\n 'viewer.no_preview': 'Bu dosya tipi için önizleme henüz yok.',\n 'viewer.edit': 'Düzenle',\n 'viewer.close': 'Kapat',\n 'presence.expand': 'İsimleri göster',\n 'presence.collapse': 'Küçült',\n 'viewer.save_annotations': 'Açıklamaları kaydet',\n 'viewer.annotations_on': 'Açıklamalar: açık',\n 'viewer.annotations_off': 'Açıklamalar: kapalı',\n 'viewer.read_only': 'Salt okunur',\n 'viewer.csv_first_row_header': 'İlk satır başlık olsun',\n 'viewer.csv_filter': 'Satır filtrele…',\n 'viewer.epub_prev': 'Önceki',\n 'viewer.epub_next': 'Sonraki',\n 'viewer.drawio.disabled': 'diagrams.net editörü bu filex kurulumunda yapılandırılmamış — yönetici FILEX_DRAWIO_URL\\'yi ayarlamalı.',\n 'viewer.archive.entries': '{n} dosya',\n 'viewer.archive.empty': 'Arşiv boş.',\n 'viewer.archive.error': 'Arşiv okunamadı.',\n 'viewer.name': 'Ad',\n 'viewer.size': 'Boyut',\n\n // ——— cila:a — sıralama / tarih grupları / yoğunluk ———\n 'col.sort': 'Sırala',\n 'group.today': 'Bugün',\n 'group.yesterday': 'Dün',\n 'group.this_week': 'Bu Hafta',\n 'group.this_month': 'Bu Ay',\n 'group.no_date': 'Tarihsiz',\n 'toolbar.density.compact': 'Sıkışık görünüm',\n 'toolbar.density.comfortable': 'Rahat görünüm',\n\n // ——— cila:c — komut paleti + kısayol yardımı + breadcrumb ———\n 'palette.placeholder': 'Dosya, klasör veya komut ara…',\n 'palette.files': 'Dosyalar',\n 'palette.commands': 'Komutlar',\n 'palette.goto': 'Yola git',\n 'palette.empty': 'Sonuç bulunamadı',\n 'palette.hint': '↑↓ gezin · Enter seç · Esc kapat',\n 'cmd.view_toggle': 'Görünümü değiştir (liste ⇄ ızgara)',\n 'cmd.trash': 'Çöp kutusunu aç',\n 'shortcuts.title': 'Klavye Kısayolları',\n 'shortcuts.group.nav': 'Gezinme',\n 'shortcuts.group.selection': 'Seçim',\n 'shortcuts.group.file': 'Dosya işlemleri',\n 'shortcuts.palette': 'Komut paleti',\n 'shortcuts.search': 'Aramaya odaklan',\n 'shortcuts.go_up': 'Üst klasöre çık',\n 'shortcuts.open': 'Seçili öğeyi aç',\n 'shortcuts.close': 'Kapat / vazgeç',\n 'shortcuts.help': 'Bu yardım penceresi',\n 'shortcuts.select_all': 'Tümünü seç',\n 'shortcuts.rename': 'Yeniden adlandır',\n 'shortcuts.delete': 'Sil',\n 'shortcuts.cut': 'Kes',\n 'shortcuts.copy': 'Kopyala',\n 'shortcuts.paste': 'Yapıştır',\n 'breadcrumb.more': 'Aradaki klasörler',\n\n // ——— State screens + undo snackbar + connection badge (cila:b) ———\n 'empty.hint': 'Dosyaları buraya sürükleyip bırakın',\n 'empty.upload': 'Dosya yükle',\n 'empty.search.title': 'Aramanla eşleşen dosya yok',\n 'empty.search.hint': 'Farklı bir arama terimi deneyin',\n 'empty.trash.title': 'Çöp kutusu boş',\n 'error.title': 'Liste yüklenemedi',\n 'error.retry': 'Yeniden dene',\n 'toast.undo': 'Geri Al',\n 'toast.undone': 'Geri alındı',\n 'toast.undo_failed': 'Geri alınamadı',\n 'toast.renamed': 'Yeniden adlandırıldı',\n 'toast.moved': 'Taşındı',\n 'toast.trashed': 'Çöpe taşındı',\n 'conn.offline': 'Canlı bağlantı yok — değişiklikler gecikebilir',\n 'conn.tooltip': 'Sunucuyla canlı bağlantı kurulamadı; liste belirli aralıklarla otomatik yenilenir. Bağlantı geri gelince bu uyarı kaybolur.',\n\n /* === bul:s3 === */\n 'palette.everywhere': 'Her yerde',\n 'palette.searching': 'Aranıyor…',\n 'palette.saved': 'Kayıtlı aramalar',\n 'palette.save': 'Aramayı kaydet',\n 'palette.saved.delete': 'Kayıtlı aramayı sil',\n 'search.in_content': 'İçerikte',\n\n /* === bag:b4 === */\n 'toolbar.more': 'Diğer işlemler',\n 'toolbar.search.close': 'Aramayı kapat',\n 'sheet.menu': 'İşlemler',\n 'sheet.close': 'Kapat',\n\n /* === koru:k1 === */\n 'toolbar.inspector': 'Ayrıntılar',\n 'ctx.details': 'Ayrıntılar',\n 'shortcuts.inspector': 'Ayrıntılar panelini aç/kapat',\n 'inspector.title': 'Ayrıntılar',\n 'inspector.close': 'Kapat',\n 'inspector.section.general': 'Genel',\n 'inspector.section.versions': 'Sürümler',\n 'inspector.section.permissions': 'İzinler',\n 'inspector.section.shares': 'Paylaşımlar',\n 'inspector.path': 'Yol',\n 'inspector.size': 'Boyut',\n 'inspector.modified': 'Değiştirilme',\n 'inspector.mime': 'MIME türü',\n 'inspector.etag': 'ETag',\n 'inspector.copy': 'Kopyala',\n 'inspector.copied': 'Kopyalandı',\n 'inspector.error': 'Yüklenemedi',\n 'inspector.items_summary': '{n} öğe, toplam {size}',\n 'inspector.folder_items': '{n} öğe',\n 'inspector.versions.empty': 'Sürüm geçmişi yok',\n 'inspector.versions.v': 'Sürüm {n}',\n 'inspector.versions.restore': 'Geri yükle',\n 'inspector.versions.restore_confirm': 'Bu sürüm geri yüklensin mi?',\n 'inspector.versions.snapshot_current': 'Önce şimdiki halin sürümünü al',\n 'inspector.versions.confirm': 'Onayla',\n 'inspector.versions.cancel': 'Vazgeç',\n 'inspector.versions.take_snapshot': 'Şimdiki halin sürümünü al',\n 'inspector.versions.restored': 'Sürüm geri yüklendi',\n 'inspector.versions.snapshotted': 'Sürüm alındı',\n 'inspector.versions.unsupported': 'Sunucu bu işlemi desteklemiyor',\n 'inspector.perm.none': 'Erişim yok',\n 'inspector.perm.viewer': 'Görüntüleyen',\n 'inspector.perm.editor': 'Düzenleyen',\n 'inspector.perm.owner': 'Sahip',\n 'inspector.perm.manage': 'İzinleri yönet',\n 'inspector.shares.empty': 'Paylaşım linki yok',\n 'inspector.shares.copy': 'Linki kopyala',\n};\n","/** English UI strings. */\nexport const en: Record<string, string> = {\n 'toolbar.new_folder': 'New Folder',\n 'toolbar.upload': 'Upload',\n 'toolbar.search': 'Search',\n 'toolbar.search.placeholder': 'File name…',\n 'toolbar.view.list': 'List',\n 'toolbar.view.grid': 'Grid',\n 'toolbar.refresh': 'Refresh',\n 'toolbar.go_up': 'Up one level',\n\n 'ctx.open': 'Open',\n 'ctx.preview': 'Preview',\n 'ctx.download': 'Download',\n 'ctx.convert': 'Convert',\n 'ctx.rename': 'Rename',\n 'ctx.delete': 'Delete',\n 'ctx.delete_perm': 'Delete Permanently',\n 'ctx.restore': 'Restore',\n 'ctx.share': 'Share',\n 'ctx.move': 'Move',\n 'ctx.copy': 'Copy',\n 'ctx.cut': 'Cut',\n 'ctx.paste': 'Paste',\n 'ctx.info': 'Info',\n 'ctx.duplicate': 'Duplicate',\n 'ctx.new_file': 'New File',\n\n 'modal.delete.title': 'Delete?',\n 'modal.delete.message': '{count} item(s) will be moved to trash.',\n 'modal.delete.confirm': 'Move to Trash',\n 'modal.delete.cancel': 'Cancel',\n\n 'modal.rename.title': 'Rename',\n 'modal.rename.save': 'Save',\n 'modal.rename.cancel': 'Cancel',\n\n 'modal.newfolder.title': 'New Folder',\n 'modal.newfolder.placeholder': 'Folder name',\n 'modal.newfolder.create': 'Create',\n 'modal.newfolder.cancel': 'Cancel',\n\n 'modal.share.title': 'Share Link',\n 'modal.share.pin': 'PIN protected',\n 'modal.share.expires': 'Expires at',\n 'modal.share.max_downloads': 'Download limit',\n 'modal.share.create': 'Share',\n 'modal.share.cancel': 'Cancel',\n 'modal.share.copy': 'Copy',\n 'modal.share.url_copied': 'Link copied',\n 'modal.share.pin_copied': 'PIN copied',\n 'modal.share.cli_copied': 'CLI command copied',\n\n 'upload.progress': 'Uploading',\n 'upload.done': 'Done',\n 'upload.error': 'Error',\n 'upload.aborted': 'Aborted',\n 'upload.cancel': 'Cancel',\n\n 'empty.folder': 'This folder is empty',\n 'empty.search': 'No results',\n 'loading': 'Loading…',\n\n 'notFound.title': 'Folder not found',\n 'notFound.desc': 'This folder does not exist, was moved, or you do not have access to it.',\n 'notFound.goRoot': 'Go to root folder',\n\n 'col.name': 'Name',\n 'col.size': 'Size',\n 'col.modified': 'Modified',\n 'col.type': 'Type',\n\n 'unit.bytes': 'B',\n 'unit.kb': 'KB',\n 'unit.mb': 'MB',\n 'unit.gb': 'GB',\n 'unit.tb': 'TB',\n\n 'breadcrumb.root': 'Root',\n 'breadcrumb.copy_path': 'Copy Path',\n 'breadcrumb.go_to_path': 'Go To Path',\n 'breadcrumb.path_placeholder': 'fileman/foo/bar',\n\n 'ops.copy': 'Copying',\n 'ops.move': 'Moving',\n 'ops.delete': 'Deleting',\n 'ops.queued': 'queued',\n 'ops.done': 'done',\n 'ops.error': 'error',\n\n 'node.trash': 'Trash',\n\n // ——— Rich viewer chrome ———\n 'viewer.open_in_new_tab': 'Open in New Tab',\n 'viewer.loading': 'Loading…',\n 'viewer.failed_to_load': 'Failed to load file',\n 'viewer.peer_not_installed': 'Optional viewer library is not installed. Install the peer dependency or use the download button.',\n 'viewer.format_unsupported_3d': 'This 3D format is not supported in the browser preview (model-viewer only reads .glb / .gltf / .usdz). Please download and open with a local tool.',\n 'viewer.zoom_in': 'Zoom in',\n 'viewer.zoom_out': 'Zoom out',\n 'viewer.fit_width': 'Fit width',\n 'viewer.next_page': 'Next page',\n 'viewer.prev_page': 'Previous page',\n 'viewer.page_n_of_m': 'Page {n} of {m}',\n 'viewer.tags': 'Tags',\n 'viewer.layers': 'Layers',\n 'viewer.toc': 'Contents',\n 'viewer.font_smaller': 'Smaller text',\n 'viewer.font_larger': 'Larger text',\n 'viewer.search': 'Search',\n 'viewer.download': 'Download',\n 'viewer.saving': 'Saving…',\n 'viewer.save': 'Save (Ctrl+S)',\n 'viewer.saved': 'Saved',\n 'viewer.save_error': 'Error',\n 'viewer.editor_loading': 'Loading editor…',\n 'viewer.no_preview': 'No preview for this file type yet.',\n 'viewer.edit': 'Edit',\n 'viewer.close': 'Close',\n 'presence.expand': 'Show names',\n 'presence.collapse': 'Collapse',\n 'viewer.save_annotations': 'Save annotations',\n 'viewer.annotations_on': 'Annotations: on',\n 'viewer.annotations_off': 'Annotations: off',\n 'viewer.read_only': 'Read only',\n 'viewer.csv_first_row_header': 'First row as header',\n 'viewer.csv_filter': 'Filter rows…',\n 'viewer.epub_prev': 'Previous',\n 'viewer.epub_next': 'Next',\n 'viewer.drawio.disabled': 'diagrams.net embed is not configured for this filex instance — operator must wire FILEX_DRAWIO_URL to enable the editor.',\n 'viewer.archive.entries': '{n} files',\n 'viewer.archive.empty': 'Archive is empty.',\n 'viewer.archive.error': 'Could not read archive contents.',\n 'viewer.name': 'Name',\n 'viewer.size': 'Size',\n\n // ——— cila:a — sorting / date groups / density ———\n 'col.sort': 'Sort',\n 'group.today': 'Today',\n 'group.yesterday': 'Yesterday',\n 'group.this_week': 'This Week',\n 'group.this_month': 'This Month',\n 'group.no_date': 'No date',\n 'toolbar.density.compact': 'Compact view',\n 'toolbar.density.comfortable': 'Comfortable view',\n\n // ——— cila:c — command palette + shortcuts help + breadcrumb ———\n 'palette.placeholder': 'Search files, folders or commands…',\n 'palette.files': 'Files',\n 'palette.commands': 'Commands',\n 'palette.goto': 'Go to path',\n 'palette.empty': 'No results',\n 'palette.hint': '↑↓ navigate · Enter select · Esc close',\n 'cmd.view_toggle': 'Toggle view (list ⇄ grid)',\n 'cmd.trash': 'Open trash',\n 'shortcuts.title': 'Keyboard Shortcuts',\n 'shortcuts.group.nav': 'Navigation',\n 'shortcuts.group.selection': 'Selection',\n 'shortcuts.group.file': 'File operations',\n 'shortcuts.palette': 'Command palette',\n 'shortcuts.search': 'Focus search',\n 'shortcuts.go_up': 'Go up one level',\n 'shortcuts.open': 'Open selected item',\n 'shortcuts.close': 'Close / cancel',\n 'shortcuts.help': 'This help dialog',\n 'shortcuts.select_all': 'Select all',\n 'shortcuts.rename': 'Rename',\n 'shortcuts.delete': 'Delete',\n 'shortcuts.cut': 'Cut',\n 'shortcuts.copy': 'Copy',\n 'shortcuts.paste': 'Paste',\n 'breadcrumb.more': 'Hidden folders',\n\n // ——— State screens + undo snackbar + connection badge (cila:b) ———\n 'empty.hint': 'Drag and drop files here',\n 'empty.upload': 'Upload files',\n 'empty.search.title': 'No files match your search',\n 'empty.search.hint': 'Try a different search term',\n 'empty.trash.title': 'Trash is empty',\n 'error.title': 'Could not load this folder',\n 'error.retry': 'Try again',\n 'toast.undo': 'Undo',\n 'toast.undone': 'Undone',\n 'toast.undo_failed': 'Could not undo',\n 'toast.renamed': 'Renamed',\n 'toast.moved': 'Moved',\n 'toast.trashed': 'Moved to trash',\n 'conn.offline': 'No live connection — changes may be delayed',\n 'conn.tooltip': 'Live connection to the server is unavailable; the list refreshes periodically. This notice disappears once the connection is back.',\n\n /* === bul:s3 === */\n 'palette.everywhere': 'Everywhere',\n 'palette.searching': 'Searching…',\n 'palette.saved': 'Saved searches',\n 'palette.save': 'Save search',\n 'palette.saved.delete': 'Delete saved search',\n 'search.in_content': 'In content',\n\n /* === bag:b4 === */\n 'toolbar.more': 'More actions',\n 'toolbar.search.close': 'Close search',\n 'sheet.menu': 'Actions',\n 'sheet.close': 'Close',\n\n /* === koru:k1 === */\n 'toolbar.inspector': 'Details',\n 'ctx.details': 'Details',\n 'shortcuts.inspector': 'Toggle details panel',\n 'inspector.title': 'Details',\n 'inspector.close': 'Close',\n 'inspector.section.general': 'General',\n 'inspector.section.versions': 'Versions',\n 'inspector.section.permissions': 'Permissions',\n 'inspector.section.shares': 'Shares',\n 'inspector.path': 'Path',\n 'inspector.size': 'Size',\n 'inspector.modified': 'Modified',\n 'inspector.mime': 'MIME type',\n 'inspector.etag': 'ETag',\n 'inspector.copy': 'Copy',\n 'inspector.copied': 'Copied',\n 'inspector.error': 'Could not load',\n 'inspector.items_summary': '{n} items, {size} total',\n 'inspector.folder_items': '{n} items',\n 'inspector.versions.empty': 'No version history',\n 'inspector.versions.v': 'Version {n}',\n 'inspector.versions.restore': 'Restore',\n 'inspector.versions.restore_confirm': 'Restore this version?',\n 'inspector.versions.snapshot_current': 'Snapshot the current state first',\n 'inspector.versions.confirm': 'Confirm',\n 'inspector.versions.cancel': 'Cancel',\n 'inspector.versions.take_snapshot': 'Snapshot current state',\n 'inspector.versions.restored': 'Version restored',\n 'inspector.versions.snapshotted': 'Snapshot taken',\n 'inspector.versions.unsupported': 'The server does not support this operation',\n 'inspector.perm.none': 'No access',\n 'inspector.perm.viewer': 'Viewer',\n 'inspector.perm.editor': 'Editor',\n 'inspector.perm.owner': 'Owner',\n 'inspector.perm.manage': 'Manage permissions',\n 'inspector.shares.empty': 'No share links',\n 'inspector.shares.copy': 'Copy link',\n};\n","/**\n * Locale message catalogue. The string-table is intentionally tiny — no\n * external i18n library, just a `t(key, vars?)` helper exposed via\n * `useLocale`.\n */\nimport { tr } from './tr';\nimport { en } from './en';\nimport type { LocaleCode } from '../types/ExplorerConfig';\n\nexport const messages: Record<LocaleCode, Record<string, string>> = { tr, en };\n\nexport { tr, en };\n","/**\n * useLocale — tr/en string table with a tiny `t()` helper.\n *\n * No i18n library — the catalogue is small enough to ship inline (see\n * src/locales).\n */\n\nimport { computed, type Ref } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { messages } from '../locales';\n\nexport function useLocale(localeRef: Ref<LocaleCode> | (() => LocaleCode)) {\n const lookup = computed(() => {\n const code = typeof localeRef === 'function' ? localeRef() : localeRef.value;\n return messages[code] ?? messages.tr;\n });\n\n function t(key: string, vars: Record<string, string | number> = {}): string {\n const raw = lookup.value[key] ?? key;\n return Object.entries(vars).reduce(\n (acc, [k, v]) => acc.replaceAll(`{${k}}`, String(v)),\n raw,\n );\n }\n\n function formatSize(bytes: number | undefined | null): string {\n if (bytes == null || bytes < 0) return '—';\n // A real zero (empty file / empty folder) is information, not absence.\n if (bytes === 0) return `0 ${t('unit.bytes')}`;\n const units: Array<[number, string]> = [\n [1024 ** 4, 'unit.tb'],\n [1024 ** 3, 'unit.gb'],\n [1024 ** 2, 'unit.mb'],\n [1024, 'unit.kb'],\n [1, 'unit.bytes'],\n ];\n for (const [div, key] of units) {\n if (bytes >= div) {\n const val = bytes / div;\n const rounded = val >= 100 ? Math.round(val) : val.toFixed(val >= 10 ? 1 : 2);\n return `${rounded} ${t(key)}`;\n }\n }\n return `${bytes} ${t('unit.bytes')}`;\n }\n\n /**\n * Render a FileNode's basename with locale-aware overrides:\n * - `.trash` directory → \"Çöp Kutusu\" / \"Trash\"\n * - Trash entries are stored as `<Ymd-His>-<rand>__<original>` so\n * listings inside .trash/ would otherwise show timestamps. Strip\n * that prefix so the user sees the original basename.\n */\n function nodeDisplayName(node: { basename: string }): string {\n if (node.basename === '.trash') return t('node.trash');\n const m = node.basename.match(/^\\d{8}-\\d{6}-[A-Za-z0-9]+__(.+)$/);\n if (m) return m[1];\n return node.basename;\n }\n\n return { t, formatSize, nodeDisplayName };\n}\n","/**\n * usePendingOps — track async copy/move/delete operations.\n *\n * Backend POST /files/{copy,move,delete} returns `{op}` immediately\n * (status='pending') and the actual S3 work runs in a worker. The\n * client polls `/files/ops` every 2s while there's anything still\n * pending or running so the user gets live feedback (\"3/5 kopyalandı\").\n *\n * Polling is reference-counted: callers `register(op)` after starting a\n * new op; an interval ticks while the registered set has any non-\n * terminal entries. Terminal ops (done/error) stay in the local cache\n * for `RETAIN_MS` so the UI can flash a final state before they fade\n * out, then a sweep removes them.\n */\n\nimport { computed, ref, onBeforeUnmount } from 'vue';\nimport type { ExplorerConfig } from '../types/ExplorerConfig';\nimport type { FileApi } from './useFileApi';\n\nexport interface PendingOp {\n id: number;\n op_type: 'copy' | 'move' | 'delete';\n status: 'pending' | 'running' | 'done' | 'error';\n progress_total: number;\n progress_done: number;\n target_path: string | null;\n source_dir: string | null;\n source_count: number;\n error_message: string | null;\n started_at: string | null;\n finished_at: string | null;\n created_at: string | null;\n}\n\nconst POLL_MS = 2000;\nconst RETAIN_MS = 8000;\n\n/**\n * normalizeOp maps the backend ops row (`{kind,total,done,failed,error,dest,\n * status:'ok'|'failed'|'partial'|…}`) onto the PendingOp contract the tray\n * renders (`{op_type,progress_total,progress_done,error_message,status:'done'|\n * 'error'|…}`). Without this the tray showed \"undefined/undefined\" for a\n * running op (progress_* were undefined) and never treated an 'ok'/'failed'\n * row as terminal. Tolerant of an already-normalized shape (idempotent).\n */\nfunction normalizeOp(raw: Record<string, unknown>): PendingOp {\n const num = (...vals: unknown[]): number => {\n for (const v of vals) if (typeof v === 'number') return v;\n return 0;\n };\n const str = (...vals: unknown[]): string | null => {\n for (const v of vals) if (typeof v === 'string' && v !== '') return v;\n return null;\n };\n const rawStatus = String(raw.status ?? 'pending');\n const status: PendingOp['status'] =\n rawStatus === 'ok' || rawStatus === 'done'\n ? 'done'\n : rawStatus === 'failed' || rawStatus === 'partial' || rawStatus === 'error'\n ? 'error'\n : rawStatus === 'running'\n ? 'running'\n : 'pending';\n const sources = Array.isArray(raw.sources) ? raw.sources : [];\n const opType = str(raw.op_type, raw.kind) ?? 'delete';\n return {\n id: num(raw.id),\n op_type: (opType === 'copy' || opType === 'move' ? opType : 'delete') as PendingOp['op_type'],\n status,\n progress_total: num(raw.progress_total, raw.total, sources.length),\n progress_done: num(raw.progress_done, raw.done),\n target_path: str(raw.target_path, raw.dest),\n source_dir: str(raw.source_dir),\n source_count: num(raw.source_count, sources.length),\n error_message: str(raw.error_message, raw.error),\n started_at: str(raw.started_at),\n finished_at: str(raw.finished_at),\n created_at: str(raw.created_at),\n };\n}\n\nexport interface UsePendingOpsOptions {\n /** Called once an op flips into a terminal state (done|error). */\n onSettled?: (op: PendingOp) => void;\n}\n\nexport function usePendingOps(\n config: ExplorerConfig,\n api: FileApi,\n opts: UsePendingOpsOptions = {},\n) {\n void config; // kept for future per-instance config knobs\n const ops = ref<PendingOp[]>([]);\n const announced = new Set<number>();\n const settledAt = new Map<number, number>();\n // First poll after mount returns the server's recent-history window\n // (last 5 min of done/error rows). Mark them announced silently and\n // skip the callback so we don't double-fire toasts on F5.\n let firstPollDone = false;\n\n const hasActive = computed(() =>\n ops.value.some((o) => o.status === 'pending' || o.status === 'running'),\n );\n\n let timer: ReturnType<typeof setInterval> | undefined;\n\n function startPolling() {\n if (timer) return;\n if (!api.endpoints.opsList) return;\n timer = setInterval(() => {\n void poll();\n }, POLL_MS);\n // Kick a poll right away.\n void poll();\n }\n\n function stopPolling() {\n if (timer) {\n clearInterval(timer);\n timer = undefined;\n }\n }\n\n async function poll(): Promise<void> {\n if (!api.endpoints.opsList) return;\n try {\n const res = await api.jsonFetch<{ ops: Record<string, unknown>[] }>(api.endpoints.opsList);\n const incoming = (res.ops || []).map(normalizeOp);\n\n for (const op of incoming) {\n if ((op.status === 'done' || op.status === 'error') && !announced.has(op.id)) {\n announced.add(op.id);\n settledAt.set(op.id, Date.now());\n if (firstPollDone) {\n opts.onSettled?.(op);\n }\n }\n }\n\n // Filter incoming: pending/running always; settled only if user\n // is currently seeing them in the local tray.\n const localIds = new Set(ops.value.map((o) => o.id));\n const visibleIncoming = incoming.filter((op) => {\n if (op.status === 'pending' || op.status === 'running') return true;\n if (!firstPollDone) return false;\n return localIds.has(op.id);\n });\n\n const visibleIds = new Set(visibleIncoming.map((o) => o.id));\n const local = ops.value.filter((o) => !visibleIds.has(o.id));\n const merged = [...visibleIncoming, ...local];\n\n firstPollDone = true;\n\n // Sweep: drop terminal ops past RETAIN_MS.\n const now = Date.now();\n const after = merged.filter((o) => {\n if (o.status === 'pending' || o.status === 'running') return true;\n const at = settledAt.get(o.id);\n return at !== undefined && now - at < RETAIN_MS;\n });\n ops.value = after;\n\n if (!hasActive.value && after.length === 0) {\n stopPolling();\n }\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn('[usePendingOps] poll failed:', err);\n }\n }\n\n function register(raw: PendingOp | Record<string, unknown>): void {\n const op = normalizeOp(raw as Record<string, unknown>);\n const exists = ops.value.some((o) => o.id === op.id);\n if (!exists) {\n ops.value = [op, ...ops.value];\n }\n startPolling();\n }\n\n function dismiss(id: number): void {\n ops.value = ops.value.filter((o) => o.id !== id);\n settledAt.delete(id);\n }\n\n onBeforeUnmount(() => {\n stopPolling();\n });\n\n return {\n ops,\n hasActive,\n register,\n dismiss,\n poll,\n startPolling,\n stopPolling,\n };\n}\n","// Realtime (WebSocket) client for filex live collaboration, bundled into the\n// core explorer so EVERY consumer — the native panel AND the vendored\n// webcomponent embedded in host apps — gets live folder updates + presence.\n//\n// Auth: the browser's native WebSocket can't set an Authorization header and,\n// when embedded, connects cross-origin to fm.brf.sh. So instead of a header we\n// fetch a short-lived, single-use TICKET through the host's normal API (which\n// injects the real token server-side) and open `wss://…/api/ws?ticket=<t>`.\n// The durable token never reaches the browser.\n//\n// Degradation: if the ticket or the socket is unavailable (old backend, blocked\n// upgrade, unsupported env), `onFallback(true)` fires so the consumer can fall\n// back to plain API polling. The page always keeps working — every send is\n// guarded, connect() is wrapped, reconnects are capped.\n\nexport interface PresenceUser {\n id: number;\n /** Stable identity key from the server (user id + optional per-end-user\n * presence key). Distinguishes end users sharing one proxy token — use it\n * for list keys and colours instead of `id`. */\n uid?: string;\n name: string;\n file?: string;\n}\n\nexport interface ChangeMessage {\n type: 'change';\n path: string;\n action: string; // create | delete | rename | move | upload | modify\n name?: string;\n new_name?: string;\n}\n\nexport interface PresenceMessage {\n type: 'presence';\n path: string;\n users: PresenceUser[];\n}\n\nexport interface WsTicket {\n ticket: string;\n ws_url: string;\n}\n\nexport interface RealtimeHandlers {\n onChange?: (msg: ChangeMessage) => void;\n onPresence?: (msg: PresenceMessage) => void;\n onStatus?: (connected: boolean) => void;\n /** Fires true when the live socket is unavailable (consumer should poll),\n * false when a live socket is (re)established. */\n onFallback?: (active: boolean) => void;\n}\n\nexport interface RealtimeOptions {\n /** Fetch a fresh ticket (single-use) via the host API. null → no live socket. */\n getTicket: () => Promise<WsTicket | null>;\n handlers: RealtimeHandlers;\n}\n\nconst PING_INTERVAL_MS = 25_000;\nconst MAX_BACKOFF_MS = 15_000;\nconst MAX_RETRIES = 6;\n\nexport class RealtimeClient {\n private ws: WebSocket | null = null;\n private opts: RealtimeOptions;\n private closed = false;\n private connecting = false;\n private retries = 0;\n private fallback = false;\n private pingTimer: ReturnType<typeof setInterval> | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Last-known intent, replayed on (re)connect.\n private currentPath: string | null = null;\n private currentFocus: string | null = null;\n\n constructor(opts: RealtimeOptions) {\n this.opts = opts;\n void this.connect();\n }\n\n /** Subscribe to a folder (\"<adapter>://<dir>\"). Swaps the active room and\n * resets focus. Passing null unsubscribes (drive list / trash have no room). */\n subscribe(path: string | null): void {\n this.currentPath = path;\n this.currentFocus = null;\n if (path) this.send({ type: 'subscribe', path });\n }\n\n /** Report the file the user is focused on (or null to clear). */\n setFocus(file: string | null): void {\n this.currentFocus = file;\n this.send({ type: 'focus', file });\n }\n\n /** Tear down permanently — call on unmount. */\n close(): void {\n this.closed = true;\n this.clearTimers();\n this.dropSocket();\n }\n\n private async connect(): Promise<void> {\n if (this.closed || this.connecting || this.ws) return;\n this.connecting = true;\n let ticket: WsTicket | null = null;\n try {\n ticket = await this.opts.getTicket();\n } catch {\n ticket = null;\n }\n this.connecting = false;\n if (this.closed) return;\n if (!ticket || !ticket.ticket || !ticket.ws_url) {\n this.fail();\n return;\n }\n\n const sep = ticket.ws_url.includes('?') ? '&' : '?';\n let ws: WebSocket;\n try {\n ws = new WebSocket(`${ticket.ws_url}${sep}ticket=${encodeURIComponent(ticket.ticket)}`);\n } catch {\n this.fail();\n return;\n }\n this.ws = ws;\n\n ws.onopen = () => {\n this.retries = 0;\n this.setFallback(false);\n this.opts.handlers.onStatus?.(true);\n if (this.currentPath) this.send({ type: 'subscribe', path: this.currentPath });\n if (this.currentFocus !== null) this.send({ type: 'focus', file: this.currentFocus });\n this.startPing();\n };\n\n ws.onmessage = (ev: MessageEvent) => {\n let msg: unknown;\n try {\n msg = JSON.parse(typeof ev.data === 'string' ? ev.data : '');\n } catch {\n return;\n }\n const m = msg as { type?: string };\n if (m?.type === 'change') this.opts.handlers.onChange?.(msg as ChangeMessage);\n else if (m?.type === 'presence') this.opts.handlers.onPresence?.(msg as PresenceMessage);\n // pong / error frames are intentionally ignored by the UI.\n };\n\n ws.onerror = () => {\n // onclose fires next; reconnect is handled there.\n };\n\n ws.onclose = () => {\n this.stopPing();\n this.ws = null;\n this.opts.handlers.onStatus?.(false);\n this.fail();\n };\n }\n\n // fail schedules a capped reconnect; after MAX_RETRIES it gives up on the live\n // socket and flips to fallback (polling) mode.\n private fail(): void {\n if (this.closed || this.reconnectTimer) return;\n if (this.retries >= MAX_RETRIES) {\n this.setFallback(true);\n return;\n }\n const delay = Math.min(1000 * 2 ** this.retries, MAX_BACKOFF_MS);\n this.retries += 1;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n void this.connect();\n }, delay);\n }\n\n private setFallback(active: boolean): void {\n if (this.fallback === active) return;\n this.fallback = active;\n this.opts.handlers.onFallback?.(active);\n }\n\n private send(obj: unknown): void {\n const ws = this.ws;\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n try {\n ws.send(JSON.stringify(obj));\n } catch {\n /* a failed send just means a missed live update */\n }\n }\n\n private startPing(): void {\n this.stopPing();\n this.pingTimer = setInterval(() => this.send({ type: 'ping' }), PING_INTERVAL_MS);\n }\n\n private stopPing(): void {\n if (this.pingTimer) {\n clearInterval(this.pingTimer);\n this.pingTimer = null;\n }\n }\n\n private dropSocket(): void {\n if (this.ws) {\n try {\n this.ws.onclose = null; // suppress reconnect\n this.ws.close();\n } catch {\n /* ignore */\n }\n this.ws = null;\n }\n }\n\n private clearTimers(): void {\n this.stopPing();\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n}\n","// useRealtime wires the folder-scoped live-collaboration layer (RealtimeClient)\n// into the explorer: it turns change events into a debounced soft reload, tracks\n// per-folder presence, and — when no live socket is available — falls back to\n// plain API polling so embedded/offline consumers still get near-live updates.\n//\n// The explorer calls start()/stop() on mount/unmount, subscribe() on folder\n// navigation, and setFocus() on selection; it binds presenceUsers into the UI.\n\nimport { ref, type Ref } from 'vue';\nimport { RealtimeClient, type PresenceUser, type PresenceMessage } from '../lib/realtime';\n\nconst RELOAD_DEBOUNCE_MS = 200;\nconst POLL_INTERVAL_MS = 12_000;\n\nexport interface RealtimeApi {\n wsTicket: () => Promise<{ ticket: string; ws_url: string } | null>;\n}\n\nexport function useRealtime(api: RealtimeApi, opts: { reload: () => void }) {\n const presenceUsers: Ref<PresenceUser[]> = ref([]);\n const connected = ref(false);\n // True while the live socket is unavailable and the polling fallback is\n // active — the explorer surfaces a small \"no live connection\" badge from it.\n // Stays false during ordinary reconnect attempts, so brief blips don't flash\n // the badge; only a genuinely given-up socket (RealtimeClient onFallback)\n // flips it.\n const degraded = ref(false);\n\n let client: RealtimeClient | null = null;\n let pendingSubscribe: string | null = null;\n let reloadTimer: ReturnType<typeof setTimeout> | null = null;\n let pollTimer: ReturnType<typeof setInterval> | null = null;\n\n function debouncedReload(): void {\n // A burst of change frames (e.g. a multi-file upload) collapses into one\n // soft reload of the current folder.\n if (reloadTimer) clearTimeout(reloadTimer);\n reloadTimer = setTimeout(() => {\n reloadTimer = null;\n opts.reload();\n }, RELOAD_DEBOUNCE_MS);\n }\n\n function onPresence(msg: PresenceMessage): void {\n // Ignore late frames for a folder we've already navigated away from.\n if (pendingSubscribe && msg.path && msg.path !== pendingSubscribe) return;\n presenceUsers.value = Array.isArray(msg.users) ? msg.users : [];\n }\n\n function onFallback(active: boolean): void {\n degraded.value = active;\n if (active) {\n // No live socket → poll the listing; presence isn't available here.\n presenceUsers.value = [];\n if (!pollTimer) pollTimer = setInterval(() => opts.reload(), POLL_INTERVAL_MS);\n } else if (pollTimer) {\n clearInterval(pollTimer);\n pollTimer = null;\n }\n }\n\n function start(): void {\n if (client) return;\n client = new RealtimeClient({\n getTicket: () => api.wsTicket(),\n handlers: {\n onChange: debouncedReload,\n onPresence,\n onFallback,\n onStatus: (c) => {\n connected.value = c;\n },\n },\n });\n }\n\n function subscribe(wire: string | null): void {\n presenceUsers.value = []; // drop the previous folder's roster immediately\n pendingSubscribe = wire;\n client?.subscribe(wire);\n }\n\n function setFocus(file: string | null): void {\n client?.setFocus(file);\n }\n\n function stop(): void {\n if (reloadTimer) {\n clearTimeout(reloadTimer);\n reloadTimer = null;\n }\n if (pollTimer) {\n clearInterval(pollTimer);\n pollTimer = null;\n }\n client?.close();\n client = null;\n degraded.value = false;\n }\n\n return { presenceUsers, connected, degraded, start, subscribe, setFocus, stop };\n}\n","// useThumbs — authenticated thumbnail loader for the grid view.\n//\n// The backend emits `thumb_url` as a ROOT-RELATIVE path (\"/api/files/thumb/{id}\").\n// A plain `<img src>` only works for the native same-origin SPA: an embedded\n// webcomponent resolves it against the HOST page's origin (work.brf.sh → 404)\n// and, even with the URL fixed, `<img>` cannot carry the bearer header a\n// proxied host (fishapp PWA) requires. So thumbs are fetched through the same\n// auth machinery as every API call (headers + credentials), cached as object\n// URLs, and handed to the grid; a failed fetch falls back to the file icon.\n\nimport { ref } from 'vue';\nimport type { FileNode } from '../types/FileNode';\n\ninterface ThumbApiSlice {\n authHeaders: (extra?: Record<string, string>) => Promise<Record<string, string>>;\n credentialsMode: () => RequestCredentials;\n}\n\n/** Cap the object-URL cache; beyond it oldest entries are revoked. Thumbs are\n * small (~KBs) so this is generous while still bounding a long session. */\nconst MAX_CACHED = 500;\n\nexport function useThumbs(apiBase: string | undefined, api: ThumbApiSlice) {\n const urls = ref<Record<string, string>>({});\n const order: string[] = [];\n const failed = new Set<string>();\n const pending = new Set<string>();\n\n function resolveUrl(raw: string): string {\n if (/^https?:\\/\\//i.test(raw)) return raw;\n const base = (apiBase || '').replace(/\\/+$/, '');\n return base && raw.startsWith('/') ? base + raw : raw;\n }\n\n /** Reactive: returns the loaded object URL for the node's thumb, kicking off\n * the fetch on first sight. null = not (yet) available → show the icon. */\n function src(n: FileNode): string | null {\n const raw = n.thumb_url;\n if (!raw) return null;\n const got = urls.value[raw];\n if (got) return got;\n if (!failed.has(raw) && !pending.has(raw)) void load(raw);\n return null;\n }\n\n async function load(raw: string): Promise<void> {\n pending.add(raw);\n try {\n const res = await fetch(resolveUrl(raw), {\n headers: await api.authHeaders({ Accept: '*/*' }),\n credentials: api.credentialsMode(),\n });\n if (!res.ok) throw new Error(String(res.status));\n const blob = await res.blob();\n if (order.length >= MAX_CACHED) {\n const evict = order.shift();\n if (evict && urls.value[evict]) {\n URL.revokeObjectURL(urls.value[evict]);\n const next = { ...urls.value };\n delete next[evict];\n urls.value = next;\n }\n }\n order.push(raw);\n urls.value = { ...urls.value, [raw]: URL.createObjectURL(blob) };\n } catch {\n // 404 (thumb evicted server-side) or auth hiccup — icon fallback, and we\n // don't retry within this session to avoid hammering.\n failed.add(raw);\n } finally {\n pending.delete(raw);\n }\n }\n\n return { src };\n}\n","/**\n * useMonacoLoader — fire-and-forget Monaco preloader.\n *\n * The preview/edit flow wants Monaco when available (best-in-class\n * editor) and highlight.js for read-only syntax colour as a graceful\n * fallback. Monaco is heavy (~5 MB), so we kick off the dynamic import\n * at module-init time — by the time the user clicks \"edit\" on a code\n * file (typically several seconds in), the chunk is already cached.\n *\n * - `monacoPromise` resolves to the Monaco namespace, or `null`\n * if the package is not installed (peer\n * missing) / load fails.\n * - `highlightPromise` resolves to the highlight.js export, or\n * `null` similarly.\n * - `getMonaco()` returns the cached module synchronously\n * (after `await monacoPromise`) so a click\n * handler doesn't re-trigger the import.\n *\n * Both modules are externalized in the bundler config — the consumer\n * either declares them as direct deps (Monaco UX) or doesn't (the\n * highlight.js read-only path takes over). No build-time hard dep here.\n */\n\nlet monacoPromise: Promise<unknown | null> | null = null;\nlet highlightPromise: Promise<unknown | null> | null = null;\nlet monacoCached: unknown | null = null;\nlet highlightCached: unknown | null = null;\n\n/**\n * Kick off the Monaco import the first time someone calls\n * `preloadEditor()` (typically the FileExplorer onMounted hook). Cheap\n * to call repeatedly — only the first call actually triggers the\n * dynamic import.\n */\nexport function preloadEditor(): void {\n if (!monacoPromise) {\n monacoPromise = import(/* @vite-ignore */ 'monaco-editor')\n .then((mod) => {\n monacoCached = (mod as { default?: unknown }).default ?? mod;\n return monacoCached;\n })\n .catch(() => {\n monacoCached = null;\n return null;\n });\n }\n if (!highlightPromise) {\n highlightPromise = import(/* @vite-ignore */ 'highlight.js')\n .then((mod) => {\n highlightCached = (mod as { default?: unknown }).default ?? mod;\n return highlightCached;\n })\n .catch(() => {\n highlightCached = null;\n return null;\n });\n }\n}\n\n/**\n * Resolve Monaco. If preload hasn't been kicked off yet, this triggers\n * it (and pays the load cost on the spot). Returns `null` when the\n * package isn't installed.\n */\nexport async function ensureMonaco(): Promise<unknown | null> {\n if (!monacoPromise) preloadEditor();\n return monacoPromise!;\n}\n\nexport async function ensureHighlight(): Promise<unknown | null> {\n if (!highlightPromise) preloadEditor();\n return highlightPromise!;\n}\n\n/** Synchronous cached lookup — null if Monaco not yet ready or absent. */\nexport function getMonaco(): unknown | null {\n return monacoCached;\n}\n\nexport function getHighlight(): unknown | null {\n return highlightCached;\n}\n\n/**\n * Composable wrapper — components that want reactive \"is Monaco ready\n * yet?\" semantics can read the resolved promise. The implementation is\n * intentionally tiny: components don't need anything fancier than\n * `await ensureMonaco()` inside the click handler.\n */\nexport function useMonacoLoader() {\n preloadEditor();\n return {\n ensureMonaco,\n ensureHighlight,\n getMonaco,\n getHighlight,\n };\n}\n","<script setup lang=\"ts\">\n// PresenceBar — compact avatar strip showing who else is viewing the current\n// folder, and (as a small badge) which file each person is focused on. The\n// server already excludes the recipient from the roster (presence answers\n// \"who ELSE is here\"); the optional selfId filter remains as a belt-and-braces\n// for older backends. Purely presentational; the live data comes from the\n// realtime presence stream.\n\nimport { computed, ref } from 'vue';\nimport type { PresenceUser } from '../lib/realtime';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\n\nconst props = defineProps<{\n users: PresenceUser[];\n selfId?: number | null;\n locale?: LocaleCode;\n}>();\n\nconst { t } = useLocale(() => props.locale ?? 'tr');\n\nconst others = computed(() =>\n (props.users ?? []).filter((u) => props.selfId == null || u.id !== props.selfId),\n);\n\n// Compact (avatar strip) ⇄ expanded (scrollable name chips). With many users\n// the strip collapses to \"+N\", so the expanded mode is how you actually READ\n// who is here; the choice sticks for the session via localStorage.\nconst EXPAND_KEY = 'filex.presence.expanded';\nconst expanded = ref<boolean>((() => {\n try {\n return localStorage.getItem(EXPAND_KEY) === '1';\n } catch {\n return false;\n }\n})());\nfunction toggleExpanded(): void {\n expanded.value = !expanded.value;\n try {\n localStorage.setItem(EXPAND_KEY, expanded.value ? '1' : '0');\n } catch {\n /* private mode — session-only */\n }\n}\n\n// Stable key per identity: end users behind one shared proxy token have the\n// same numeric id but distinct server-issued uids.\nfunction keyOf(u: PresenceUser): string {\n return u.uid ?? String(u.id);\n}\n\nfunction initials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '?';\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n}\n\n// Deterministic hue per identity so the same person keeps the same colour.\nfunction hue(u: PresenceUser): number {\n const s = keyOf(u);\n let h = 0;\n for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) >>> 0;\n return h % 360;\n}\n\nfunction label(u: PresenceUser): string {\n return u.file ? `${u.name} · ${u.file}` : u.name;\n}\n</script>\n\n<template>\n <div v-if=\"others.length\" class=\"fx-presence\" :class=\"{ 'fx-presence--wide': expanded }\">\n <!-- Expanded: every user as an avatar+name chip in a horizontally\n scrollable row — names stay fully readable however many join. -->\n <div v-if=\"expanded\" class=\"fx-presence-chips\">\n <span\n v-for=\"u in others\"\n :key=\"keyOf(u)\"\n class=\"fx-presence-chip\"\n :title=\"label(u)\"\n >\n <span\n class=\"fx-presence-avatar\"\n :style=\"{ backgroundColor: `hsl(${hue(u)} 60% 45%)` }\"\n >\n {{ initials(u.name) }}\n <span v-if=\"u.file\" class=\"fx-presence-dot\" aria-hidden=\"true\"></span>\n </span>\n <span class=\"fx-presence-chip-name\">{{ u.name }}</span>\n <span v-if=\"u.file\" class=\"fx-presence-chip-file\">· {{ u.file }}</span>\n </span>\n </div>\n\n <!-- Compact: the classic overlapping avatar strip. -->\n <template v-else>\n <div class=\"fx-presence-avatars\" :title=\"others.map(label).join(', ')\">\n <span\n v-for=\"u in others.slice(0, 5)\"\n :key=\"keyOf(u)\"\n class=\"fx-presence-avatar\"\n :style=\"{ backgroundColor: `hsl(${hue(u)} 60% 45%)` }\"\n :title=\"label(u)\"\n >\n {{ initials(u.name) }}\n <span v-if=\"u.file\" class=\"fx-presence-dot\" aria-hidden=\"true\"></span>\n </span>\n <span v-if=\"others.length > 5\" class=\"fx-presence-more\">+{{ others.length - 5 }}</span>\n </div>\n <span class=\"fx-presence-text\" :title=\"others.map(label).join(', ')\">\n {{ others.length === 1 ? others[0].name : `${others.length} kişi` }}\n <template v-if=\"others.length === 1 && others[0].file\">\n · <span class=\"fx-presence-file\">{{ others[0].file }}</span>\n </template>\n </span>\n </template>\n\n <button\n type=\"button\"\n class=\"fx-presence-toggle\"\n :title=\"expanded ? t('presence.collapse') : t('presence.expand')\"\n :aria-expanded=\"expanded\"\n @click=\"toggleExpanded\"\n >{{ expanded ? '‹' : '›' }}</button>\n </div>\n</template>\n\n<style scoped>\n.fx-presence {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n max-width: 100%;\n}\n.fx-presence-avatars {\n display: inline-flex;\n align-items: center;\n}\n.fx-presence-avatar {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.5rem;\n height: 1.5rem;\n margin-left: -0.4rem;\n border-radius: 9999px;\n border: 2px solid var(--fx-presence-ring, #ffffff);\n color: #fff;\n font-size: 0.6rem;\n font-weight: 600;\n line-height: 1;\n user-select: none;\n}\n.fx-presence-avatar:first-child {\n margin-left: 0;\n}\n.fx-presence-dot {\n position: absolute;\n right: -1px;\n bottom: -1px;\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 9999px;\n background: #22c55e; /* green — actively focused on a file */\n border: 1.5px solid var(--fx-presence-ring, #ffffff);\n}\n.fx-presence-more {\n margin-left: 0.15rem;\n font-size: 0.7rem;\n color: rgb(113 113 122); /* zinc-500 */\n}\n.fx-presence--wide {\n flex: 1 1 auto;\n min-width: 0;\n}\n.fx-presence-chips {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n overflow-x: auto;\n min-width: 0;\n padding-bottom: 2px; /* keep the scrollbar off the chips */\n scrollbar-width: thin;\n}\n.fx-presence-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n flex: 0 0 auto;\n padding: 0.15rem 0.5rem 0.15rem 0.2rem;\n border-radius: 9999px;\n background: rgb(244 244 245); /* zinc-100 */\n font-size: 0.75rem;\n color: rgb(63 63 70); /* zinc-700 */\n white-space: nowrap;\n}\n.fx-presence-chip .fx-presence-avatar {\n margin-left: 0;\n}\n.fx-presence-chip-name {\n font-weight: 500;\n}\n.fx-presence-chip-file {\n color: rgb(113 113 122); /* zinc-500 */\n max-width: 12rem;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.fx-presence-toggle {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.25rem;\n height: 1.25rem;\n border: none;\n border-radius: 9999px;\n background: transparent;\n color: rgb(113 113 122); /* zinc-500 */\n font-size: 0.9rem;\n line-height: 1;\n cursor: pointer;\n}\n.fx-presence-toggle:hover {\n background: rgb(228 228 231); /* zinc-200 */\n color: rgb(63 63 70);\n}\n:global(.dark) .fx-presence-chip {\n background: rgb(39 39 42); /* zinc-800 */\n color: rgb(212 212 216); /* zinc-300 */\n}\n:global(.dark) .fx-presence-toggle:hover {\n background: rgb(39 39 42);\n color: rgb(212 212 216);\n}\n.fx-presence-text {\n font-size: 0.75rem;\n color: rgb(113 113 122); /* zinc-500 */\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 14rem;\n}\n.fx-presence-file {\n color: rgb(82 82 91); /* zinc-600 */\n font-weight: 500;\n}\n:global(.dark) .fx-presence-avatar,\n:global(.dark) .fx-presence-dot {\n --fx-presence-ring: #18181b; /* zinc-900 */\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * ContextMenu — Teleport-based menu.\n *\n * Teleported under <body> so no parent (Ionic <ion-page>, Filament's\n * transformed flex containers, panel sidebars, …) can shift the\n * `position: fixed` backdrop off-window.\n */\nimport { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue';\nimport type { LocaleCode, ThemeMode } from '../types/ExplorerConfig';\nimport type { FileNode } from '../types/FileNode';\nimport { useLocale } from '../composables/useLocale';\n\nexport interface ContextAction {\n key: string;\n label: string;\n icon?: string;\n danger?: boolean;\n disabled?: boolean;\n hidden?: boolean;\n divider?: boolean;\n}\n\nconst props = defineProps<{\n locale: LocaleCode;\n actions: ContextAction[];\n /**\n * Resolved theme. Teleported into <body> we lose the `.fe` parent\n * that scopes CSS vars, so we tag the backdrop with the current\n * theme so variables.css can re-apply dark overrides outside the\n * explorer tree.\n */\n theme?: ThemeMode;\n /**\n * bag:b4 — bottom-sheet presentation for coarse-pointer (touch)\n * contexts. When true the menu renders as a full-width sheet sliding\n * up from the bottom edge (grab handle, ≥44px touch targets; closed\n * by overlay tap, dragging the handle down, or Esc). The position\n * passed to show() is ignored. When absent/false the classic anchored\n * menu renders — desktop right-click behavior is untouched.\n */\n sheet?: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: 'select', action: ContextAction, target: FileNode[]): void;\n}>();\n\nconst { t } = useLocale(() => props.locale); // bag:b4 — sheet aria labels need t()\n\nconst open = ref(false);\nconst x = ref(0);\nconst y = ref(0);\nconst targetNodes = ref<FileNode[]>([]);\nconst menuEl = ref<HTMLElement | null>(null);\n\nasync function show(ev: { clientX: number; clientY: number }, nodes: FileNode[]) {\n open.value = true;\n x.value = ev.clientX;\n y.value = ev.clientY;\n targetNodes.value = nodes;\n // After the menu renders, clamp it inside the viewport so a click near the\n // bottom/right edge doesn't push the menu off-screen (it opens down-right\n // from the cursor by default).\n await nextTick();\n if (props.sheet) {\n // bag:b4 — sheet mode: no anchoring; focus the panel so Esc closes it\n // without requiring a prior click inside.\n sheetEl.value?.focus();\n return;\n }\n clampToViewport();\n}\n\nfunction clampToViewport() {\n const el = menuEl.value;\n if (!el || typeof window === 'undefined') return;\n const rect = el.getBoundingClientRect();\n const margin = 8;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n if (y.value + rect.height > vh - margin) {\n y.value = Math.max(margin, vh - rect.height - margin);\n }\n if (x.value + rect.width > vw - margin) {\n x.value = Math.max(margin, vw - rect.width - margin);\n }\n}\n\nfunction hide() {\n open.value = false;\n /* bag:b4 — reset any in-flight sheet drag so reopening starts clean. */\n sheetDragging.value = false;\n sheetDragY.value = 0;\n}\n\n/* bag:b4 — sheet drag-to-dismiss. Bound to the grab handle only, so the\n * scrollable item list keeps its native touch scrolling. Dragging past the\n * threshold closes; anything less snaps back. */\nconst sheetEl = ref<HTMLElement | null>(null);\nconst sheetDragging = ref(false);\nconst sheetDragY = ref(0);\nlet sheetDragStart = 0;\n\nfunction onSheetDragStart(e: TouchEvent) {\n const t0 = e.touches[0];\n if (!t0) return;\n sheetDragging.value = true;\n sheetDragStart = t0.clientY;\n sheetDragY.value = 0;\n}\nfunction onSheetDragMove(e: TouchEvent) {\n if (!sheetDragging.value) return;\n const t0 = e.touches[0];\n if (!t0) return;\n sheetDragY.value = Math.max(0, t0.clientY - sheetDragStart);\n}\nfunction onSheetDragEnd() {\n if (!sheetDragging.value) return;\n const shouldClose = sheetDragY.value > 72;\n sheetDragging.value = false;\n if (shouldClose) {\n hide();\n } else {\n sheetDragY.value = 0;\n }\n}\nconst sheetStyle = computed(() =>\n sheetDragY.value > 0\n ? { transform: `translateY(${sheetDragY.value}px)`, transition: 'none' }\n : undefined,\n);\n/* /bag:b4 */\n\nfunction pick(a: ContextAction) {\n if (a.disabled) return;\n emit('select', a, targetNodes.value);\n hide();\n}\n\nfunction onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') hide();\n}\n\nconst visibleActions = computed(() => props.actions.filter((a) => !a.hidden));\n\nconst prefersDark = ref(false);\nlet mq: MediaQueryList | undefined;\nfunction syncPrefersDark(e?: MediaQueryListEvent | MediaQueryList) {\n prefersDark.value = !!(e && 'matches' in e && e.matches);\n}\nonMounted(() => {\n if (typeof window === 'undefined') return;\n mq = window.matchMedia('(prefers-color-scheme: dark)');\n syncPrefersDark(mq);\n mq.addEventListener?.('change', syncPrefersDark);\n});\nonBeforeUnmount(() => {\n mq?.removeEventListener?.('change', syncPrefersDark);\n});\n\nconst themeClass = computed(() => {\n const t = props.theme || 'auto';\n return `fe-ctx-backdrop--theme-${t}`;\n});\n\ndefineExpose({ show, hide });\n</script>\n\n<template>\n <Teleport to=\"body\">\n <transition :name=\"sheet ? 'fe-sheet' : 'fe-ctx'\">\n <div\n v-if=\"open\"\n class=\"fe-ctx-backdrop\"\n :class=\"[themeClass, { 'fe-ctx-backdrop--sheet': sheet }]\"\n :data-prefers-dark=\"prefersDark ? '1' : '0'\"\n @click=\"hide\"\n @contextmenu.prevent=\"hide\"\n @keydown=\"onKey\"\n >\n <!-- bag:b4 — bottom-sheet variant (coarse pointer / touch) -->\n <div\n v-if=\"sheet\"\n ref=\"sheetEl\"\n class=\"fe-sheet\"\n role=\"menu\"\n :aria-label=\"t('sheet.menu')\"\n tabindex=\"-1\"\n :style=\"sheetStyle\"\n @click.stop\n >\n <div\n class=\"fe-sheet__handle\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t('sheet.close')\"\n @click=\"hide\"\n @keydown.enter.prevent=\"hide\"\n @touchstart.passive=\"onSheetDragStart\"\n @touchmove.passive=\"onSheetDragMove\"\n @touchend=\"onSheetDragEnd\"\n @touchcancel=\"onSheetDragEnd\"\n />\n <div class=\"fe-sheet__items\">\n <template v-for=\"(a, i) in visibleActions\" :key=\"a.key || i\">\n <div v-if=\"a.divider\" class=\"fe-ctx__sep\" />\n <button\n v-else\n type=\"button\"\n class=\"fe-ctx__item fe-sheet__item\"\n :class=\"{ 'is-danger': a.danger, 'is-disabled': a.disabled }\"\n :disabled=\"a.disabled\"\n role=\"menuitem\"\n @click=\"pick(a)\"\n >\n <span v-if=\"a.icon\" class=\"fe-ctx__icon\" aria-hidden=\"true\">{{ a.icon }}</span>\n <span class=\"fe-ctx__label\">{{ a.label }}</span>\n </button>\n </template>\n </div>\n </div>\n <div\n v-else\n ref=\"menuEl\"\n class=\"fe-ctx\"\n role=\"menu\"\n :style=\"{ top: y + 'px', left: x + 'px' }\"\n @click.stop\n >\n <template v-for=\"(a, i) in visibleActions\" :key=\"a.key || i\">\n <div v-if=\"a.divider\" class=\"fe-ctx__sep\" />\n <button\n v-else\n type=\"button\"\n class=\"fe-ctx__item\"\n :class=\"{ 'is-danger': a.danger, 'is-disabled': a.disabled }\"\n :disabled=\"a.disabled\"\n role=\"menuitem\"\n @click=\"pick(a)\"\n >\n <span v-if=\"a.icon\" class=\"fe-ctx__icon\" aria-hidden=\"true\">{{ a.icon }}</span>\n <span class=\"fe-ctx__label\">{{ a.label }}</span>\n </button>\n </template>\n </div>\n </div>\n </transition>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Toolbar — selection-aware action row.\n *\n * Layout:\n * - No selection → [📁 Yeni Klasör] [search | ⬆ ↻] [☰ ▦]\n * - 1 file selected → [👁 ⬇ 🔗 ✎ 🗑] [search | ⬆ ↻] [☰ ▦]\n * - 1 folder selected → [↗ ✎ 🗑] [search | ⬆ ↻] [☰ ▦]\n * - Multi selection → [✂ ❐ 🗑] [search | ⬆ ↻] [☰ ▦]\n *\n * Presentational only — all logic (rename, share, …) lives in\n * FileExplorer.vue, which listens for `action` emits.\n */\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';\nimport type { ViewMode } from '../types/FileNode';\nimport type { LocaleCode, ThemeMode } from '../types/ExplorerConfig';\nimport ContextMenu, { type ContextAction } from './ContextMenu.vue';\nimport { useLocale } from '../composables/useLocale';\n\nexport type SelectionMode = 'none' | 'single-file' | 'single-dir' | 'multi';\n\nconst props = defineProps<{\n viewMode: ViewMode;\n searchQuery: string;\n /**\n * Tells the toolbar which action set to render (a `.trash/` listing\n * gets a restore-only menu instead of cut/copy/etc).\n */\n trashActive: boolean;\n /**\n * The action list to render, supplied by FileExplorer. This is the SAME\n * list the right-click context menu renders for the current selection, so\n * the two menus can never drift apart. Dividers/hidden entries are filtered\n * out here (the toolbar is a flat row).\n */\n actions: ContextAction[];\n /** Current selection metadata — toolbar uses this to pick its mode. */\n selectionMode?: SelectionMode;\n /** True when clipboard has cut/copy items, so we can enable Paste. */\n pasteEnabled?: boolean;\n /** True when the universal converter (FILEX_CONVERT_URL) is available. */\n convertEnabled?: boolean;\n /**\n * True when the current dir has a parent the user can step up to.\n * Hidden at storage root because there's nothing above it.\n */\n canGoUp?: boolean;\n /**\n * Multi-storage virtual root marker — when true, mutation buttons\n * (New Folder / Upload / Paste) are hidden because there's no real\n * backend folder to write to.\n */\n atVirtualRoot?: boolean;\n /**\n * RBAC: false hides the write affordances (New Folder / Upload / Paste) when\n * the current user lacks edit on this directory. Undefined = no RBAC gating\n * (backward-compatible for embedders that don't pass it).\n */\n canWrite?: boolean;\n locale: LocaleCode;\n /**\n * bag:b4 — narrow/embed mini mode. When true the toolbar collapses to\n * [↑?] [🔍] [⬆] [⋯]: secondary actions (New Folder, Refresh, density,\n * view switcher, selection actions, Paste) move into the \"⋯\" overflow\n * menu and search expands from an icon to a full-width input. When\n * absent/false the classic wide layout renders unchanged.\n */\n narrow?: boolean;\n /**\n * bag:b4 — resolved theme, forwarded to the teleported overflow menu\n * (which loses the `.fe` variable scope under <body>).\n */\n theme?: ThemeMode;\n /* koru:k1 — inspector (details panel) toggle state, for the pressed style. */\n inspectorOpen?: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:viewMode', v: ViewMode): void;\n (e: 'update:searchQuery', v: string): void;\n (e: 'new-folder'): void;\n (e: 'upload'): void;\n (e: 'refresh'): void;\n (e: 'go-up'): void;\n (e: 'action', key: string): void;\n (e: 'open-recents'): void;\n (e: 'update:density', v: Density): void;\n (e: 'toggle-inspector'): void /* koru:k1 */;\n}>();\n\n// Density toggle — the toolbar owns the persisted preference; the parent\n// only mirrors the value into a root class so both views pick it up.\nexport type Density = 'comfortable' | 'compact';\nconst DENSITY_LS_KEY = 'filex.density';\nconst density = ref<Density>(\n (() => {\n try {\n return localStorage.getItem(DENSITY_LS_KEY) === 'compact' ? 'compact' : 'comfortable';\n } catch {\n return 'comfortable';\n }\n })(),\n);\nonMounted(() => emit('update:density', density.value));\n\nfunction toggleDensity() {\n density.value = density.value === 'compact' ? 'comfortable' : 'compact';\n try {\n localStorage.setItem(DENSITY_LS_KEY, density.value);\n } catch {\n /* quota */\n }\n emit('update:density', density.value);\n}\n\nconst { t } = useLocale(() => props.locale);\n\nconst searchEl = ref<HTMLInputElement | null>(null);\nconst localSearch = ref(props.searchQuery);\n\nwatch(() => props.searchQuery, (v) => {\n localSearch.value = v;\n});\n\nlet debounce: ReturnType<typeof setTimeout> | undefined;\nfunction onSearchInput(ev: Event) {\n const v = (ev.target as HTMLInputElement).value;\n localSearch.value = v;\n if (debounce) clearTimeout(debounce);\n debounce = setTimeout(() => emit('update:searchQuery', v), 200);\n}\n\nasync function focusSearch() {\n /* bag:b4 — in narrow mode the input is collapsed behind the icon. */\n if (props.narrow && !searchOpen.value) {\n searchOpen.value = true;\n await nextTick();\n }\n searchEl.value?.focus();\n searchEl.value?.select();\n}\n\ndefineExpose({ focusSearch });\n\nconst mode = computed<SelectionMode>(() => props.selectionMode ?? 'none');\n\n// The visible action buttons = the shared list from FileExplorer, minus\n// dividers and hidden entries (the toolbar is a flat row, not a dropdown).\n// Disabled entries render greyed-out. Because this is the SAME list the\n// context menu uses, the two menus are guaranteed to match.\nconst toolbarItems = computed(() => props.actions.filter((a) => !a.divider && !a.hidden));\n\nfunction fire(key: string) {\n emit('action', key);\n}\n\n/* === bag:b4 — narrow-mode state: expandable search + \"⋯\" overflow menu === */\n\nconst searchOpen = ref(false);\n// Leaving narrow mode discards the transient expanded-search state so the\n// wide layout always comes back exactly as it was.\nwatch(\n () => props.narrow,\n (n) => {\n if (!n) searchOpen.value = false;\n },\n);\n\nasync function openSearch() {\n searchOpen.value = true;\n await nextTick();\n searchEl.value?.focus();\n}\nfunction closeSearch() {\n // Keep the query (it still filters the listing); the icon shows an\n // active state while a query is set.\n searchOpen.value = false;\n}\n\n// Coarse-pointer detection — the overflow menu renders as a bottom sheet on\n// touch devices, matching the file context menu.\nconst coarse = ref(false);\nlet coarseMq: MediaQueryList | undefined;\nfunction syncCoarse(e?: MediaQueryListEvent | MediaQueryList) {\n coarse.value = !!(e && 'matches' in e && e.matches);\n}\nonMounted(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return;\n coarseMq = window.matchMedia('(pointer: coarse)');\n syncCoarse(coarseMq);\n coarseMq.addEventListener?.('change', syncCoarse);\n});\nonBeforeUnmount(() => {\n coarseMq?.removeEventListener?.('change', syncCoarse);\n});\n\nconst moreBtnEl = ref<HTMLElement | null>(null);\nconst moreRef = ref<InstanceType<typeof ContextMenu> | null>(null);\n\n// Everything the wide toolbar renders as standalone buttons, folded into one\n// action list: folder-level writes (New Folder / Paste), the shared\n// selection actions, then the view utilities (Refresh / density / view mode).\nconst moreActions = computed<ContextAction[]>(() => {\n const list: ContextAction[] = [];\n const writable =\n !props.trashActive && !props.atVirtualRoot && props.canWrite !== false;\n if (mode.value === 'none' && writable) {\n list.push({ key: 'new-folder', label: t('toolbar.new_folder'), icon: '📁' });\n if (props.pasteEnabled) list.push({ key: 'paste', label: t('ctx.paste'), icon: '📋' });\n }\n list.push(...toolbarItems.value);\n if (list.length) list.push({ divider: true, key: 'bag-sep', label: '' });\n list.push({ key: 'refresh', label: t('toolbar.refresh'), icon: '↻' });\n list.push({\n key: 'density',\n label:\n density.value === 'compact'\n ? t('toolbar.density.comfortable')\n : t('toolbar.density.compact'),\n icon: '⇅',\n });\n list.push(\n props.viewMode === 'list'\n ? { key: 'view-grid', label: t('toolbar.view.grid'), icon: '▦' }\n : { key: 'view-list', label: t('toolbar.view.list'), icon: '☰' },\n );\n /* koru:k1 — inspector toggle also reachable from the narrow overflow menu */\n list.push({ key: 'inspector', label: t('toolbar.inspector'), icon: 'ℹ' });\n return list;\n});\n\nfunction openMore() {\n const r = moreBtnEl.value?.getBoundingClientRect();\n moreRef.value?.show({ clientX: r ? r.right : 0, clientY: r ? r.bottom + 4 : 0 }, []);\n}\n\nfunction onMoreSelect(a: ContextAction) {\n switch (a.key) {\n case 'new-folder':\n emit('new-folder');\n break;\n case 'refresh':\n emit('refresh');\n break;\n case 'density':\n toggleDensity();\n break;\n case 'view-list':\n emit('update:viewMode', 'list');\n break;\n case 'view-grid':\n emit('update:viewMode', 'grid');\n break;\n case 'inspector' /* koru:k1 */:\n emit('toggle-inspector');\n break;\n default:\n fire(a.key);\n }\n}\n\n/* === /bag:b4 === */\n</script>\n\n<template>\n <div\n class=\"fe-toolbar\"\n :class=\"{\n 'fe-toolbar--narrow': narrow /* bag:b4 */,\n 'fe-toolbar--searching': narrow && searchOpen /* bag:b4 */,\n }\"\n >\n <!-- bag:b4 — wide layout, untouched; renders exactly as before when not narrow -->\n <template v-if=\"!narrow\">\n <div class=\"fe-toolbar__primary\">\n <button\n v-if=\"canGoUp\"\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :title=\"t('toolbar.go_up')\"\n :aria-label=\"t('toolbar.go_up')\"\n @click=\"emit('go-up')\"\n >\n <span class=\"fe-icon\">↑</span>\n </button>\n\n <button\n v-if=\"mode === 'none' && !trashActive && !atVirtualRoot && canWrite !== false\"\n type=\"button\"\n class=\"fe-btn fe-btn--primary\"\n :title=\"t('toolbar.new_folder')\"\n @click=\"emit('new-folder')\"\n >\n <span class=\"fe-icon\">📁</span>\n <span class=\"fe-btn__label\">{{ t('toolbar.new_folder') }}</span>\n </button>\n\n <button\n v-for=\"a in toolbarItems\"\n :key=\"a.key\"\n type=\"button\"\n class=\"fe-btn\"\n :class=\"{ 'fe-btn--danger': a.danger, 'is-disabled': a.disabled }\"\n :disabled=\"a.disabled\"\n :title=\"a.label\"\n @click=\"fire(a.key)\"\n >\n <span class=\"fe-icon\">{{ a.icon }}</span>\n <span class=\"fe-btn__label\">{{ a.label }}</span>\n </button>\n\n <button\n v-if=\"pasteEnabled && mode === 'none' && !trashActive && !atVirtualRoot && canWrite !== false\"\n type=\"button\"\n class=\"fe-btn\"\n :title=\"t('ctx.paste')\"\n @click=\"fire('paste')\"\n >\n <span class=\"fe-icon\">📋</span>\n <span class=\"fe-btn__label\">{{ t('ctx.paste') }}</span>\n </button>\n </div>\n\n <div class=\"fe-toolbar__spacer\" />\n\n <div class=\"fe-toolbar__search-group\">\n <div class=\"fe-search\">\n <input\n ref=\"searchEl\"\n type=\"search\"\n class=\"fe-search__input\"\n :placeholder=\"t('toolbar.search.placeholder')\"\n :value=\"localSearch\"\n aria-label=\"Search\"\n @input=\"onSearchInput\"\n />\n </div>\n <button\n v-if=\"!atVirtualRoot && canWrite !== false\"\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :title=\"t('toolbar.upload')\"\n @click=\"emit('upload')\"\n >\n <span class=\"fe-icon\">⬆</span>\n </button>\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :title=\"t('toolbar.refresh')\"\n @click=\"emit('refresh')\"\n >\n <span class=\"fe-icon\">↻</span>\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only fe-toolbar__density\"\n :class=\"{ 'is-active': density === 'compact' }\"\n :aria-pressed=\"density === 'compact'\"\n :aria-label=\"density === 'compact' ? t('toolbar.density.comfortable') : t('toolbar.density.compact')\"\n :title=\"density === 'compact' ? t('toolbar.density.comfortable') : t('toolbar.density.compact')\"\n @click=\"toggleDensity\"\n >\n <!-- Row-spacing glyph: tight rows when compact is ON, airy rows otherwise. -->\n <svg\n v-if=\"density === 'compact'\"\n class=\"fe-ficon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M4 6.5h16M4 10.5h16M4 14.5h16M4 18.5h16\" />\n </svg>\n <svg\n v-else\n class=\"fe-ficon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M4 5.5h16M4 12h16M4 18.5h16\" />\n </svg>\n </button>\n\n <!-- koru:k1 — inspector (details panel) toggle -->\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only fe-toolbar__inspector\"\n :class=\"{ 'is-active': inspectorOpen }\"\n :aria-pressed=\"!!inspectorOpen\"\n :title=\"t('toolbar.inspector')\"\n :aria-label=\"t('toolbar.inspector')\"\n @click=\"emit('toggle-inspector')\"\n >\n <svg\n class=\"fe-ficon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 11v5\" />\n <circle cx=\"12\" cy=\"7.6\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n </button>\n\n <div class=\"fe-toolbar__view\" role=\"tablist\" aria-label=\"View\">\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :class=\"{ 'is-active': viewMode === 'list' }\"\n role=\"tab\"\n :aria-selected=\"viewMode === 'list'\"\n :title=\"t('toolbar.view.list')\"\n @click=\"emit('update:viewMode', 'list')\"\n >\n <span class=\"fe-icon\">☰</span>\n </button>\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :class=\"{ 'is-active': viewMode === 'grid' }\"\n role=\"tab\"\n :aria-selected=\"viewMode === 'grid'\"\n :title=\"t('toolbar.view.grid')\"\n @click=\"emit('update:viewMode', 'grid')\"\n >\n <span class=\"fe-icon\">▦</span>\n </button>\n </div>\n </template>\n\n <!-- bag:b4 — narrow layout: [↑?] ... [🔍] [⬆] [⋯], search expands full-width -->\n <template v-else>\n <template v-if=\"searchOpen\">\n <div class=\"fe-search fe-search--full\">\n <input\n ref=\"searchEl\"\n type=\"search\"\n class=\"fe-search__input\"\n :placeholder=\"t('toolbar.search.placeholder')\"\n :value=\"localSearch\"\n :aria-label=\"t('toolbar.search')\"\n @input=\"onSearchInput\"\n @keydown.esc.stop.prevent=\"closeSearch\"\n />\n </div>\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :title=\"t('toolbar.search.close')\"\n :aria-label=\"t('toolbar.search.close')\"\n @click=\"closeSearch\"\n >\n <span class=\"fe-icon\">✕</span>\n </button>\n </template>\n <template v-else>\n <button\n v-if=\"canGoUp\"\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :title=\"t('toolbar.go_up')\"\n :aria-label=\"t('toolbar.go_up')\"\n @click=\"emit('go-up')\"\n >\n <span class=\"fe-icon\">↑</span>\n </button>\n\n <div class=\"fe-toolbar__spacer\" />\n\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only fe-toolbar__search-toggle\"\n :class=\"{ 'is-active': !!localSearch }\"\n :title=\"t('toolbar.search')\"\n :aria-label=\"t('toolbar.search')\"\n @click=\"openSearch\"\n >\n <span class=\"fe-icon\">🔍</span>\n </button>\n <button\n v-if=\"!atVirtualRoot && canWrite !== false\"\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only\"\n :title=\"t('toolbar.upload')\"\n :aria-label=\"t('toolbar.upload')\"\n @click=\"emit('upload')\"\n >\n <span class=\"fe-icon\">⬆</span>\n </button>\n <button\n ref=\"moreBtnEl\"\n type=\"button\"\n class=\"fe-btn fe-btn--icon-only fe-toolbar__more\"\n :title=\"t('toolbar.more')\"\n :aria-label=\"t('toolbar.more')\"\n aria-haspopup=\"menu\"\n @click=\"openMore\"\n >\n <span class=\"fe-icon\">⋯</span>\n </button>\n </template>\n\n <ContextMenu\n ref=\"moreRef\"\n :locale=\"locale\"\n :theme=\"theme || 'auto'\"\n :sheet=\"coarse\"\n :actions=\"moreActions\"\n @select=\"onMoreSelect\"\n />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * TagPicker — small chip list with add/remove for a node.\n *\n * Reads `GET /api/files/manager/tags?node_id=…` on mount, writes the\n * full new array via `POST /api/files/manager/tags`.\n *\n * Tag colors are deterministic: hash(name) → palette index. Consumers\n * can override with the `palette` prop.\n */\nimport { ref, watch, onMounted, computed } from 'vue';\n\nconst props = defineProps<{\n nodeId: number;\n apiBase?: string;\n authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n /** Optional list of palette swatches; one is picked per tag deterministically. */\n palette?: string[];\n}>();\n\nconst emit = defineEmits<{\n (e: 'change', tags: string[]): void;\n (e: 'error', message: string): void;\n}>();\n\nconst tags = ref<string[]>([]);\nconst loading = ref(false);\nconst adding = ref(false);\nconst newTag = ref('');\n\nconst palette = computed(() => props.palette ?? [\n '#ef4444', '#f59e0b', '#10b981', '#3b82f6',\n '#8b5cf6', '#ec4899', '#14b8a6', '#f97316',\n]);\n\nfunction colorFor(tag: string): string {\n let h = 0;\n for (let i = 0; i < tag.length; i++) h = (h * 31 + tag.charCodeAt(i)) | 0;\n const arr = palette.value;\n return arr[Math.abs(h) % arr.length];\n}\n\nasync function buildHeaders(extra: Record<string, string> = {}): Promise<Record<string, string>> {\n return { ...(await (props.authHeaders ?? (() => ({})))()), ...extra };\n}\n\nasync function load() {\n loading.value = true;\n try {\n const base = props.apiBase ?? '';\n const res = await fetch(`${base}/api/files/manager/tags?node_id=${props.nodeId}`, {\n headers: await buildHeaders(),\n credentials: 'include',\n });\n if (res.ok) {\n const body = await res.json();\n tags.value = Array.isArray(body.tags) ? body.tags : [];\n }\n } catch (err) {\n emit('error', err instanceof Error ? err.message : String(err));\n } finally {\n loading.value = false;\n }\n}\n\nasync function persist(next: string[]) {\n const previous = [...tags.value];\n tags.value = next;\n try {\n const base = props.apiBase ?? '';\n const res = await fetch(`${base}/api/files/manager/tags`, {\n method: 'POST',\n headers: await buildHeaders({ 'Content-Type': 'application/json' }),\n credentials: 'include',\n body: JSON.stringify({ node_id: props.nodeId, tags: next }),\n });\n if (!res.ok) throw new Error(`tag save failed: ${res.status}`);\n emit('change', next);\n } catch (err) {\n tags.value = previous;\n emit('error', err instanceof Error ? err.message : String(err));\n }\n}\n\nfunction add() {\n const v = newTag.value.trim();\n if (!v || tags.value.includes(v)) {\n newTag.value = '';\n adding.value = false;\n return;\n }\n persist([...tags.value, v]);\n newTag.value = '';\n adding.value = false;\n}\n\nfunction remove(tag: string) {\n persist(tags.value.filter((t) => t !== tag));\n}\n\nonMounted(load);\nwatch(() => props.nodeId, load);\n</script>\n\n<template>\n <div class=\"filex-tag-picker\" :class=\"{ 'is-loading': loading }\">\n <span\n v-for=\"tag in tags\"\n :key=\"tag\"\n class=\"filex-tag\"\n :style=\"{ '--filex-tag-color': colorFor(tag) }\"\n >\n {{ tag }}\n <button class=\"filex-tag-x\" type=\"button\" @click=\"remove(tag)\" aria-label=\"Remove tag\">×</button>\n </span>\n\n <form v-if=\"adding\" class=\"filex-tag-add\" @submit.prevent=\"add\">\n <input\n v-model=\"newTag\"\n autofocus\n placeholder=\"tag name\"\n @blur=\"add\"\n @keydown.escape=\"adding = false; newTag = ''\"\n />\n </form>\n <button v-else class=\"filex-tag-add-btn\" type=\"button\" @click=\"adding = true\">+ Add tag</button>\n </div>\n</template>\n\n<style scoped>\n.filex-tag-picker {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n.filex-tag-picker.is-loading {\n opacity: 0.6;\n pointer-events: none;\n}\n.filex-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n border-radius: 999px;\n padding: 2px 10px;\n font-size: 12px;\n font-weight: 500;\n color: #fff;\n background: var(--filex-tag-color);\n}\n.filex-tag-x {\n background: transparent;\n border: none;\n color: rgba(255, 255, 255, 0.85);\n cursor: pointer;\n padding: 0 2px;\n font-size: 14px;\n line-height: 1;\n}\n.filex-tag-x:hover {\n color: #fff;\n}\n.filex-tag-add input {\n border: 1px solid var(--filex-border, #d1d5db);\n border-radius: 12px;\n padding: 2px 10px;\n font-size: 12px;\n width: 110px;\n}\n.filex-tag-add-btn {\n border: 1px dashed var(--filex-border, #d1d5db);\n background: transparent;\n border-radius: 999px;\n padding: 2px 10px;\n font-size: 12px;\n color: var(--filex-text-muted, #6b7280);\n cursor: pointer;\n}\n.filex-tag-add-btn:hover {\n border-color: var(--filex-accent, #6366f1);\n color: var(--filex-accent, #6366f1);\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * RecentlyOpened — drop-down/sidebar tray of the user's recently-opened\n * files. Backed by `GET /api/files/manager/recent?limit=20`.\n */\nimport { ref, onMounted, watch } from 'vue';\n\ninterface RecentNode {\n id: number;\n storage_id: number;\n path: string;\n name: string;\n mime?: string;\n last_opened?: string;\n}\n\nconst props = defineProps<{\n apiBase?: string;\n authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n limit?: number;\n /** Optional refresh trigger — incrementing this re-fetches. */\n refreshKey?: number | string;\n}>();\n\nconst emit = defineEmits<{\n (e: 'open', node: RecentNode): void;\n (e: 'error', message: string): void;\n}>();\n\nconst items = ref<RecentNode[]>([]);\nconst loading = ref(false);\n\nasync function load() {\n loading.value = true;\n try {\n const headers = await (props.authHeaders ?? (() => ({})))();\n const base = props.apiBase ?? '';\n const limit = props.limit ?? 20;\n const res = await fetch(`${base}/api/files/manager/recent?limit=${limit}`, {\n headers,\n credentials: 'include',\n });\n if (res.ok) {\n const body = await res.json();\n items.value = Array.isArray(body.entries) ? body.entries : (Array.isArray(body) ? body : []);\n }\n } catch (err) {\n emit('error', err instanceof Error ? err.message : String(err));\n } finally {\n loading.value = false;\n }\n}\n\nfunction fmtTime(s?: string): string {\n if (!s) return '';\n const t = new Date(s).getTime();\n if (Number.isNaN(t)) return '';\n const diff = Date.now() - t;\n if (diff < 60_000) return 'just now';\n if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m ago`;\n if (diff < 86_400_000) return `${Math.floor(diff / 3_600_000)}h ago`;\n return `${Math.floor(diff / 86_400_000)}d ago`;\n}\n\nonMounted(load);\nwatch(() => props.refreshKey, load);\n</script>\n\n<template>\n <div class=\"filex-recent\">\n <header>\n <h3>Recently opened</h3>\n <button class=\"filex-recent-refresh\" type=\"button\" @click=\"load\" :disabled=\"loading\">\n ↻\n </button>\n </header>\n\n <ul v-if=\"items.length\">\n <li v-for=\"n in items\" :key=\"n.id\">\n <button type=\"button\" @click=\"emit('open', n)\" class=\"filex-recent-item\">\n <span class=\"filex-recent-name\">{{ n.name }}</span>\n <span class=\"filex-recent-meta\">{{ fmtTime(n.last_opened) }}</span>\n </button>\n </li>\n </ul>\n <p v-else-if=\"!loading\" class=\"filex-recent-empty\">Nothing here yet.</p>\n <p v-else class=\"filex-recent-empty\">Loading…</p>\n </div>\n</template>\n\n<style scoped>\n.filex-recent {\n background: var(--fe-bg-elev, var(--filex-bg-card, #ffffff));\n border: 1px solid var(--fe-border, var(--filex-border, #e5e7eb));\n border-radius: 8px;\n padding: 12px;\n font-size: 13px;\n}\n.filex-recent header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n.filex-recent h3 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--fe-text, var(--filex-text, #111827));\n}\n.filex-recent-refresh {\n background: transparent;\n border: none;\n color: var(--fe-text-muted, var(--filex-text-muted, #9ca3af));\n cursor: pointer;\n font-size: 14px;\n padding: 2px 6px;\n}\n.filex-recent ul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n.filex-recent-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n background: transparent;\n border: none;\n padding: 6px 8px;\n cursor: pointer;\n border-radius: 4px;\n text-align: left;\n}\n.filex-recent-item:hover {\n background: var(--fe-bg-hover, var(--filex-bg-soft, #f3f4f6));\n}\n.filex-recent-name {\n color: var(--fe-text, var(--filex-text, #111827));\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.filex-recent-meta {\n color: var(--fe-text-muted, var(--filex-text-muted, #9ca3af));\n font-size: 11px;\n margin-left: 8px;\n flex-shrink: 0;\n}\n.filex-recent-empty {\n color: var(--fe-text-muted, var(--filex-text-muted, #9ca3af));\n margin: 4px 0 0;\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * Breadcrumb — adapter-aware path crumbs.\n *\n * Dirname arrives as `<adapter>://<rel>` (e.g. `s3-test://aa/bb`). The\n * first crumb is ALWAYS the storage root — its label is the adapter\n * name itself (`s3-test`) and clicking it lands you at `<adapter>://`,\n * NOT at the first sub-folder you happened to be inside. The remaining\n * crumbs walk down the path one segment at a time.\n *\n * Examples:\n * `s3-test://` → [s3-test]\n * `s3-test://aa` → [s3-test] › [aa]\n * `s3-test://aa/bb` → [s3-test] › [aa] › [bb]\n *\n * `rootLabel` overrides the adapter name when the embedder wants a\n * branded label ('Files', 'My Drive', etc). Defaults to the adapter.\n *\n * The ✏ button swaps the crumbs for a free-form input; Enter\n * navigates, Escape cancels.\n */\nimport { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\n\nconst props = defineProps<{\n dirname: string;\n adapter: string;\n rootLabel: string;\n locale: LocaleCode;\n /**\n * Multi-storage mode — when true the breadcrumb prepends a global\n * \"/\" crumb so the user can pop all the way back to the storage\n * picker. Storage name then occupies crumb #1 instead of #0.\n */\n multiStorageRoot?: boolean;\n /**\n * Root confinement (qualified `<adapter>://<rel>`). When set the breadcrumb\n * treats this folder as `/`: crumbs above it are hidden, the root crumb is\n * the confined folder's own name, and the ✏ path editor shows/accepts paths\n * relative to it (`/`, `/sub`). Pairs with FileExplorer's rootPath clamp.\n */\n rootPath?: string;\n}>();\n\n// Confined root parsed into its adapter-relative form (\"projeler/acme\") and\n// the trailing folder name used as the \"/\" crumb label.\nconst confinedRel = computed(() => {\n if (!props.rootPath) return '';\n const r = props.rootPath;\n const i = r.indexOf('://');\n return (i >= 0 ? r.slice(i + 3) : r).replace(/^\\/+|\\/+$/g, '');\n});\nconst floorLabel = computed(() => {\n const rel = confinedRel.value;\n if (!rel) return props.rootLabel || props.adapter;\n const parts = rel.split('/');\n return parts[parts.length - 1] || (props.rootLabel || props.adapter);\n});\n\nconst { t } = useLocale(() => props.locale);\n\nconst emit = defineEmits<{\n (e: 'navigate', adapterPath: string): void;\n (e: 'copy-path', adapterPath: string): void;\n (e: 'crumb-context', payload: { x: number; y: number; adapterPath: string; label: string }): void;\n (e: 'crumb-drop', adapterPath: string, ev: DragEvent): void;\n}>();\n\ninterface Crumb {\n label: string;\n adapterPath: string;\n}\n\nconst crumbs = computed<Crumb[]>(() => {\n const adapterPrefix = `${props.adapter}://`;\n const raw = props.dirname.startsWith(adapterPrefix)\n ? props.dirname.slice(adapterPrefix.length)\n : props.dirname;\n const parts = raw.split('/').filter(Boolean);\n\n const out: Crumb[] = [];\n\n // Confined: the root folder is the top crumb (its own name), and only the\n // path BELOW it is walked — segments above the confinement are never shown.\n if (props.rootPath) {\n const floor = confinedRel.value;\n const cur = raw.replace(/^\\/+|\\/+$/g, '');\n const below = floor && (cur === floor || cur.startsWith(floor + '/'))\n ? cur.slice(floor.length).replace(/^\\/+/, '')\n : '';\n out.push({ label: floorLabel.value, adapterPath: props.rootPath });\n let acc = floor;\n for (const part of below.split('/').filter(Boolean)) {\n acc = acc ? `${acc}/${part}` : part;\n out.push({ label: part === '.trash' ? t('node.trash') : part, adapterPath: `${adapterPrefix}${acc}` });\n }\n return out;\n }\n\n if (props.multiStorageRoot) {\n // Global \"/\" crumb — clicking it pops back to the storage picker\n // (FileExplorer treats the empty string as the virtual root).\n out.push({ label: '/', adapterPath: '' });\n if (props.adapter) {\n // Storage segment — wire form `<adapter>://` lands at storage\n // root regardless of where we are now.\n out.push({ label: props.rootLabel || props.adapter, adapterPath: adapterPrefix });\n }\n } else {\n // Single-storage mode: the storage name IS the root, no \"/\"\n // above it.\n out.push({\n label: props.rootLabel || props.adapter,\n adapterPath: adapterPrefix,\n });\n }\n\n let acc = '';\n for (const part of parts) {\n acc = acc ? `${acc}/${part}` : part;\n const label = part === '.trash' ? t('node.trash') : part;\n out.push({ label, adapterPath: `${adapterPrefix}${acc}` });\n }\n return out;\n});\n\n// ------------------------------------------------------------------\n// Overflow collapse (cila:c / I5) — when the trail grows past the\n// threshold, show `root › … › parent › current`; the middle crumbs move\n// into a dropdown. Visible crumbs keep their full click/drag-drop/context\n// behavior; dropdown entries only navigate.\n// ------------------------------------------------------------------\nconst OVERFLOW_THRESHOLD = 4;\nconst collapsed = computed(() => crumbs.value.length > OVERFLOW_THRESHOLD);\nconst leadCrumbs = computed<Crumb[]>(() =>\n collapsed.value ? crumbs.value.slice(0, 1) : crumbs.value,\n);\nconst middleCrumbs = computed<Crumb[]>(() =>\n collapsed.value ? crumbs.value.slice(1, -2) : [],\n);\nconst tailCrumbs = computed<Crumb[]>(() =>\n collapsed.value ? crumbs.value.slice(-2) : [],\n);\n\nconst overflowOpen = ref(false);\nconst moreWrapEl = ref<HTMLElement | null>(null);\n\nfunction onOverflowPick(crumb: Crumb) {\n overflowOpen.value = false;\n emit('navigate', crumb.adapterPath);\n}\n\nfunction onDocClick(e: MouseEvent) {\n const wrap = moreWrapEl.value;\n if (wrap && e.target instanceof Node && wrap.contains(e.target)) return;\n overflowOpen.value = false;\n}\n\nfunction onDocKeydown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.stopPropagation();\n overflowOpen.value = false;\n }\n}\n\nwatch(overflowOpen, (v) => {\n if (v) {\n document.addEventListener('click', onDocClick, true);\n document.addEventListener('keydown', onDocKeydown, true);\n } else {\n document.removeEventListener('click', onDocClick, true);\n document.removeEventListener('keydown', onDocKeydown, true);\n }\n});\n// Navigation rebuilds the trail — a stale open menu would list crumbs of\n// the previous folder.\nwatch(crumbs, () => {\n overflowOpen.value = false;\n});\nonBeforeUnmount(() => {\n document.removeEventListener('click', onDocClick, true);\n document.removeEventListener('keydown', onDocKeydown, true);\n});\n\nfunction onClick(crumb: Crumb) {\n emit('navigate', crumb.adapterPath);\n}\n\nfunction onContext(ev: MouseEvent, crumb: Crumb) {\n ev.preventDefault();\n ev.stopPropagation();\n emit('crumb-context', {\n x: ev.clientX,\n y: ev.clientY,\n adapterPath: crumb.adapterPath,\n label: crumb.label,\n });\n}\n\nfunction onCrumbDragOver(ev: DragEvent) {\n if (!ev.dataTransfer?.types.includes('application/x-brf-files')) return;\n ev.preventDefault();\n ev.stopPropagation();\n if (ev.dataTransfer) ev.dataTransfer.dropEffect = 'move';\n}\n\nfunction onCrumbDrop(ev: DragEvent, crumb: Crumb) {\n if (!ev.dataTransfer?.types.includes('application/x-brf-files')) return;\n ev.preventDefault();\n ev.stopPropagation();\n emit('crumb-drop', crumb.adapterPath, ev);\n}\n\nconst editing = ref(false);\nconst pathDraft = ref('');\nconst pathInput = ref<HTMLInputElement | null>(null);\n\nfunction startEdit() {\n const adapterPrefix = `${props.adapter}://`;\n const rel = props.dirname.startsWith(adapterPrefix)\n ? props.dirname.slice(adapterPrefix.length)\n : props.dirname;\n // Confined: edit relative to the root folder — `/` is the root, `/sub` below.\n if (props.rootPath) {\n const floor = confinedRel.value;\n const cur = rel.replace(/^\\/+|\\/+$/g, '');\n const below = floor && (cur === floor || cur.startsWith(floor + '/'))\n ? cur.slice(floor.length).replace(/^\\/+/, '')\n : '';\n pathDraft.value = below ? `/${below}` : '/';\n editing.value = true;\n void nextTick(() => {\n pathInput.value?.focus();\n pathInput.value?.select();\n });\n return;\n }\n // Multi-storage: show `/<storage>/<rel>` so the user can edit the\n // whole tree (`/main/foo`, `/s3-test/example`, just `/` for root).\n if (props.multiStorageRoot) {\n if (!props.adapter) {\n pathDraft.value = '/';\n } else {\n const trimmed = rel.replace(/^\\/+|\\/+$/g, '');\n pathDraft.value = trimmed\n ? `/${props.adapter}/${trimmed}`\n : `/${props.adapter}`;\n }\n } else {\n pathDraft.value = rel;\n }\n editing.value = true;\n void nextTick(() => {\n pathInput.value?.focus();\n pathInput.value?.select();\n });\n}\n\nfunction submitPath() {\n const raw = pathDraft.value.trim();\n editing.value = false;\n\n // Confined: the typed path is relative to the root folder; prepend the floor.\n if (props.rootPath) {\n const sub = raw.replace(/^\\/+|\\/+$/g, '');\n const floor = confinedRel.value;\n const rel = sub ? (floor ? `${floor}/${sub}` : sub) : floor;\n emit('navigate', rel ? `${props.adapter}://${rel}` : `${props.adapter}://`);\n return;\n }\n\n if (props.multiStorageRoot) {\n // Strip leading/trailing slashes. First segment = storage.\n const clean = raw.replace(/^\\/+|\\/+$/g, '');\n if (!clean) {\n // navigate to global root by emitting empty wire path; the\n // FileExplorer treats it as virtual storage list.\n emit('navigate', '');\n return;\n }\n const slash = clean.indexOf('/');\n const adapter = slash === -1 ? clean : clean.slice(0, slash);\n const rel = slash === -1 ? '' : clean.slice(slash + 1);\n emit('navigate', rel ? `${adapter}://${rel}` : `${adapter}://`);\n return;\n }\n\n const v = raw.replace(/^\\/+|\\/+$/g, '');\n if (!v) return;\n emit('navigate', `${props.adapter}://${v}`);\n}\n\nfunction cancelEdit() {\n editing.value = false;\n}\n</script>\n\n<template>\n <nav class=\"fe-breadcrumb\" aria-label=\"Breadcrumb\">\n <template v-if=\"!editing\">\n <button\n v-for=\"(c, i) in leadCrumbs\"\n :key=\"c.adapterPath\"\n class=\"fe-breadcrumb__crumb\"\n :class=\"{ 'is-last': !collapsed && i === leadCrumbs.length - 1 }\"\n type=\"button\"\n :aria-current=\"!collapsed && i === leadCrumbs.length - 1 ? 'page' : undefined\"\n @click=\"onClick(c)\"\n @contextmenu=\"onContext($event, c)\"\n @dragover=\"onCrumbDragOver\"\n @drop=\"onCrumbDrop($event, c)\"\n >\n <span>{{ c.label }}</span>\n <span v-if=\"collapsed || i < leadCrumbs.length - 1\" class=\"fe-breadcrumb__sep\" aria-hidden=\"true\">›</span>\n </button>\n <span v-if=\"middleCrumbs.length\" ref=\"moreWrapEl\" class=\"fe-breadcrumb__more-wrap\">\n <button\n type=\"button\"\n class=\"fe-breadcrumb__more\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"overflowOpen\"\n :aria-label=\"t('breadcrumb.more')\"\n :title=\"t('breadcrumb.more')\"\n @click=\"overflowOpen = !overflowOpen\"\n >…</button>\n <span class=\"fe-breadcrumb__sep\" aria-hidden=\"true\">›</span>\n <div v-if=\"overflowOpen\" class=\"fe-breadcrumb__menu\" role=\"menu\">\n <button\n v-for=\"c in middleCrumbs\"\n :key=\"c.adapterPath\"\n type=\"button\"\n class=\"fe-breadcrumb__menu-item\"\n role=\"menuitem\"\n @click=\"onOverflowPick(c)\"\n >{{ c.label }}</button>\n </div>\n </span>\n <button\n v-for=\"(c, i) in tailCrumbs\"\n :key=\"c.adapterPath\"\n class=\"fe-breadcrumb__crumb\"\n :class=\"{ 'is-last': i === tailCrumbs.length - 1 }\"\n type=\"button\"\n :aria-current=\"i === tailCrumbs.length - 1 ? 'page' : undefined\"\n @click=\"onClick(c)\"\n @contextmenu=\"onContext($event, c)\"\n @dragover=\"onCrumbDragOver\"\n @drop=\"onCrumbDrop($event, c)\"\n >\n <span>{{ c.label }}</span>\n <span v-if=\"i < tailCrumbs.length - 1\" class=\"fe-breadcrumb__sep\" aria-hidden=\"true\">›</span>\n </button>\n <button\n type=\"button\"\n class=\"fe-breadcrumb__edit\"\n :title=\"t('breadcrumb.go_to_path')\"\n :aria-label=\"t('breadcrumb.go_to_path')\"\n @click=\"startEdit\"\n >✏</button>\n </template>\n <template v-else>\n <input\n ref=\"pathInput\"\n v-model=\"pathDraft\"\n type=\"text\"\n class=\"fe-breadcrumb__input\"\n :placeholder=\"t('breadcrumb.path_placeholder')\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n @keydown.enter.prevent=\"submitPath\"\n @keydown.escape.prevent=\"cancelEdit\"\n @blur=\"cancelEdit\"\n />\n </template>\n </nav>\n</template>\n","/**\n * fileIcons — extension/type → inline SVG icon mapping.\n *\n * Replaces the old emoji maps in GridView/ListView with a minimalist\n * line-icon set. Icons are hand-drawn 24×24 strokes on `currentColor`;\n * each family gets an accent via `--fe-icon-<family>` (variables.css),\n * applied through the `fe-ficon--<family>` class in base.css.\n *\n * Scope: file-TYPE icons only. Action emojis (trash/star/…) and the\n * special `.trash` / storage rows stay emoji — see the views.\n */\n\nexport type IconFamily =\n | 'folder'\n | 'image'\n | 'video'\n | 'audio'\n | 'pdf'\n | 'doc'\n | 'sheet'\n | 'slides'\n | 'archive'\n | 'code'\n | 'text'\n | 'unknown';\n\nconst EXT_FAMILIES: Record<string, IconFamily> = {};\n\nfunction reg(family: IconFamily, exts: string[]) {\n for (const e of exts) EXT_FAMILIES[e] = family;\n}\n\nreg('image', ['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'avif', 'heic', 'svg', 'ico', 'tiff', 'tif']);\nreg('video', ['mp4', 'webm', 'mov', 'mkv', 'avi', 'ogv', 'm4v']);\nreg('audio', ['mp3', 'wav', 'flac', 'ogg', 'm4a', 'aac', 'opus']);\nreg('pdf', ['pdf']);\nreg('doc', ['doc', 'docx', 'odt', 'rtf']);\nreg('sheet', ['xls', 'xlsx', 'ods', 'csv']);\nreg('slides', ['ppt', 'pptx', 'odp']);\nreg('archive', ['zip', 'tar', 'gz', 'bz2', '7z', 'rar', 'xz', 'zst']);\nreg('code', [\n 'js', 'ts', 'jsx', 'tsx', 'mjs', 'cjs', 'vue', 'py', 'go', 'rs', 'php', 'rb',\n 'java', 'kt', 'swift', 'c', 'cpp', 'h', 'hpp', 'cs', 'css', 'scss', 'less',\n 'html', 'htm', 'json', 'yml', 'yaml', 'xml', 'sh', 'bash', 'ps1', 'sql', 'toml',\n]);\nreg('text', ['txt', 'md', 'markdown', 'log', 'ini', 'conf', 'cfg', 'env']);\n\n/** Pick the icon family for a listing node. */\nexport function iconFamilyFor(node: {\n type?: string;\n extension?: string | null;\n}): IconFamily {\n if (node.type === 'dir') return 'folder';\n const ext = (node.extension || '').toLowerCase();\n return EXT_FAMILIES[ext] ?? 'unknown';\n}\n\n// Shared fragments. The document families reuse one sheet-with-fold base so\n// the set reads as one system; media families get standalone shapes.\nconst FILE_BASE =\n '<path d=\"M6.5 3h7L18.5 8v11.5a1.5 1.5 0 0 1-1.5 1.5H6.5A1.5 1.5 0 0 1 5 19.5v-15A1.5 1.5 0 0 1 6.5 3z\"/>' +\n '<path d=\"M13.5 3v5h5\"/>';\n\nconst GLYPHS: Record<IconFamily, string> = {\n // Folder is the one \"filled\" member — a soft currentColor wash keeps it\n // visually anchored without breaking the line style.\n folder:\n '<path d=\"M3 7a2 2 0 0 1 2-2h4.2l2 2.4H19a2 2 0 0 1 2 2V17a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" fill=\"currentColor\" fill-opacity=\"0.14\"/>',\n image:\n '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/>' +\n '<circle cx=\"8.6\" cy=\"10\" r=\"1.6\"/>' +\n '<path d=\"M5.2 16.6l4.3-4.3 3 3 2.4-2.4 3.9 3.7\"/>',\n video:\n '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/>' +\n '<path d=\"M10.2 9.3v5.4l4.8-2.7z\" fill=\"currentColor\" stroke=\"none\"/>',\n audio:\n '<path d=\"M9 17.5V7.2l9-2.2v10.4\"/>' +\n '<circle cx=\"6.8\" cy=\"17.6\" r=\"2.2\"/>' +\n '<circle cx=\"15.8\" cy=\"15.5\" r=\"2.2\"/>',\n pdf:\n FILE_BASE +\n '<rect x=\"7.5\" y=\"12\" width=\"9\" height=\"5\" rx=\"1\" fill=\"currentColor\" fill-opacity=\"0.14\"/>',\n doc:\n FILE_BASE +\n '<path d=\"M8.5 13h7M8.5 16h7\"/>',\n sheet:\n FILE_BASE +\n '<path d=\"M8 12.5h8M8 15.5h8M8 18h8M12 12.5V18\"/>',\n slides:\n FILE_BASE +\n '<rect x=\"8\" y=\"12.5\" width=\"8\" height=\"5\" rx=\"0.8\"/>',\n archive:\n FILE_BASE +\n '<path d=\"M10 3v1.6M10 6.6v1.6M10 10.2v1.6\"/>' +\n '<rect x=\"8.6\" y=\"14\" width=\"2.8\" height=\"3.4\" rx=\"0.8\"/>',\n code:\n FILE_BASE +\n '<path d=\"M10.4 12.5L8.3 15l2.1 2.5M13.6 12.5l2.1 2.5-2.1 2.5\"/>',\n text:\n FILE_BASE +\n '<path d=\"M8.5 12h7M8.5 15h7M8.5 18h4.5\"/>',\n unknown:\n FILE_BASE +\n '<path d=\"M10.3 13.1a1.8 1.8 0 1 1 2.5 1.9c-.6.3-.8.7-.8 1.4\"/>' +\n '<circle cx=\"12\" cy=\"18.4\" r=\"0.9\" fill=\"currentColor\" stroke=\"none\"/>',\n};\n\nconst SVG_CACHE = new Map<IconFamily, string>();\n\n/** Inline SVG markup for a family (safe static strings — v-html friendly). */\nexport function iconSvg(family: IconFamily): string {\n let svg = SVG_CACHE.get(family);\n if (!svg) {\n svg =\n `<svg class=\"fe-ficon fe-ficon--${family}\" viewBox=\"0 0 24 24\" fill=\"none\" ` +\n 'stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" ' +\n 'stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">' +\n `${GLYPHS[family]}</svg>`;\n SVG_CACHE.set(family, svg);\n }\n return svg;\n}\n\n/** Convenience: node → SVG markup in one call. */\nexport function fileIconSvg(node: { type?: string; extension?: string | null }): string {\n return iconSvg(iconFamilyFor(node));\n}\n","/* bul:s3 */\n/**\n * Snippet segment parser — the search backend returns content snippets as\n * PLAIN TEXT with matched words wrapped in «guillemets» (contract: no HTML\n * ever crosses the wire). The UI renders highlights by splitting the string\n * into segments and emitting each one as a TEXT node (a <mark> wrapper for\n * matches) — never via innerHTML, so a file whose content contains markup\n * can't inject anything into the page.\n */\n\nexport interface SnippetSegment {\n /** Literal text of this segment. Always rendered as a text node. */\n text: string;\n /** True when the segment was «wrapped» — render inside <mark>. */\n match: boolean;\n}\n\n/**\n * Split a `«»`-annotated snippet into render segments. An unpaired `«`\n * degrades gracefully: the rest of the string is treated as plain text.\n */\nexport function snippetSegments(snippet: string): SnippetSegment[] {\n const out: SnippetSegment[] = [];\n if (!snippet) return out;\n const re = /«([^«»]*)»/g;\n let last = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(snippet)) !== null) {\n if (m.index > last) out.push({ text: snippet.slice(last, m.index), match: false });\n if (m[1]) out.push({ text: m[1], match: true });\n last = m.index + m[0].length;\n }\n if (last < snippet.length) out.push({ text: snippet.slice(last), match: false });\n return out;\n}\n\n/** Matched-in values the search contract allows on a hit. */\nexport type SearchMatched = 'name' | 'content' | 'both';\n\n/** True when the hit matched (at least partly) inside file CONTENT. */\nexport function matchedInContent(matched: unknown): boolean {\n return matched === 'content' || matched === 'both';\n}\n","<script setup lang=\"ts\">\n/**\n * StarButton — toggleable star indicator for a node.\n *\n * Backed by the `node_meta key=\"starred\"` server-side row (see\n * `POST /api/files/manager/star`). Optimistic update — flips the local\n * state immediately and rolls back on API error.\n */\nimport { ref, watch } from 'vue';\n\nconst props = defineProps<{\n starred: boolean;\n nodeId: number;\n apiBase?: string;\n /** Auth header builder injected by the parent file explorer. */\n authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n /** Compact mode for grid view (no label, just the icon). */\n compact?: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: 'change', value: boolean): void;\n (e: 'error', message: string): void;\n}>();\n\nconst local = ref(props.starred);\nwatch(() => props.starred, (v) => { local.value = v; });\n\nasync function toggle() {\n const next = !local.value;\n local.value = next; // optimistic\n try {\n const headers = {\n 'Content-Type': 'application/json',\n ...(await (props.authHeaders ?? (() => ({})))()),\n };\n const base = props.apiBase ?? '';\n const res = await fetch(`${base}/api/files/manager/star`, {\n method: 'POST',\n headers,\n credentials: 'include',\n body: JSON.stringify({ node_id: props.nodeId, starred: next }),\n });\n if (!res.ok) throw new Error(`star toggle failed: ${res.status}`);\n emit('change', next);\n } catch (err) {\n local.value = !next; // rollback\n emit('error', err instanceof Error ? err.message : String(err));\n }\n}\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"filex-star-btn\"\n :class=\"{ 'is-starred': local, 'is-compact': compact }\"\n :aria-pressed=\"local\"\n :title=\"local ? 'Unstar' : 'Star'\"\n @click.stop=\"toggle\"\n >\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" aria-hidden=\"true\">\n <path\n :fill=\"local ? 'currentColor' : 'none'\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linejoin=\"round\"\n d=\"M12 2.5l3.09 6.26 6.91 1-5 4.87 1.18 6.87L12 18.27l-6.18 3.23L7 14.63 2 9.76l6.91-1z\"\n />\n </svg>\n <span v-if=\"!compact\" class=\"filex-star-label\">{{ local ? 'Starred' : 'Star' }}</span>\n </button>\n</template>\n\n<style scoped>\n.filex-star-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 6px;\n padding: 4px 8px;\n color: var(--filex-text-muted, #9ca3af);\n cursor: pointer;\n transition: color 120ms, background 120ms;\n}\n.filex-star-btn:hover {\n color: var(--filex-accent-amber, #f59e0b);\n background: var(--filex-bg-soft, rgba(0, 0, 0, 0.04));\n}\n.filex-star-btn.is-starred {\n color: var(--filex-accent-amber, #f59e0b);\n}\n.filex-star-btn.is-compact {\n padding: 4px;\n}\n.filex-star-label {\n font-size: 13px;\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * ListView — tabular layout (name / size / modified).\n *\n * Selection + context menu + double-click open are caller-owned — we\n * just emit the events and let FileExplorer.vue handle them uniformly\n * across List and Grid.\n */\nimport { computed, ref } from 'vue';\nimport type { FileNode } from '../types/FileNode';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\nimport { fileIconSvg } from '../lib/fileIcons';\nimport { matchedInContent, snippetSegments } from '../lib/snippet'; /* bul:s3 */\nimport StarButton from './StarButton.vue';\n\nconst props = defineProps<{\n files: FileNode[];\n selected: Set<string>;\n /** Paths that were cut → dim them so the user sees the pending move. */\n clipped?: Set<string>;\n /**\n * Show each row's parent directory under the basename. Caller flips\n * this on while a search filter is active so the user can tell\n * `invoice.pdf` (in 2024/) apart from `invoice.pdf` (in 2025/) when\n * both match the same query.\n */\n showParentPath?: boolean;\n locale: LocaleCode;\n loading?: boolean;\n /** Set of node IDs flagged starred by the user — render an inline\n * filled star indicator and let the user toggle it from the row. */\n starredIds?: Set<number>;\n /** Backend base URL + auth header builder forwarded to StarButton\n * so it can POST /api/files/manager/star on click. Optional —\n * embedders without auth wire-up pass nothing and the star column\n * hides itself. */\n apiBase?: string;\n authHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'click-row', node: FileNode, mod: { ctrl: boolean; shift: boolean }): void;\n (e: 'dbl-row', node: FileNode): void;\n (e: 'context-row', node: FileNode, ev: MouseEvent): void;\n (e: 'item-drag-start', node: FileNode, ev: DragEvent): void;\n (e: 'item-drop-into', target: FileNode, ev: DragEvent): void;\n (e: 'star-change', node: FileNode, value: boolean): void;\n}>();\n\nconst { t, formatSize, nodeDisplayName } = useLocale(() => props.locale);\n\nfunction isSelected(n: FileNode): boolean {\n return props.selected.has(n.path);\n}\n\nfunction onRowClick(n: FileNode, ev: MouseEvent) {\n emit('click-row', n, { ctrl: ev.ctrlKey || ev.metaKey, shift: ev.shiftKey });\n}\n\nfunction onRowDbl(n: FileNode) {\n emit('dbl-row', n);\n}\n\nfunction onRowCtx(n: FileNode, ev: MouseEvent) {\n // Stop bubbling so the root `@contextmenu` handler doesn't fire and\n // clear the selection we just set.\n ev.preventDefault();\n ev.stopPropagation();\n emit('context-row', n, ev);\n}\n\nfunction onItemDragStart(n: FileNode, ev: DragEvent) {\n emit('item-drag-start', n, ev);\n}\n\nfunction onItemDragOver(n: FileNode, ev: DragEvent) {\n if (n.type !== 'dir') return;\n if (!ev.dataTransfer?.types.includes('application/x-brf-files')) return;\n ev.preventDefault();\n ev.stopPropagation();\n if (ev.dataTransfer) ev.dataTransfer.dropEffect = 'move';\n}\n\nfunction onItemDrop(n: FileNode, ev: DragEvent) {\n if (n.type !== 'dir') return;\n if (!ev.dataTransfer?.types.includes('application/x-brf-files')) return;\n ev.preventDefault();\n ev.stopPropagation();\n emit('item-drop-into', n, ev);\n}\n\nlet pressTimer: ReturnType<typeof setTimeout> | undefined;\nlet pressTarget: FileNode | null = null;\n\nfunction onTouchStart(n: FileNode, ev: TouchEvent) {\n pressTarget = n;\n if (pressTimer) clearTimeout(pressTimer);\n pressTimer = setTimeout(() => {\n if (pressTarget) {\n const t0 = ev.touches[0];\n emit('context-row', pressTarget, {\n clientX: t0.clientX,\n clientY: t0.clientY,\n preventDefault: () => {},\n } as unknown as MouseEvent);\n }\n }, 500);\n}\n\nfunction cancelPress() {\n if (pressTimer) clearTimeout(pressTimer);\n pressTarget = null;\n}\n\n// Special rows keep their emoji (trash/storage are not file-TYPE icons);\n// everything else renders the SVG icon set from lib/fileIcons.\nfunction specialEmojiFor(n: FileNode): string | null {\n if (n.basename === '.trash') return '🗑';\n if (n.mime_type === 'inode/storage') return '💾';\n return null;\n}\n\nfunction isPinnedSpecial(n: FileNode): boolean {\n return n.basename === '.trash' || n.mime_type === 'inode/storage';\n}\n\nfunction displayDate(ms: number | undefined): string {\n if (!ms) return '—';\n const d = new Date(ms * (ms < 1e12 ? 1000 : 1));\n return d.toLocaleString();\n}\n\nfunction parentDir(path: string): string {\n const stripped = path.replace(/^[a-z][a-z0-9+.-]*:\\/\\//i, '');\n const idx = stripped.lastIndexOf('/');\n if (idx === -1) return '';\n return stripped.slice(0, idx);\n}\n\n/* bul:s3 — search-result enrichment. The v0.2 backend inlines `snippet`\n * (plain text, «» highlights) + `matched` on search hits; regular listings\n * never carry them, so presence-gating keeps normal rows untouched and an\n * older backend simply renders nothing extra. */\nfunction rowSnippet(n: FileNode): string {\n const s = (n as Record<string, unknown>).snippet;\n return typeof s === 'string' ? s : '';\n}\n\nfunction rowInContent(n: FileNode): boolean {\n return matchedInContent((n as Record<string, unknown>).matched);\n}\n\n// ------------------------------------------------------------------\n// Column sorting — local to the list view. Default (null) keeps the\n// backend order, i.e. exactly the pre-existing behavior.\n// ------------------------------------------------------------------\n\ntype SortKey = 'name' | 'size' | 'modified';\nconst SORT_LS_KEY = 'filex.list-sort';\n\nconst sortKey = ref<SortKey | null>(null);\nconst sortDir = ref<'asc' | 'desc'>('asc');\ntry {\n const raw = localStorage.getItem(SORT_LS_KEY);\n if (raw) {\n const p = JSON.parse(raw) as { key?: unknown; dir?: unknown };\n if (p.key === 'name' || p.key === 'size' || p.key === 'modified') sortKey.value = p.key;\n if (p.dir === 'asc' || p.dir === 'desc') sortDir.value = p.dir;\n }\n} catch {\n /* private mode / bad JSON */\n}\n\n// Dates default to newest-first, the others to ascending.\nfunction defaultDir(key: SortKey): 'asc' | 'desc' {\n return key === 'modified' ? 'desc' : 'asc';\n}\n\n// Click cycle per column: default direction → flipped → back to backend order.\nfunction toggleSort(key: SortKey) {\n if (sortKey.value !== key) {\n sortKey.value = key;\n sortDir.value = defaultDir(key);\n } else if (sortDir.value === defaultDir(key)) {\n sortDir.value = sortDir.value === 'asc' ? 'desc' : 'asc';\n } else {\n sortKey.value = null;\n }\n try {\n localStorage.setItem(\n SORT_LS_KEY,\n JSON.stringify({ key: sortKey.value, dir: sortDir.value }),\n );\n } catch {\n /* quota */\n }\n}\n\nfunction ariaSort(key: SortKey): 'ascending' | 'descending' | 'none' {\n if (sortKey.value !== key) return 'none';\n return sortDir.value === 'asc' ? 'ascending' : 'descending';\n}\n\nfunction modifiedMs(n: FileNode): number | null {\n const v = n.last_modified;\n if (!v) return null;\n return v * (v < 1e12 ? 1000 : 1);\n}\n\nconst rows = computed(() => {\n const key = sortKey.value;\n if (!key) return props.files;\n // Virtual rows (.trash / storage drives) stay pinned on top in their\n // original order; only real entries take part in the sort.\n const pinned: FileNode[] = [];\n const rest: FileNode[] = [];\n for (const n of props.files) (isPinnedSpecial(n) ? pinned : rest).push(n);\n const dir = sortDir.value === 'asc' ? 1 : -1;\n rest.sort((a, b) => {\n if (key === 'name') {\n return (\n dir *\n a.basename.localeCompare(b.basename, undefined, { numeric: true, sensitivity: 'base' })\n );\n }\n if (key === 'size') return dir * ((a.size ?? -1) - (b.size ?? -1));\n const am = modifiedMs(a);\n const bm = modifiedMs(b);\n // Undated rows go last in both directions so date groups stay clean.\n if (am == null && bm == null) return 0;\n if (am == null) return 1;\n if (bm == null) return -1;\n return dir * (am - bm);\n });\n return [...pinned, ...rest];\n});\n\n// ------------------------------------------------------------------\n// Date grouping — only while sorted by modified date. Rows are split\n// into contiguous segments so the row markup below stays untouched.\n// ------------------------------------------------------------------\n\ninterface Segment {\n id: string;\n /** null = no header (ungrouped mode, or the pinned virtual rows). */\n label: string | null;\n nodes: FileNode[];\n}\n\nconst monthFmt = computed(\n () =>\n new Intl.DateTimeFormat(props.locale === 'tr' ? 'tr-TR' : 'en-US', {\n month: 'long',\n year: 'numeric',\n }),\n);\n\nfunction bucketFor(ms: number | null): { id: string; label: string } {\n if (ms == null) return { id: 'none', label: t('group.no_date') };\n const d = new Date(ms);\n const now = new Date();\n const dayStart = (x: Date) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();\n const today = dayStart(now);\n const day = dayStart(d);\n const DAY = 86_400_000;\n // Future stamps (clock skew) read best as \"today\".\n if (day >= today) return { id: 'today', label: t('group.today') };\n if (day === today - DAY) return { id: 'yesterday', label: t('group.yesterday') };\n if (day > today - 7 * DAY) return { id: 'week', label: t('group.this_week') };\n if (d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth()) {\n return { id: 'month', label: t('group.this_month') };\n }\n return { id: `m-${d.getFullYear()}-${d.getMonth()}`, label: monthFmt.value.format(d) };\n}\n\nconst segments = computed<Segment[]>(() => {\n const list = rows.value;\n if (sortKey.value !== 'modified') return [{ id: 'all', label: null, nodes: list }];\n const out: Segment[] = [];\n let cur: Segment | null = null;\n for (const n of list) {\n const b = isPinnedSpecial(n) ? { id: 'pinned', label: null } : bucketFor(modifiedMs(n));\n if (!cur || cur.id !== b.id) {\n cur = { id: b.id, label: b.label, nodes: [] };\n out.push(cur);\n }\n cur.nodes.push(n);\n }\n return out;\n});\n</script>\n\n<template>\n <div class=\"fe-list\" :class=\"{ 'is-loading': loading, 'has-star-col': !!apiBase || apiBase === '' }\">\n <div class=\"fe-list__head\" role=\"row\">\n <div class=\"fe-list__col fe-list__col--star\" role=\"columnheader\" aria-label=\"Star\"></div>\n <div class=\"fe-list__col fe-list__col--name\" role=\"columnheader\" :aria-sort=\"ariaSort('name')\">\n <button type=\"button\" class=\"fe-list__sort\" :title=\"t('col.sort')\" @click=\"toggleSort('name')\">\n {{ t('col.name') }}\n <span v-if=\"sortKey === 'name'\" class=\"fe-list__sort-arrow\" aria-hidden=\"true\">{{ sortDir === 'asc' ? '↑' : '↓' }}</span>\n </button>\n </div>\n <div class=\"fe-list__col fe-list__col--size\" role=\"columnheader\" :aria-sort=\"ariaSort('size')\">\n <button type=\"button\" class=\"fe-list__sort\" :title=\"t('col.sort')\" @click=\"toggleSort('size')\">\n {{ t('col.size') }}\n <span v-if=\"sortKey === 'size'\" class=\"fe-list__sort-arrow\" aria-hidden=\"true\">{{ sortDir === 'asc' ? '↑' : '↓' }}</span>\n </button>\n </div>\n <div class=\"fe-list__col fe-list__col--mod\" role=\"columnheader\" :aria-sort=\"ariaSort('modified')\">\n <button type=\"button\" class=\"fe-list__sort\" :title=\"t('col.sort')\" @click=\"toggleSort('modified')\">\n {{ t('col.modified') }}\n <span v-if=\"sortKey === 'modified'\" class=\"fe-list__sort-arrow\" aria-hidden=\"true\">{{ sortDir === 'asc' ? '↑' : '↓' }}</span>\n </button>\n </div>\n </div>\n <div class=\"fe-list__body\" role=\"rowgroup\">\n <template v-for=\"seg in segments\" :key=\"seg.id\">\n <div v-if=\"seg.label\" class=\"fe-list__group\" role=\"presentation\">{{ seg.label }}</div>\n <div\n v-for=\"n in seg.nodes\"\n :key=\"n.path\"\n class=\"fe-list__row\"\n :class=\"{\n 'is-selected': isSelected(n),\n 'is-dir': n.type === 'dir',\n 'is-trash': n.trashed,\n 'is-clipped': clipped?.has(n.path),\n }\"\n role=\"row\"\n tabindex=\"0\"\n draggable=\"true\"\n @click=\"onRowClick(n, $event)\"\n @dblclick=\"onRowDbl(n)\"\n @contextmenu=\"onRowCtx(n, $event)\"\n @dragstart=\"onItemDragStart(n, $event)\"\n @dragover=\"onItemDragOver(n, $event)\"\n @drop=\"onItemDrop(n, $event)\"\n @touchstart.passive=\"onTouchStart(n, $event)\"\n @touchend=\"cancelPress\"\n @touchmove=\"cancelPress\"\n >\n <div class=\"fe-list__col fe-list__col--star\" @click.stop>\n <StarButton\n v-if=\"typeof n.id === 'number' && n.type === 'file'\"\n :starred=\"!!starredIds?.has(n.id)\"\n :node-id=\"n.id\"\n :api-base=\"apiBase\"\n :auth-headers=\"authHeaders\"\n compact\n @change=\"(val: boolean) => emit('star-change', n, val)\"\n />\n </div>\n <div class=\"fe-list__col fe-list__col--name\">\n <span v-if=\"specialEmojiFor(n)\" class=\"fe-list__icon\" aria-hidden=\"true\">{{ specialEmojiFor(n) }}</span>\n <!-- eslint-disable-next-line vue/no-v-html — static markup from lib/fileIcons -->\n <span v-else class=\"fe-list__icon fe-list__icon--svg\" aria-hidden=\"true\" v-html=\"fileIconSvg(n)\"></span>\n <div class=\"fe-list__name-wrap\">\n <span class=\"fe-list__name\" :title=\"n.basename\">\n {{ nodeDisplayName(n) }}\n <!-- bul:s3 — content-match badge -->\n <span v-if=\"rowInContent(n)\" class=\"fe-list__badge\">{{ t('search.in_content') }}</span>\n </span>\n <span\n v-if=\"showParentPath\"\n class=\"fe-list__parent\"\n :title=\"parentDir(n.path)\"\n >{{ parentDir(n.path) || '—' }}</span>\n <!-- bul:s3 — content snippet («» → <mark> via TEXT segments, no innerHTML) -->\n <span v-if=\"rowSnippet(n)\" class=\"fe-list__snippet\">\n <template v-for=\"(seg, si) in snippetSegments(rowSnippet(n))\" :key=\"si\">\n <mark v-if=\"seg.match\" class=\"fe-list__mark\">{{ seg.text }}</mark>\n <template v-else>{{ seg.text }}</template>\n </template>\n </span>\n </div>\n </div>\n <div class=\"fe-list__col fe-list__col--size\">\n {{ formatSize(n.size) }}\n </div>\n <div class=\"fe-list__col fe-list__col--mod\">\n {{ displayDate(n.last_modified) }}\n </div>\n </div>\n </template>\n <div v-if=\"!loading && rows.length === 0\" class=\"fe-list__empty\">\n {{ t('empty.folder') }}\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GridView — card grid. Thumbnails preferred, fall back to icon.\n */\nimport type { FileNode } from '../types/FileNode';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\nimport { fileIconSvg } from '../lib/fileIcons';\n\nconst props = defineProps<{\n files: FileNode[];\n selected: Set<string>;\n clipped?: Set<string>;\n showParentPath?: boolean;\n locale: LocaleCode;\n loading?: boolean;\n /** Authenticated thumb resolver (useThumbs.src). Raw `thumb_url` is\n * root-relative and unauthenticated — a bare <img src> only works for the\n * native same-origin SPA, so embedded hosts NEED this. null = icon. */\n thumbSrc?: (n: FileNode) => string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: 'click-card', node: FileNode, mod: { ctrl: boolean; shift: boolean }): void;\n (e: 'dbl-card', node: FileNode): void;\n (e: 'context-card', node: FileNode, ev: MouseEvent): void;\n (e: 'item-drag-start', node: FileNode, ev: DragEvent): void;\n (e: 'item-drop-into', target: FileNode, ev: DragEvent): void;\n}>();\n\nconst { t, formatSize, nodeDisplayName } = useLocale(() => props.locale);\n\n// Prefer the authenticated resolver when the host wired one; otherwise fall\n// back to the raw URL (legacy same-origin behavior).\nfunction thumbOf(n: FileNode): string | null {\n return props.thumbSrc ? props.thumbSrc(n) : (n.thumb_url ?? null);\n}\n\nfunction isSelected(n: FileNode): boolean {\n return props.selected.has(n.path);\n}\n\nfunction onClick(n: FileNode, ev: MouseEvent) {\n emit('click-card', n, { ctrl: ev.ctrlKey || ev.metaKey, shift: ev.shiftKey });\n}\n\nfunction onDbl(n: FileNode) {\n emit('dbl-card', n);\n}\n\nfunction onCtx(n: FileNode, ev: MouseEvent) {\n ev.preventDefault();\n ev.stopPropagation();\n emit('context-card', n, ev);\n}\n\nfunction onItemDragStart(n: FileNode, ev: DragEvent) {\n emit('item-drag-start', n, ev);\n}\n\nfunction onItemDragOver(n: FileNode, ev: DragEvent) {\n if (n.type !== 'dir') return;\n if (!ev.dataTransfer?.types.includes('application/x-brf-files')) return;\n ev.preventDefault();\n ev.stopPropagation();\n if (ev.dataTransfer) ev.dataTransfer.dropEffect = 'move';\n}\n\nfunction onItemDrop(n: FileNode, ev: DragEvent) {\n if (n.type !== 'dir') return;\n if (!ev.dataTransfer?.types.includes('application/x-brf-files')) return;\n ev.preventDefault();\n ev.stopPropagation();\n emit('item-drop-into', n, ev);\n}\n\nlet pressTimer: ReturnType<typeof setTimeout> | undefined;\nlet pressTarget: FileNode | null = null;\nfunction onTouchStart(n: FileNode, ev: TouchEvent) {\n pressTarget = n;\n if (pressTimer) clearTimeout(pressTimer);\n pressTimer = setTimeout(() => {\n if (pressTarget) {\n const t0 = ev.touches[0];\n emit('context-card', pressTarget, {\n clientX: t0.clientX,\n clientY: t0.clientY,\n preventDefault: () => {},\n } as unknown as MouseEvent);\n }\n }, 500);\n}\nfunction cancelPress() {\n if (pressTimer) clearTimeout(pressTimer);\n pressTarget = null;\n}\n\nfunction parentDir(path: string): string {\n const stripped = path.replace(/^[a-z][a-z0-9+.-]*:\\/\\//i, '');\n const idx = stripped.lastIndexOf('/');\n if (idx === -1) return '';\n return stripped.slice(0, idx);\n}\n\n// Special rows keep their emoji (trash/storage are not file-TYPE icons);\n// everything else renders the SVG icon set from lib/fileIcons.\nfunction specialEmojiFor(n: FileNode): string | null {\n if (n.basename === '.trash') return '🗑';\n if (n.mime_type === 'inode/storage') return '💾';\n return null;\n}\n</script>\n\n<template>\n <div class=\"fe-grid\" :class=\"{ 'is-loading': loading }\">\n <div\n v-for=\"n in files\"\n :key=\"n.path\"\n class=\"fe-grid__card\"\n :class=\"{\n 'is-selected': isSelected(n),\n 'is-dir': n.type === 'dir',\n 'is-trash': n.trashed,\n 'is-clipped': clipped?.has(n.path),\n }\"\n tabindex=\"0\"\n draggable=\"true\"\n @click=\"onClick(n, $event)\"\n @dblclick=\"onDbl(n)\"\n @contextmenu=\"onCtx(n, $event)\"\n @dragstart=\"onItemDragStart(n, $event)\"\n @dragover=\"onItemDragOver(n, $event)\"\n @drop=\"onItemDrop(n, $event)\"\n @touchstart.passive=\"onTouchStart(n, $event)\"\n @touchend=\"cancelPress\"\n @touchmove=\"cancelPress\"\n >\n <div class=\"fe-grid__thumb\">\n <!--\n draggable=\"false\" — HTML5 image drag dataTransfer adds 'Files'\n MIME, which trips the parent's upload handler; without this\n the user dragging an item with a thumbnail re-uploads it.\n Parent card stays draggable=true so internal move works.\n -->\n <img\n v-if=\"thumbOf(n)\"\n :src=\"thumbOf(n)!\"\n :alt=\"n.basename\"\n loading=\"lazy\"\n draggable=\"false\"\n />\n <span v-else-if=\"specialEmojiFor(n)\" class=\"fe-grid__icon\">{{ specialEmojiFor(n) }}</span>\n <!-- eslint-disable-next-line vue/no-v-html — static markup from lib/fileIcons -->\n <span v-else class=\"fe-grid__icon fe-grid__icon--svg\" v-html=\"fileIconSvg(n)\"></span>\n </div>\n <div class=\"fe-grid__label\" :title=\"n.basename\">\n {{ nodeDisplayName(n) }}\n </div>\n <div\n v-if=\"showParentPath\"\n class=\"fe-grid__parent\"\n :title=\"parentDir(n.path)\"\n >{{ parentDir(n.path) || '—' }}</div>\n <div class=\"fe-grid__meta\">\n {{ formatSize(n.size) }}\n </div>\n </div>\n <div v-if=\"!loading && files.length === 0\" class=\"fe-grid__empty\">\n {{ t('empty.folder') }}\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * UploadProgress — floating footer showing active + recently-done uploads.\n */\nimport { computed } from 'vue';\nimport type { UploadJob } from '../composables/useUploadChunked';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\n\nconst props = defineProps<{\n jobs: UploadJob[];\n locale: LocaleCode;\n}>();\n\nconst emit = defineEmits<{\n (e: 'cancel', job: UploadJob): void;\n (e: 'dismiss', job: UploadJob): void;\n}>();\n\nconst { t, formatSize } = useLocale(() => props.locale);\n\nconst visible = computed(() => props.jobs);\n\nfunction statusLabel(j: UploadJob): string {\n switch (j.status) {\n case 'done':\n return t('upload.done');\n case 'error':\n return `${t('upload.error')}: ${j.error ?? ''}`;\n case 'aborted':\n return t('upload.aborted');\n default:\n return t('upload.progress');\n }\n}\n</script>\n\n<template>\n <transition name=\"fe-upload-slide\">\n <div v-if=\"visible.length > 0\" class=\"fe-upload\">\n <div class=\"fe-upload__header\">\n <strong>{{ t('upload.progress') }}</strong>\n <span class=\"fe-upload__count\">{{ visible.length }}</span>\n </div>\n <ul class=\"fe-upload__list\">\n <li\n v-for=\"j in visible\"\n :key=\"j.id\"\n class=\"fe-upload__item\"\n :class=\"`is-${j.status}`\"\n >\n <div class=\"fe-upload__name\" :title=\"j.file.name\">{{ j.file.name }}</div>\n <div class=\"fe-upload__bar\" :aria-valuenow=\"j.percent\" role=\"progressbar\">\n <div class=\"fe-upload__bar-fill\" :style=\"{ width: j.percent + '%' }\" />\n </div>\n <div class=\"fe-upload__meta\">\n <span>{{ statusLabel(j) }}</span>\n <span>{{ formatSize(j.uploadedBytes) }} / {{ formatSize(j.totalBytes) }}</span>\n <button\n v-if=\"j.status === 'uploading' || j.status === 'initializing'\"\n type=\"button\"\n class=\"fe-upload__cancel\"\n @click=\"emit('cancel', j)\"\n >\n {{ t('upload.cancel') }}\n </button>\n <button\n v-else\n type=\"button\"\n class=\"fe-upload__cancel\"\n @click=\"emit('dismiss', j)\"\n >×</button>\n </div>\n </li>\n </ul>\n </div>\n </transition>\n</template>\n","<script setup lang=\"ts\">\n/**\n * PendingOpsTray — bottom-left toast list for queued copy/move/delete.\n *\n * Sits next to UploadProgress visually (offset to its left when both\n * are open). Each row shows op type + a progress bar driven by\n * `progress_done / progress_total`. Terminal rows linger for a moment\n * (RETAIN_MS in usePendingOps) so the final state is visible before\n * they fade out.\n */\nimport { computed } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport type { PendingOp } from '../composables/usePendingOps';\nimport { useLocale } from '../composables/useLocale';\n\nconst props = defineProps<{\n ops: PendingOp[];\n locale: LocaleCode;\n}>();\n\nconst emit = defineEmits<{\n (e: 'dismiss', id: number): void;\n}>();\n\nconst { t } = useLocale(() => props.locale);\n\nconst sorted = computed(() => [...props.ops].sort((a, b) => b.id - a.id));\n\nfunction percent(op: PendingOp): number {\n if (op.status === 'done') return 100;\n if (op.progress_total <= 0) return 0;\n return Math.min(100, Math.round((op.progress_done / op.progress_total) * 100));\n}\n\nfunction statusClass(op: PendingOp): string {\n if (op.status === 'done') return 'is-done';\n if (op.status === 'error') return 'is-error';\n return '';\n}\n\nfunction summary(op: PendingOp): string {\n const verb =\n op.op_type === 'copy'\n ? t('ops.copy')\n : op.op_type === 'move'\n ? t('ops.move')\n : t('ops.delete');\n if (op.status === 'pending') return `${verb} (${t('ops.queued')})`;\n if (op.status === 'running') return `${verb} ${op.progress_done}/${op.progress_total}`;\n if (op.status === 'done') return `${verb} ${t('ops.done')} (${op.progress_total})`;\n if (op.status === 'error') return `${verb} ${t('ops.error')}`;\n return verb;\n}\n</script>\n\n<template>\n <transition-group\n v-if=\"sorted.length > 0\"\n name=\"fe-ops-slide\"\n tag=\"div\"\n class=\"fe-ops\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n v-for=\"op in sorted\"\n :key=\"op.id\"\n class=\"fe-ops__item\"\n :class=\"statusClass(op)\"\n >\n <div class=\"fe-ops__row\">\n <span class=\"fe-ops__title\" :title=\"op.target_path || op.source_dir || ''\">\n {{ summary(op) }}\n </span>\n <button\n v-if=\"op.status === 'done' || op.status === 'error'\"\n type=\"button\"\n class=\"fe-ops__dismiss\"\n aria-label=\"Dismiss\"\n @click=\"emit('dismiss', op.id)\"\n >×</button>\n </div>\n <div class=\"fe-ops__bar\">\n <div class=\"fe-ops__bar-fill\" :style=\"{ width: percent(op) + '%' }\" />\n </div>\n <div v-if=\"op.status === 'error' && op.error_message\" class=\"fe-ops__error\">\n {{ op.error_message }}\n </div>\n </div>\n </transition-group>\n</template>\n","<script setup lang=\"ts\">\n/**\n * InspectorPanel — koru:k1 details (\"Ayrıntılar\") side panel.\n *\n * Rendered as a flex sibling of `.fe__body` (right side, ~300px). In\n * `fe--narrow` embeds it becomes a full-size overlay with its own close\n * button (Esc handled by FileExplorer's shortcut chain).\n *\n * Sections:\n * - Genel : icon/thumb, name, path (copy), size, modified, mime, etag.\n * Multi-select → \"N items, total X\" summary; no selection →\n * current-folder summary.\n * - Sürümler : version history via GET /api/files/versions?node_id=…\n * + restore (with optional snapshot-current) + snapshot-now.\n * The section hides silently when the backend gates the\n * endpoint (401/403) or doesn't ship it (404).\n * - İzinler : effective RBAC level badge + \"manage\" (opens the existing\n * PermissionsModal through the host). Only when ACL is\n * enforced on the storage (perm is a non-empty string).\n * - Paylaşımlar: existing share links (GET /api/files/share?path=…) with\n * copy buttons. Hidden silently when the list call fails\n * (viewer-level users get 403 by design).\n *\n * The panel is mounted with v-if by the host — closed state leaves zero DOM.\n */\nimport { computed, ref, watch } from 'vue';\nimport type { FileApi, NodeVersion } from '../composables/useFileApi';\nimport type { FileNode, ShareInfo } from '../types/FileNode';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\nimport { fileIconSvg } from '../lib/fileIcons';\n\nconst props = defineProps<{\n api: FileApi;\n /** Current selection (empty array → current-folder summary). */\n nodes: FileNode[];\n /** Display label of the folder being viewed (for the no-selection state). */\n dirLabel: string;\n /** Number of entries in the folder being viewed. */\n dirCount: number;\n /** RBAC effective level of the current dir ('' = ACL not enforced). */\n dirPerm?: string;\n locale: LocaleCode;\n /** Narrow/embed mode → full-size overlay presentation. */\n narrow?: boolean;\n /** Authenticated thumbnail resolver (useThumbs.src). Optional. */\n thumbSrc?: (n: FileNode) => string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n (e: 'manage-permissions', node: FileNode): void;\n (e: 'toast', message: string): void;\n /** Fired after a successful restore/snapshot so the host can reload. */\n (e: 'changed'): void;\n}>();\n\nconst { t, formatSize, nodeDisplayName } = useLocale(() => props.locale);\n\n// ── selection shape ──────────────────────────────────────────────────\nconst single = computed<FileNode | null>(() =>\n props.nodes.length === 1 ? props.nodes[0] : null,\n);\nconst isMulti = computed(() => props.nodes.length > 1);\nconst isFile = computed(() => single.value?.type === 'file');\nconst nodeId = computed<number | null>(() =>\n typeof single.value?.id === 'number' ? (single.value.id as number) : null,\n);\nconst multiTotal = computed(() =>\n props.nodes.reduce((acc, n) => acc + (typeof n.size === 'number' ? n.size : 0), 0),\n);\nconst etag = computed<string | null>(() => {\n const v = single.value?.etag;\n return typeof v === 'string' && v !== '' ? v : null;\n});\nconst thumb = computed<string | null>(() =>\n single.value && isFile.value && props.thumbSrc ? props.thumbSrc(single.value) : null,\n);\n\nfunction shortHash(h: string): string {\n return h.length > 12 ? `${h.slice(0, 12)}…` : h;\n}\n\nfunction formatDate(ms: number | undefined): string {\n if (!ms) return '—';\n try {\n return new Date(ms).toLocaleString(props.locale === 'en' ? 'en-GB' : 'tr-TR', {\n dateStyle: 'medium',\n timeStyle: 'short',\n });\n } catch {\n return new Date(ms).toISOString();\n }\n}\n\nfunction formatDateStr(s: string | undefined | null): string {\n if (!s) return '—';\n const ms = Date.parse(s);\n return Number.isNaN(ms) ? s : formatDate(ms);\n}\n\nasync function copyText(text: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(text);\n emit('toast', t('inspector.copied'));\n } catch {\n emit('toast', text);\n }\n}\n\n// ── RBAC (İzinler) ───────────────────────────────────────────────────\n// Effective level for the selected item: its own perm, else the dir's.\n// A non-empty string means ACL is enforced → section shows.\nconst effectivePerm = computed<string>(() => {\n if (!single.value) return '';\n // Backends may send '' when ACL is off — widen past the declared union.\n const own = single.value.perm as string | undefined;\n if (typeof own === 'string' && own !== '') return own;\n return props.dirPerm || '';\n});\nconst canManagePerms = computed(\n () => effectivePerm.value === 'editor' || effectivePerm.value === 'owner',\n);\nfunction permLabel(level: string): string {\n return t(`inspector.perm.${level}`) === `inspector.perm.${level}`\n ? level\n : t(`inspector.perm.${level}`);\n}\n\n// ── versions state ───────────────────────────────────────────────────\ntype SectionState = 'idle' | 'loading' | 'ok' | 'hidden' | 'error';\nconst versionsState = ref<SectionState>('idle');\nconst versions = ref<NodeVersion[]>([]);\nconst confirmVersionId = ref<number | null>(null);\nconst snapshotFirst = ref(true);\nconst versionBusy = ref(false);\n\n// ── shares state ─────────────────────────────────────────────────────\nconst sharesState = ref<SectionState>('idle');\nconst shares = ref<ShareInfo[]>([]);\n\n// Race guard: only the latest refresh may write state.\nlet refreshSeq = 0;\n\nasync function refresh(): Promise<void> {\n const seq = ++refreshSeq;\n confirmVersionId.value = null;\n versions.value = [];\n shares.value = [];\n\n // Versions — single file with a backend node id only.\n if (single.value && isFile.value && nodeId.value != null) {\n versionsState.value = 'loading';\n void loadVersions(seq);\n } else {\n versionsState.value = 'hidden';\n }\n\n // Shares — any single selection (files and folders both shareable).\n if (single.value) {\n sharesState.value = 'loading';\n const path = single.value.path;\n try {\n const { shares: list } = await props.api.listShares(path);\n if (seq !== refreshSeq) return;\n shares.value = Array.isArray(list) ? list : [];\n sharesState.value = 'ok';\n } catch {\n if (seq !== refreshSeq) return;\n // 403 = viewer-level user (by design), anything else — auxiliary\n // info, hide silently rather than alarm.\n sharesState.value = 'hidden';\n }\n } else {\n sharesState.value = 'hidden';\n }\n}\n\nasync function loadVersions(seq: number): Promise<void> {\n const id = nodeId.value;\n if (id == null) return;\n try {\n const list = await props.api.listVersions(id);\n if (seq !== refreshSeq) return;\n versions.value = list;\n versionsState.value = 'ok';\n } catch (err) {\n if (seq !== refreshSeq) return;\n const status = (err as { status?: number }).status;\n // Gated (401/403) or absent (404) endpoint → section silently hidden.\n if (status === 401 || status === 403 || status === 404) {\n versionsState.value = 'hidden';\n } else {\n versionsState.value = 'error';\n }\n }\n}\n\nfunction askRestore(v: NodeVersion): void {\n confirmVersionId.value = v.id;\n snapshotFirst.value = true;\n}\n\nasync function confirmRestore(v: NodeVersion): Promise<void> {\n const id = nodeId.value;\n if (id == null || versionBusy.value) return;\n versionBusy.value = true;\n try {\n await props.api.restoreVersion(id, v.id, snapshotFirst.value);\n emit('toast', t('inspector.versions.restored'));\n confirmVersionId.value = null;\n emit('changed');\n await loadVersions(++refreshSeq);\n } catch (err) {\n emit('toast', (err as Error).message);\n } finally {\n versionBusy.value = false;\n }\n}\n\nasync function takeSnapshot(): Promise<void> {\n const id = nodeId.value;\n if (id == null || versionBusy.value) return;\n versionBusy.value = true;\n try {\n await props.api.snapshotVersion(id);\n emit('toast', t('inspector.versions.snapshotted'));\n await loadVersions(++refreshSeq);\n } catch (err) {\n const status = (err as { status?: number }).status;\n // Older backends don't ship POST /versions/snapshot yet.\n if (status === 404 || status === 405 || status === 501) {\n emit('toast', t('inspector.versions.unsupported'));\n } else {\n emit('toast', (err as Error).message);\n }\n } finally {\n versionBusy.value = false;\n }\n}\n\nwatch(\n () => props.nodes.map((n) => n.path).join('\u0000'),\n () => void refresh(),\n { immediate: true },\n);\n</script>\n\n<template>\n <aside\n class=\"fe-inspector\"\n :class=\"{ 'fe-inspector--overlay': narrow }\"\n role=\"complementary\"\n :aria-label=\"t('inspector.title')\"\n >\n <header class=\"fe-inspector__head\">\n <h2 class=\"fe-inspector__title\">{{ t('inspector.title') }}</h2>\n <button\n type=\"button\"\n class=\"fe-inspector__close\"\n :title=\"t('inspector.close')\"\n :aria-label=\"t('inspector.close')\"\n @click=\"emit('close')\"\n >×</button>\n </header>\n\n <div class=\"fe-inspector__scroll\">\n <!-- ══ Genel ══ -->\n <section class=\"fe-inspector__section\">\n <h3 class=\"fe-inspector__heading\">{{ t('inspector.section.general') }}</h3>\n\n <!-- Multi selection → summary -->\n <div v-if=\"isMulti\" class=\"fe-inspector__hero\">\n <span class=\"fe-inspector__bigicon\" v-html=\"fileIconSvg({ type: 'dir' })\"></span>\n <p class=\"fe-inspector__name\">\n {{ t('inspector.items_summary', { n: nodes.length, size: formatSize(multiTotal) }) }}\n </p>\n </div>\n\n <!-- Single selection → full meta -->\n <template v-else-if=\"single\">\n <div class=\"fe-inspector__hero\">\n <img\n v-if=\"thumb\"\n class=\"fe-inspector__thumb\"\n :src=\"thumb\"\n alt=\"\"\n aria-hidden=\"true\"\n />\n <span\n v-else\n class=\"fe-inspector__bigicon\"\n v-html=\"fileIconSvg(single)\"\n ></span>\n <p class=\"fe-inspector__name\" :title=\"single.basename\">\n {{ nodeDisplayName(single) }}\n </p>\n </div>\n\n <dl class=\"fe-inspector__meta\">\n <div class=\"fe-inspector__row\">\n <dt>{{ t('inspector.path') }}</dt>\n <dd class=\"fe-inspector__pathcell\">\n <span class=\"fe-inspector__path\" :title=\"single.path\">{{ single.path }}</span>\n <button\n type=\"button\"\n class=\"fe-inspector__copy\"\n :title=\"t('inspector.copy')\"\n :aria-label=\"t('inspector.copy')\"\n @click=\"copyText(single.path)\"\n >⧉</button>\n </dd>\n </div>\n <div v-if=\"isFile\" class=\"fe-inspector__row\">\n <dt>{{ t('inspector.size') }}</dt>\n <dd>{{ formatSize(typeof single.size === 'number' ? single.size : null) }}</dd>\n </div>\n <div class=\"fe-inspector__row\">\n <dt>{{ t('inspector.modified') }}</dt>\n <dd>{{ formatDate(single.last_modified) }}</dd>\n </div>\n <div v-if=\"isFile && single.mime_type\" class=\"fe-inspector__row\">\n <dt>{{ t('inspector.mime') }}</dt>\n <dd class=\"fe-inspector__mime\">{{ single.mime_type }}</dd>\n </div>\n <div v-if=\"etag\" class=\"fe-inspector__row\">\n <dt>{{ t('inspector.etag') }}</dt>\n <dd class=\"fe-inspector__pathcell\">\n <span class=\"fe-inspector__path\" :title=\"etag\">{{ shortHash(etag) }}</span>\n <button\n type=\"button\"\n class=\"fe-inspector__copy\"\n :title=\"t('inspector.copy')\"\n :aria-label=\"t('inspector.copy')\"\n @click=\"copyText(etag)\"\n >⧉</button>\n </dd>\n </div>\n </dl>\n </template>\n\n <!-- No selection → current folder summary -->\n <div v-else class=\"fe-inspector__hero\">\n <span class=\"fe-inspector__bigicon\" v-html=\"fileIconSvg({ type: 'dir' })\"></span>\n <p class=\"fe-inspector__name\" :title=\"dirLabel\">{{ dirLabel }}</p>\n <p class=\"fe-inspector__sub\">{{ t('inspector.folder_items', { n: dirCount }) }}</p>\n </div>\n </section>\n\n <!-- ══ Sürümler ══ -->\n <section\n v-if=\"versionsState === 'ok' || versionsState === 'error'\"\n class=\"fe-inspector__section\"\n >\n <h3 class=\"fe-inspector__heading\">{{ t('inspector.section.versions') }}</h3>\n\n <p v-if=\"versionsState === 'error'\" class=\"fe-inspector__empty\">\n {{ t('inspector.error') }}\n </p>\n <template v-else>\n <p v-if=\"versions.length === 0\" class=\"fe-inspector__empty\">\n {{ t('inspector.versions.empty') }}\n </p>\n <ul v-else class=\"fe-inspector__versions\">\n <li v-for=\"v in versions\" :key=\"v.id\" class=\"fe-inspector__version\">\n <div class=\"fe-inspector__version-main\">\n <span class=\"fe-inspector__version-n\">\n {{ t('inspector.versions.v', { n: v.version_n }) }}\n </span>\n <span class=\"fe-inspector__version-meta\">\n {{ formatDateStr(v.created_at) }} · {{ formatSize(v.size) }}\n </span>\n </div>\n <div v-if=\"confirmVersionId === v.id\" class=\"fe-inspector__confirm\">\n <p class=\"fe-inspector__confirm-q\">{{ t('inspector.versions.restore_confirm') }}</p>\n <label class=\"fe-inspector__check\">\n <input v-model=\"snapshotFirst\" type=\"checkbox\" />\n {{ t('inspector.versions.snapshot_current') }}\n </label>\n <div class=\"fe-inspector__confirm-actions\">\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--primary fe-btn--sm\"\n :disabled=\"versionBusy\"\n @click=\"confirmRestore(v)\"\n >{{ t('inspector.versions.confirm') }}</button>\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--sm\"\n :disabled=\"versionBusy\"\n @click=\"confirmVersionId = null\"\n >{{ t('inspector.versions.cancel') }}</button>\n </div>\n </div>\n <button\n v-else\n type=\"button\"\n class=\"fe-btn fe-btn--sm\"\n :disabled=\"versionBusy\"\n @click=\"askRestore(v)\"\n >{{ t('inspector.versions.restore') }}</button>\n </li>\n </ul>\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--sm fe-inspector__snapshot\"\n :disabled=\"versionBusy\"\n @click=\"takeSnapshot\"\n >{{ t('inspector.versions.take_snapshot') }}</button>\n </template>\n </section>\n\n <!-- ══ İzinler ══ -->\n <section v-if=\"single && effectivePerm\" class=\"fe-inspector__section\">\n <h3 class=\"fe-inspector__heading\">{{ t('inspector.section.permissions') }}</h3>\n <div class=\"fe-inspector__permrow\">\n <span\n class=\"fe-inspector__badge\"\n :class=\"`fe-inspector__badge--${effectivePerm}`\"\n >{{ permLabel(effectivePerm) }}</span>\n <button\n v-if=\"canManagePerms\"\n type=\"button\"\n class=\"fe-btn fe-btn--sm\"\n @click=\"emit('manage-permissions', single)\"\n >{{ t('inspector.perm.manage') }}</button>\n </div>\n </section>\n\n <!-- ══ Paylaşımlar ══ -->\n <section v-if=\"sharesState === 'ok'\" class=\"fe-inspector__section\">\n <h3 class=\"fe-inspector__heading\">{{ t('inspector.section.shares') }}</h3>\n <p v-if=\"shares.length === 0\" class=\"fe-inspector__empty\">\n {{ t('inspector.shares.empty') }}\n </p>\n <ul v-else class=\"fe-inspector__shares\">\n <li v-for=\"s in shares\" :key=\"s.uuid\" class=\"fe-inspector__share\">\n <span class=\"fe-inspector__share-url\" :title=\"s.url\">{{ s.url }}</span>\n <span v-if=\"s.password_pin\" class=\"fe-inspector__badge fe-inspector__badge--pin\">PIN</span>\n <span v-if=\"s.expires_at\" class=\"fe-inspector__share-exp\">\n {{ formatDateStr(s.expires_at) }}\n </span>\n <button\n type=\"button\"\n class=\"fe-inspector__copy\"\n :title=\"t('inspector.shares.copy')\"\n :aria-label=\"t('inspector.shares.copy')\"\n @click=\"copyText(s.url)\"\n >⧉</button>\n </li>\n </ul>\n </section>\n </div>\n </aside>\n</template>\n","<script setup lang=\"ts\">\n/**\n * CommandPalette — Ctrl/Cmd+K quick launcher.\n *\n * Sources (no new backend calls — everything comes from props):\n * 1. Files/folders of the CURRENT listing (`files` prop), filtered by a\n * tiny scored-includes matcher (no fuzzy-search dependency).\n * 2. Commands mapped 1:1 onto existing FileExplorer actions, surfaced as\n * individual emits so the host wires each to code it already has.\n * 3. Path jump: any query containing `/` offers a \"go to path\" entry.\n *\n * Keyboard: ↑/↓ move, Enter selects, Esc closes; the listener sits on the\n * document in CAPTURE phase so it wins over useKeyboardShortcuts' window\n * handler (otherwise Enter would also fire the explorer's own onOpen).\n *\n * bul:s3 additions:\n * 4. \"Everywhere\" group — ≥3-char queries also hit the global files-search\n * endpoint (debounced 250ms, max 8 rows) via the `globalSearch` prop.\n * Content matches get an \"İçerikte\" badge + a «»-highlighted snippet\n * rendered as pure text nodes (no innerHTML).\n * 5. Saved searches — localStorage-backed (`filex.saved-searches`, max 10);\n * \"save current query\" command + per-row delete.\n */\nimport { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport type { FileNode, ViewMode } from '../types/FileNode';\nimport type { GlobalSearchHit } from '../composables/useFileApi';\nimport { matchedInContent, snippetSegments } from '../lib/snippet';\nimport { useLocale } from '../composables/useLocale';\n\nconst props = defineProps<{\n open: boolean;\n locale: LocaleCode;\n files: FileNode[];\n viewMode: ViewMode;\n /** Gates the mutating commands (new folder / upload). */\n canWrite?: boolean;\n /** Gates the \"up one level\" command. */\n canGoUp?: boolean;\n /* bul:s3 — global search callback; absent = older host, group hidden. */\n globalSearch?: (q: string) => Promise<GlobalSearchHit[]>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n (e: 'open-node', node: FileNode): void;\n (e: 'navigate', path: string): void;\n (e: 'new-folder'): void;\n (e: 'upload'): void;\n (e: 'toggle-view'): void;\n (e: 'open-trash'): void;\n (e: 'refresh'): void;\n (e: 'go-up'): void;\n /* bul:s3 — an \"everywhere\" hit was chosen. */\n (e: 'open-hit', hit: GlobalSearchHit): void;\n}>();\n\nconst { t, nodeDisplayName } = useLocale(() => props.locale);\n\nconst query = ref('');\nconst active = ref(0);\nconst inputEl = ref<HTMLInputElement | null>(null);\nconst listEl = ref<HTMLElement | null>(null);\n\ntype PaletteItem =\n | { kind: 'goto'; id: string; label: string; icon: string; path: string }\n | { kind: 'file'; id: string; label: string; icon: string; node: FileNode }\n | { kind: 'command'; id: string; label: string; icon: string; command: string }\n /* bul:s3 — everywhere hit / saved search / save-current-query. */\n | { kind: 'hit'; id: string; label: string; icon: string; hit: GlobalSearchHit; crumb: string; inContent: boolean; snippet: string }\n | { kind: 'saved'; id: string; label: string; icon: string; query: string }\n | { kind: 'save'; id: string; label: string; icon: string; query: string };\n\n/* bul:s3 — narrowed aliases so the template doesn't need kind-guards. */\ntype HitItem = Extract<PaletteItem, { kind: 'hit' }>;\ntype SavedGroupItem = Extract<PaletteItem, { kind: 'saved' | 'save' }>;\n\n/**\n * Scored includes: -1 = no match; otherwise earlier + prefix matches rank\n * higher and shorter names get a small edge. Good enough without a fuzzy\n * dependency.\n */\nfunction matchScore(label: string, q: string): number {\n if (!q) return 0;\n const n = label.toLocaleLowerCase();\n const s = q.toLocaleLowerCase();\n const i = n.indexOf(s);\n if (i === -1) return -1;\n let sc = 100 - Math.min(i, 50);\n if (i === 0) sc += 40;\n sc -= Math.min(n.length, 40) / 4;\n return sc;\n}\n\nconst gotoItems = computed<PaletteItem[]>(() => {\n const q = query.value.trim();\n if (!q.includes('/')) return [];\n const clean = q.replace(/^\\/+|\\/+$/g, '');\n if (!clean) return [];\n return [\n { kind: 'goto', id: `goto:${clean}`, label: `${t('palette.goto')}: ${clean}`, icon: '➜', path: clean },\n ];\n});\n\nconst fileItems = computed<PaletteItem[]>(() => {\n const q = query.value.trim();\n const scored = props.files\n .map((f) => ({ f, name: nodeDisplayName(f), s: matchScore(nodeDisplayName(f), q) }))\n .filter((r) => r.s >= 0);\n if (q) scored.sort((a, b) => b.s - a.s);\n return scored.slice(0, 8).map((r) => ({\n kind: 'file' as const,\n id: `file:${r.f.path}`,\n label: r.name,\n icon: r.f.type === 'dir' ? '📁' : '📄',\n node: r.f,\n }));\n});\n\nconst commandItems = computed<PaletteItem[]>(() => {\n const q = query.value.trim();\n const defs: Array<{ command: string; label: string; icon: string; enabled: boolean }> = [\n { command: 'new-folder', label: t('toolbar.new_folder'), icon: '📁', enabled: props.canWrite !== false },\n { command: 'upload', label: t('toolbar.upload'), icon: '⬆', enabled: props.canWrite !== false },\n { command: 'toggle-view', label: t('cmd.view_toggle'), icon: props.viewMode === 'list' ? '▦' : '☰', enabled: true },\n { command: 'open-trash', label: t('cmd.trash'), icon: '🗑', enabled: true },\n { command: 'refresh', label: t('toolbar.refresh'), icon: '⟳', enabled: true },\n { command: 'go-up', label: t('toolbar.go_up'), icon: '↑', enabled: props.canGoUp !== false },\n ];\n return defs\n .filter((d) => d.enabled && matchScore(d.label, q) >= 0)\n .map((d) => ({ kind: 'command' as const, id: `cmd:${d.command}`, label: d.label, icon: d.icon, command: d.command }));\n});\n\n/* === bul:s3 — \"everywhere\" global search ================================ */\n\nconst EVERYWHERE_MIN_CHARS = 3;\nconst EVERYWHERE_LIMIT = 8;\nconst EVERYWHERE_DEBOUNCE_MS = 250;\n\nconst everywhere = ref<GlobalSearchHit[]>([]);\nconst everywhereLoading = ref(false);\nlet everywhereTimer: ReturnType<typeof setTimeout> | undefined;\nlet everywhereSeq = 0;\n\nfunction scheduleEverywhere(q: string) {\n if (everywhereTimer) clearTimeout(everywhereTimer);\n const fn = props.globalSearch;\n if (!fn || q.length < EVERYWHERE_MIN_CHARS) {\n everywhere.value = [];\n everywhereLoading.value = false;\n return;\n }\n everywhereLoading.value = true;\n everywhereTimer = setTimeout(async () => {\n const seq = ++everywhereSeq;\n try {\n const hits = await fn(q);\n if (seq !== everywhereSeq) return; // stale response — a newer query won\n everywhere.value = Array.isArray(hits) ? hits.slice(0, EVERYWHERE_LIMIT) : [];\n } catch {\n if (seq === everywhereSeq) everywhere.value = [];\n } finally {\n if (seq === everywhereSeq) everywhereLoading.value = false;\n }\n }, EVERYWHERE_DEBOUNCE_MS);\n}\n\n/** Parent-path crumb for a hit row (storage label when the hit carries one). */\nfunction hitCrumb(h: GlobalSearchHit): string {\n const rel = String(h.path ?? '').replace(/^\\/+|\\/+$/g, '');\n const slash = rel.lastIndexOf('/');\n const parent = slash === -1 ? '' : rel.slice(0, slash);\n const storage =\n (typeof h.storage === 'string' && h.storage) ||\n (typeof h.storage_name === 'string' && h.storage_name) ||\n '';\n if (storage && parent) return `${storage}/${parent}`;\n if (storage) return storage;\n return parent || '/';\n}\n\nconst hitItems = computed<HitItem[]>(() =>\n everywhere.value.map((h) => ({\n kind: 'hit' as const,\n id: `hit:${h.storage_id ?? ''}:${h.path ?? ''}:${h.id ?? ''}`,\n label: String(h.name ?? h.path ?? ''),\n icon: h.type === 'dir' ? '📁' : '📄',\n hit: h,\n crumb: hitCrumb(h),\n inContent: matchedInContent(h.matched),\n snippet: typeof h.snippet === 'string' ? h.snippet : '',\n })),\n);\n\n/* === bul:s3 — saved searches (localStorage) ============================= */\n\nconst SAVED_LS_KEY = 'filex.saved-searches';\nconst SAVED_MAX = 10;\n\nconst savedSearches = ref<string[]>([]);\n\nfunction readSavedSearches(): string[] {\n try {\n const raw = localStorage.getItem(SAVED_LS_KEY);\n if (!raw) return [];\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((x): x is string => typeof x === 'string' && x.trim() !== '').slice(0, SAVED_MAX);\n } catch {\n return [];\n }\n}\n\nfunction writeSavedSearches(list: string[]) {\n savedSearches.value = list.slice(0, SAVED_MAX);\n try {\n localStorage.setItem(SAVED_LS_KEY, JSON.stringify(savedSearches.value));\n } catch {\n /* private mode / quota — the in-memory list still works this session */\n }\n}\n\nfunction saveSearch(q: string) {\n const clean = q.trim();\n if (!clean) return;\n const list = savedSearches.value.filter((s) => s !== clean);\n list.unshift(clean); // newest first; cap enforced by writeSavedSearches\n writeSavedSearches(list);\n}\n\nfunction removeSavedSearch(q: string) {\n writeSavedSearches(savedSearches.value.filter((s) => s !== q));\n if (active.value >= flat.value.length) active.value = Math.max(0, flat.value.length - 1);\n}\n\nconst savedItems = computed<SavedGroupItem[]>(() => {\n const q = query.value.trim();\n const out: SavedGroupItem[] = [];\n // \"Save this query\" command — only when there IS a query and it isn't saved yet.\n if (q && !savedSearches.value.includes(q)) {\n out.push({ kind: 'save', id: `save:${q}`, label: `${t('palette.save')}: ${q}`, icon: '💾', query: q });\n }\n const scored = savedSearches.value\n .map((s) => ({ s, sc: matchScore(s, q) }))\n .filter((r) => r.sc >= 0 || !q);\n for (const r of scored) {\n out.push({ kind: 'saved', id: `saved:${r.s}`, label: r.s, icon: '🔖', query: r.s });\n }\n return out;\n});\n\n/* ======================================================================== */\n\nconst flat = computed<PaletteItem[]>(() => [\n ...gotoItems.value,\n ...fileItems.value,\n ...hitItems.value,\n ...savedItems.value,\n ...commandItems.value,\n]);\nconst fileOffset = computed(() => gotoItems.value.length);\nconst hitOffset = computed(() => fileOffset.value + fileItems.value.length);\nconst savedOffset = computed(() => hitOffset.value + hitItems.value.length);\nconst cmdOffset = computed(() => savedOffset.value + savedItems.value.length);\n\nwatch(query, (q) => {\n active.value = 0;\n scheduleEverywhere(q.trim()); /* bul:s3 */\n});\n\nfunction move(delta: number) {\n const n = flat.value.length;\n if (!n) return;\n active.value = (active.value + delta + n) % n;\n void nextTick(() => {\n listEl.value?.querySelector('.is-active')?.scrollIntoView({ block: 'nearest' });\n });\n}\n\nfunction choose(item?: PaletteItem) {\n const it = item ?? flat.value[active.value];\n if (!it) return;\n /* bul:s3 — saved-search rows keep the palette OPEN: picking one re-runs\n * the palette with that query; saving just persists it. */\n if (it.kind === 'saved') {\n query.value = it.query;\n void nextTick(() => inputEl.value?.focus());\n return;\n }\n if (it.kind === 'save') {\n saveSearch(it.query);\n void nextTick(() => inputEl.value?.focus());\n return;\n }\n emit('close');\n if (it.kind === 'hit') {\n emit('open-hit', it.hit);\n return;\n }\n if (it.kind === 'file') {\n emit('open-node', it.node);\n } else if (it.kind === 'goto') {\n emit('navigate', it.path);\n } else {\n switch (it.command) {\n case 'new-folder': emit('new-folder'); break;\n case 'upload': emit('upload'); break;\n case 'toggle-view': emit('toggle-view'); break;\n case 'open-trash': emit('open-trash'); break;\n case 'refresh': emit('refresh'); break;\n case 'go-up': emit('go-up'); break;\n }\n }\n}\n\nfunction onDocKeydown(e: KeyboardEvent) {\n if (!props.open) return;\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n e.stopPropagation();\n move(1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n e.stopPropagation();\n move(-1);\n break;\n case 'Enter':\n e.preventDefault();\n e.stopPropagation();\n choose();\n break;\n case 'Escape':\n e.preventDefault();\n e.stopPropagation();\n emit('close');\n break;\n }\n}\n\nwatch(\n () => props.open,\n (v) => {\n if (v) {\n query.value = '';\n active.value = 0;\n /* bul:s3 — fresh session state for the new groups. */\n everywhere.value = [];\n everywhereLoading.value = false;\n savedSearches.value = readSavedSearches();\n document.addEventListener('keydown', onDocKeydown, true);\n void nextTick(() => inputEl.value?.focus());\n } else {\n if (everywhereTimer) clearTimeout(everywhereTimer); /* bul:s3 */\n document.removeEventListener('keydown', onDocKeydown, true);\n }\n },\n);\n\nonBeforeUnmount(() => {\n if (everywhereTimer) clearTimeout(everywhereTimer); /* bul:s3 */\n document.removeEventListener('keydown', onDocKeydown, true);\n});\n</script>\n\n<template>\n <transition name=\"fe-modal\">\n <div\n v-if=\"open\"\n class=\"fe-modal__backdrop fe-cmdp__backdrop\"\n role=\"presentation\"\n @click=\"emit('close')\"\n >\n <div\n class=\"fe-cmdp\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"t('palette.placeholder')\"\n @click.stop\n >\n <div class=\"fe-cmdp__inputwrap\">\n <svg\n class=\"fe-cmdp__glyph\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"7\" cy=\"7\" r=\"4.5\" />\n <path d=\"m10.5 10.5 3.5 3.5\" />\n </svg>\n <input\n ref=\"inputEl\"\n v-model=\"query\"\n type=\"text\"\n class=\"fe-cmdp__input\"\n :placeholder=\"t('palette.placeholder')\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n\n <div ref=\"listEl\" class=\"fe-cmdp__list\" role=\"listbox\">\n <button\n v-for=\"(it, i) in gotoItems\"\n :key=\"it.id\"\n type=\"button\"\n class=\"fe-cmdp__item\"\n :class=\"{ 'is-active': i === active }\"\n role=\"option\"\n :aria-selected=\"i === active\"\n @mouseenter=\"active = i\"\n @click=\"choose(it)\"\n >\n <span class=\"fe-cmdp__icon\" aria-hidden=\"true\">{{ it.icon }}</span>\n <span class=\"fe-cmdp__label\">{{ it.label }}</span>\n </button>\n\n <template v-if=\"fileItems.length\">\n <div class=\"fe-cmdp__group\">{{ t('palette.files') }}</div>\n <button\n v-for=\"(it, i) in fileItems\"\n :key=\"it.id\"\n type=\"button\"\n class=\"fe-cmdp__item\"\n :class=\"{ 'is-active': fileOffset + i === active }\"\n role=\"option\"\n :aria-selected=\"fileOffset + i === active\"\n @mouseenter=\"active = fileOffset + i\"\n @click=\"choose(it)\"\n >\n <span class=\"fe-cmdp__icon\" aria-hidden=\"true\">{{ it.icon }}</span>\n <span class=\"fe-cmdp__label\">{{ it.label }}</span>\n </button>\n </template>\n\n <!-- bul:s3 — \"Everywhere\" global-search hits -->\n <template v-if=\"hitItems.length || everywhereLoading\">\n <div class=\"fe-cmdp__group\">{{ t('palette.everywhere') }}</div>\n <div v-if=\"everywhereLoading && !hitItems.length\" class=\"fe-cmdp__loading\">\n {{ t('palette.searching') }}\n </div>\n <button\n v-for=\"(it, i) in hitItems\"\n :key=\"it.id\"\n type=\"button\"\n class=\"fe-cmdp__item fe-cmdp__item--hit\"\n :class=\"{ 'is-active': hitOffset + i === active }\"\n role=\"option\"\n :aria-selected=\"hitOffset + i === active\"\n @mouseenter=\"active = hitOffset + i\"\n @click=\"choose(it)\"\n >\n <span class=\"fe-cmdp__icon\" aria-hidden=\"true\">{{ it.icon }}</span>\n <span class=\"fe-cmdp__hitbody\">\n <span class=\"fe-cmdp__hitline\">\n <span class=\"fe-cmdp__label\">{{ it.label }}</span>\n <span v-if=\"it.inContent\" class=\"fe-cmdp__badge\">{{ t('search.in_content') }}</span>\n </span>\n <span v-if=\"it.crumb\" class=\"fe-cmdp__crumb\" :title=\"it.crumb\">{{ it.crumb }}</span>\n <!-- Snippet: «»-highlights become <mark> via TEXT segments — never innerHTML. -->\n <span v-if=\"it.snippet\" class=\"fe-cmdp__snippet\">\n <template v-for=\"(seg, si) in snippetSegments(it.snippet)\" :key=\"si\">\n <mark v-if=\"seg.match\" class=\"fe-cmdp__mark\">{{ seg.text }}</mark>\n <template v-else>{{ seg.text }}</template>\n </template>\n </span>\n </span>\n </button>\n </template>\n\n <!-- bul:s3 — saved searches -->\n <template v-if=\"savedItems.length\">\n <div class=\"fe-cmdp__group\">{{ t('palette.saved') }}</div>\n <div\n v-for=\"(it, i) in savedItems\"\n :key=\"it.id\"\n class=\"fe-cmdp__item fe-cmdp__item--saved\"\n :class=\"{ 'is-active': savedOffset + i === active }\"\n role=\"option\"\n :aria-selected=\"savedOffset + i === active\"\n tabindex=\"-1\"\n @mouseenter=\"active = savedOffset + i\"\n @click=\"choose(it)\"\n @keydown.enter.prevent=\"choose(it)\"\n >\n <span class=\"fe-cmdp__icon\" aria-hidden=\"true\">{{ it.icon }}</span>\n <span class=\"fe-cmdp__label\">{{ it.label }}</span>\n <button\n v-if=\"it.kind === 'saved'\"\n type=\"button\"\n class=\"fe-cmdp__del\"\n :title=\"t('palette.saved.delete')\"\n :aria-label=\"t('palette.saved.delete')\"\n @click.stop=\"removeSavedSearch(it.query)\"\n >🗑</button>\n </div>\n </template>\n\n <template v-if=\"commandItems.length\">\n <div class=\"fe-cmdp__group\">{{ t('palette.commands') }}</div>\n <button\n v-for=\"(it, i) in commandItems\"\n :key=\"it.id\"\n type=\"button\"\n class=\"fe-cmdp__item\"\n :class=\"{ 'is-active': cmdOffset + i === active }\"\n role=\"option\"\n :aria-selected=\"cmdOffset + i === active\"\n @mouseenter=\"active = cmdOffset + i\"\n @click=\"choose(it)\"\n >\n <span class=\"fe-cmdp__icon\" aria-hidden=\"true\">{{ it.icon }}</span>\n <span class=\"fe-cmdp__label\">{{ it.label }}</span>\n </button>\n </template>\n\n <div v-if=\"flat.length === 0 && !everywhereLoading\" class=\"fe-cmdp__empty\">\n {{ t('palette.empty') }}\n </div>\n </div>\n\n <div class=\"fe-cmdp__hint\">{{ t('palette.hint') }}</div>\n </div>\n </div>\n </transition>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Modal — tiny headless wrapper. Backdrop + centered card + ESC + autofocus.\n */\nimport { watch, onBeforeUnmount, ref } from 'vue';\n\nconst props = defineProps<{\n open: boolean;\n title?: string;\n size?: 'sm' | 'md' | 'lg' | 'xl';\n closeOnBackdrop?: boolean;\n /** When true, drop the dialog chrome (backdrop tint, header, footer,\n * centered card with border-radius) and render the slot full-bleed.\n * Used by the standalone /files/edit route where the browser tab IS\n * the container — a modal frame on top of it just steals real estate\n * from the editor. ESC + emit('close') still wire through so the\n * parent route can window.close() the tab. */\n chromeless?: boolean;\n /** Explicit theme. When set the modal stamps the appropriate\n * `.fe--theme-{light,dark}` class on its `.fe` backdrop so the CSS\n * variable cascade matches the host shell regardless of OS\n * preference (Modal is a portal-shaped descendant of `<body>`\n * rather than a child of the parent component, so plain DOM\n * inheritance isn't always enough). */\n theme?: 'light' | 'dark' | 'auto';\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n}>();\n\nconst cardEl = ref<HTMLElement | null>(null);\n\nwatch(\n () => props.open,\n (v) => {\n if (v) {\n document.addEventListener('keydown', onKey);\n setTimeout(() => {\n const focusable = cardEl.value?.querySelector<HTMLElement>(\n 'input,select,textarea,button,[tabindex]:not([tabindex=\"-1\"])',\n );\n focusable?.focus();\n }, 30);\n } else {\n document.removeEventListener('keydown', onKey);\n }\n },\n);\n\nonBeforeUnmount(() => document.removeEventListener('keydown', onKey));\n\nfunction onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') emit('close');\n}\n\nfunction onBackdrop() {\n if (props.closeOnBackdrop !== false) emit('close');\n}\n</script>\n\n<template>\n <transition name=\"fe-modal\">\n <div\n v-if=\"open\"\n class=\"fe fe-modal__backdrop\"\n :class=\"[\n { 'fe-modal__backdrop--chromeless': chromeless },\n theme === 'light' ? 'fe--theme-light' : '',\n theme === 'dark' ? 'fe--theme-dark' : '',\n ]\"\n role=\"presentation\"\n @click=\"onBackdrop\"\n >\n <div\n ref=\"cardEl\"\n class=\"fe-modal__card\"\n :class=\"[\n `fe-modal__card--${size || 'md'}`,\n chromeless && 'fe-modal__card--chromeless',\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n @click.stop\n >\n <header v-if=\"title && !chromeless\" class=\"fe-modal__head\">\n <h2 class=\"fe-modal__title\">{{ title }}</h2>\n <button\n type=\"button\"\n class=\"fe-modal__close\"\n aria-label=\"Close\"\n @click=\"emit('close')\"\n >×</button>\n </header>\n <div class=\"fe-modal__body\">\n <slot />\n </div>\n <footer v-if=\"$slots.actions && !chromeless\" class=\"fe-modal__actions\">\n <slot name=\"actions\" />\n </footer>\n </div>\n </div>\n </transition>\n</template>\n","<script setup lang=\"ts\">\n/**\n * ShortcutsHelp — \"?\" cheat-sheet modal.\n *\n * Renders the SHORTCUTS table exported by useKeyboardShortcuts (single\n * source of truth) grouped by section. Modal.vue supplies Esc handling,\n * backdrop, focus and the close button.\n */\nimport { computed } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\nimport { SHORTCUTS, type ShortcutDef } from '../composables/useKeyboardShortcuts';\nimport Modal from '../modals/Modal.vue';\n\nconst props = defineProps<{\n open: boolean;\n locale: LocaleCode;\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n}>();\n\nconst { t } = useLocale(() => props.locale);\n\nconst groups = computed(() => {\n const order: string[] = [];\n const map = new Map<string, ShortcutDef[]>();\n for (const s of SHORTCUTS) {\n if (!map.has(s.groupKey)) {\n map.set(s.groupKey, []);\n order.push(s.groupKey);\n }\n map.get(s.groupKey)!.push(s);\n }\n return order.map((key) => ({ key, items: map.get(key)! }));\n});\n</script>\n\n<template>\n <Modal :open=\"open\" :title=\"t('shortcuts.title')\" size=\"md\" @close=\"emit('close')\">\n <div class=\"fe-shortcuts\">\n <section v-for=\"g in groups\" :key=\"g.key\" class=\"fe-shortcuts__group\">\n <h3 class=\"fe-shortcuts__heading\">{{ t(g.key) }}</h3>\n <div class=\"fe-shortcuts__table\">\n <div v-for=\"s in g.items\" :key=\"s.labelKey\" class=\"fe-shortcuts__row\">\n <span class=\"fe-shortcuts__keys\">\n <template v-for=\"(combo, i) in s.keys\" :key=\"combo\">\n <kbd class=\"fe-kbd\">{{ combo }}</kbd>\n <span v-if=\"i < s.keys.length - 1\" class=\"fe-shortcuts__or\" aria-hidden=\"true\">/</span>\n </template>\n </span>\n <span class=\"fe-shortcuts__desc\">{{ t(s.labelKey) }}</span>\n </div>\n </div>\n </section>\n </div>\n </Modal>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\nimport Modal from './Modal.vue';\n\nconst props = defineProps<{\n open: boolean;\n locale: LocaleCode;\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n (e: 'submit', name: string): void;\n}>();\n\nconst { t } = useLocale(() => props.locale);\nconst name = ref('');\nconst err = ref<string | null>(null);\n\nwatch(() => props.open, (v) => {\n if (v) {\n name.value = '';\n err.value = null;\n }\n});\n\nfunction submit() {\n const clean = name.value.trim();\n if (!clean) {\n err.value = t('modal.newfolder.placeholder');\n return;\n }\n if (/[\\\\/]/.test(clean) || clean === '.' || clean === '..') {\n err.value = 'Geçersiz karakter';\n return;\n }\n emit('submit', clean);\n}\n</script>\n\n<template>\n <Modal :open=\"open\" :title=\"t('modal.newfolder.title')\" size=\"sm\" @close=\"emit('close')\">\n <form @submit.prevent=\"submit\">\n <input\n v-model=\"name\"\n type=\"text\"\n class=\"fe-input\"\n :placeholder=\"t('modal.newfolder.placeholder')\"\n autocomplete=\"off\"\n @keydown.enter.prevent=\"submit\"\n />\n <p v-if=\"err\" class=\"fe-form__error\">{{ err }}</p>\n </form>\n <template #actions>\n <button type=\"button\" class=\"fe-btn\" @click=\"emit('close')\">\n {{ t('modal.newfolder.cancel') }}\n </button>\n <button type=\"button\" class=\"fe-btn fe-btn--primary\" @click=\"submit\">\n {{ t('modal.newfolder.create') }}\n </button>\n </template>\n </Modal>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\nimport Modal from './Modal.vue';\n\nconst props = defineProps<{\n open: boolean;\n locale: LocaleCode;\n currentName: string;\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n (e: 'submit', name: string): void;\n}>();\n\nconst { t } = useLocale(() => props.locale);\nconst name = ref('');\n\nwatch(\n () => [props.open, props.currentName] as const,\n ([isOpen, cur]) => {\n if (isOpen) {\n name.value = cur;\n }\n },\n);\n\nfunction submit() {\n const clean = name.value.trim();\n if (!clean) return;\n if (/[\\\\/]/.test(clean) || clean === '.' || clean === '..') return;\n emit('submit', clean);\n}\n</script>\n\n<template>\n <Modal :open=\"open\" :title=\"t('modal.rename.title')\" size=\"sm\" @close=\"emit('close')\">\n <form @submit.prevent=\"submit\">\n <input\n v-model=\"name\"\n type=\"text\"\n class=\"fe-input\"\n autocomplete=\"off\"\n @keydown.enter.prevent=\"submit\"\n />\n </form>\n <template #actions>\n <button type=\"button\" class=\"fe-btn\" @click=\"emit('close')\">\n {{ t('modal.rename.cancel') }}\n </button>\n <button type=\"button\" class=\"fe-btn fe-btn--primary\" @click=\"submit\">\n {{ t('modal.rename.save') }}\n </button>\n </template>\n </Modal>\n</template>\n","<script setup lang=\"ts\">\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport { useLocale } from '../composables/useLocale';\nimport Modal from './Modal.vue';\n\nconst props = defineProps<{\n open: boolean;\n locale: LocaleCode;\n count: number;\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n (e: 'confirm'): void;\n}>();\n\nconst { t } = useLocale(() => props.locale);\n</script>\n\n<template>\n <Modal :open=\"open\" :title=\"t('modal.delete.title')\" size=\"sm\" @close=\"emit('close')\">\n <p>{{ t('modal.delete.message', { count }) }}</p>\n <template #actions>\n <button type=\"button\" class=\"fe-btn\" @click=\"emit('close')\">\n {{ t('modal.delete.cancel') }}\n </button>\n <button type=\"button\" class=\"fe-btn fe-btn--danger\" @click=\"emit('confirm')\">\n {{ t('modal.delete.confirm') }}\n </button>\n </template>\n </Modal>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport type { ShareInfo } from '../types/FileNode';\nimport { useLocale } from '../composables/useLocale';\nimport Modal from './Modal.vue';\n\nconst props = defineProps<{\n open: boolean;\n locale: LocaleCode;\n share?: (ShareInfo & { url: string; filename?: string }) | null;\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n (\n e: 'submit',\n payload: { password: boolean; expires_at: string | null; max_downloads: number | null },\n ): void;\n (e: 'toast', msg: string): void;\n}>();\n\nconst { t } = useLocale(() => props.locale);\n\nconst usePin = ref(false);\nconst expiresAt = ref<string>('');\nconst maxDownloads = ref<string>('');\n\nwatch(() => props.open, (v) => {\n if (v) {\n usePin.value = false;\n expiresAt.value = '';\n maxDownloads.value = '';\n }\n});\n\nfunction submit() {\n emit('submit', {\n password: usePin.value,\n expires_at: expiresAt.value ? new Date(expiresAt.value).toISOString() : null,\n max_downloads: maxDownloads.value ? Number(maxDownloads.value) : null,\n });\n}\n\nasync function copy(value: string, toast: string) {\n try {\n await navigator.clipboard.writeText(value);\n emit('toast', toast);\n } catch {\n /* no-op */\n }\n}\n\n// Wrap a value in single quotes for safe paste into a POSIX shell —\n// embedded single quotes become the standard '\\'' dance.\nfunction shQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\n// One-line curl that downloads the shared file straight onto a server.\n// The PIN (if any) rides in the querystring — HandleDownload accepts\n// ?pin=, and -L follows the 302 to the presigned URL for S3 storages.\nconst cliCommand = computed(() => {\n const sh = props.share;\n if (!sh) return '';\n let url = sh.url;\n if (sh.password_pin) {\n url += (url.includes('?') ? '&' : '?') + 'pin=' + encodeURIComponent(sh.password_pin);\n }\n // Prefer an explicit output name; fall back to the server's\n // Content-Disposition filename (-OJ) when we don't know it.\n const target = sh.filename ? `-o ${shQuote(sh.filename)} ` : '-OJ ';\n return `curl -fSL ${target}${shQuote(url)}`;\n});\n</script>\n\n<template>\n <Modal :open=\"open\" :title=\"t('modal.share.title')\" size=\"md\" @close=\"emit('close')\">\n <template v-if=\"!share\">\n <form class=\"fe-form\" @submit.prevent=\"submit\">\n <label class=\"fe-form__row\">\n <input v-model=\"usePin\" type=\"checkbox\" />\n <span>{{ t('modal.share.pin') }}</span>\n </label>\n <label class=\"fe-form__row fe-form__row--stack\">\n <span>{{ t('modal.share.expires') }}</span>\n <input v-model=\"expiresAt\" type=\"datetime-local\" class=\"fe-input\" />\n </label>\n <label class=\"fe-form__row fe-form__row--stack\">\n <span>{{ t('modal.share.max_downloads') }}</span>\n <input v-model=\"maxDownloads\" type=\"number\" min=\"1\" class=\"fe-input\" />\n </label>\n </form>\n </template>\n <template v-else>\n <div class=\"fe-share-result\">\n <div class=\"fe-share-result__row\">\n <label>Link</label>\n <div class=\"fe-share-result__copy\">\n <input :value=\"share.url\" readonly class=\"fe-input\" />\n <button type=\"button\" class=\"fe-btn\" @click=\"copy(share.url, t('modal.share.url_copied'))\">\n {{ t('modal.share.copy') }}\n </button>\n </div>\n </div>\n <div v-if=\"share.password_pin\" class=\"fe-share-result__row\">\n <label>PIN</label>\n <div class=\"fe-share-result__copy\">\n <input :value=\"share.password_pin\" readonly class=\"fe-input fe-input--mono\" />\n <button type=\"button\" class=\"fe-btn\" @click=\"copy(share.password_pin, t('modal.share.pin_copied'))\">\n {{ t('modal.share.copy') }}\n </button>\n </div>\n </div>\n <div class=\"fe-share-result__row\">\n <label>CLI</label>\n <div class=\"fe-share-result__copy\">\n <input :value=\"cliCommand\" readonly class=\"fe-input fe-input--mono\" />\n <button type=\"button\" class=\"fe-btn\" @click=\"copy(cliCommand, t('modal.share.cli_copied'))\">\n {{ t('modal.share.copy') }}\n </button>\n </div>\n </div>\n </div>\n </template>\n <template #actions>\n <button type=\"button\" class=\"fe-btn\" @click=\"emit('close')\">\n {{ share ? 'Kapat' : t('modal.share.cancel') }}\n </button>\n <button v-if=\"!share\" type=\"button\" class=\"fe-btn fe-btn--primary\" @click=\"submit\">\n {{ t('modal.share.create') }}\n </button>\n </template>\n </Modal>\n</template>\n","<script setup lang=\"ts\">\n/**\n * PreviewModal — inline file preview.\n *\n * Strategy by extension:\n * image / video / audio / pdf → native browser elements\n * md / markdown → markdown-it (lazy) → rendered HTML\n * code (js/ts/php/py/json/...) → Monaco when ready, highlight.js\n * fallback while it's still loading,\n * plain `<pre>` when neither is\n * installed\n * office (docx/xlsx/pptx) → OnlyOffice iframe (config.onlyOfficeBase)\n * plain text (txt/log/conf) → CodeMirror when saveText is set,\n * `<pre>` otherwise\n * anything else → \"indir\" fallback\n *\n * Monaco is dynamic-imported at FileExplorer onMounted; by the time the\n * user clicks an editable code file the chunk is usually already cached.\n * We probe `getMonaco()` synchronously when the modal opens — if it's\n * not yet loaded we render the highlight.js read-only view immediately,\n * then upgrade to Monaco once the import resolves.\n */\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue';\nimport type { Component } from 'vue';\nimport type { FileNode } from '../types/FileNode';\nimport type { LocaleCode } from '../types/ExplorerConfig';\nimport Modal from './Modal.vue';\nimport { ensureMonaco, getMonaco, ensureHighlight } from '../composables/useMonacoLoader';\nimport { useLocale } from '../composables/useLocale';\n\nconst props = defineProps<{\n open: boolean;\n locale: LocaleCode;\n file: FileNode | null;\n previewUrl: (path: string) => string;\n downloadUrl: (path: string) => string;\n onlyOfficeBase?: string | null;\n onlyOfficeConfigEndpoint?: string | null;\n saveTextEndpoint?: string | null;\n openMode?: 'edit' | 'view';\n authHeaders?: () => Record<string, string>;\n authCredentials?: RequestCredentials;\n /** New rich-viewer config (forwarded by FileExplorer from ExplorerConfig). */\n drawioUrl?: string | null;\n pdfWorkerUrl?: string | null;\n pdfSaveUrl?: string | null;\n /** Standalone full-screen viewer route — `?path=…&storage=…&type=…`. */\n viewerBaseUrl?: string | null;\n /** Drop the dialog chrome (backdrop tint, header bar, footer actions)\n * so the viewer fills the full viewport. Used by the standalone\n * /files/edit route where the browser tab IS the container — a\n * modal frame on top of the editor just steals real estate. */\n chromeless?: boolean;\n /** When the dynamic-viewer chunk fails to load, fall back to the\n * legacy native renderer (e.g. native `<object>` for PDFs). */\n /** Explicit theme. Forwarded to the underlying Modal (which tags\n * its backdrop with `.fe--theme-{light,dark}` so the CSS variable\n * override matches the host admin shell) and to Monaco (vs vs\n * vs-dark). When unset Monaco falls back to `prefers-color-scheme`\n * and the modal cascade follows whatever `.fe` parent it gets. */\n theme?: 'light' | 'dark' | 'auto';\n}>();\n\nconst emit = defineEmits<{\n (e: 'close'): void;\n}>();\n\nconst { t } = useLocale(() => props.locale);\n\nfunction ext(f: FileNode | null): string {\n return (f?.extension || '').toLowerCase();\n}\n\nconst IMAGE = ['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'avif', 'svg', 'heic'];\nconst VIDEO = ['mp4', 'webm', 'mov', 'mkv', 'm4v', 'ogv'];\nconst AUDIO = ['mp3', 'wav', 'ogg', 'flac', 'm4a', 'aac', 'opus'];\n\nconst CODE_LANGS: Record<string, string> = {\n md: 'markdown', markdown: 'markdown',\n txt: 'plaintext', log: 'plaintext',\n js: 'javascript', mjs: 'javascript', cjs: 'javascript',\n ts: 'typescript', tsx: 'typescript', jsx: 'javascript',\n vue: 'xml', svelte: 'xml', html: 'xml', htm: 'xml', xml: 'xml', svg: 'xml',\n css: 'css', scss: 'scss', sass: 'scss', less: 'less',\n json: 'json', jsonc: 'json',\n yml: 'yaml', yaml: 'yaml',\n php: 'php', py: 'python', rb: 'ruby', go: 'go', rs: 'rust',\n java: 'java', kt: 'kotlin', swift: 'swift', cpp: 'cpp', c: 'c',\n h: 'cpp', hpp: 'cpp', cs: 'csharp', dart: 'dart',\n sh: 'bash', bash: 'bash', zsh: 'bash', fish: 'bash',\n sql: 'sql',\n toml: 'ini', ini: 'ini', conf: 'ini', env: 'bash', cfg: 'ini',\n dockerfile: 'dockerfile',\n graphql: 'graphql', gql: 'graphql',\n diff: 'diff', patch: 'diff',\n};\n// CSV/TSV land in the rich viewer (`csv` kind below) instead of the\n// legacy plain-text path so the user gets a proper table preview.\nconst TEXT_PLAIN = ['txt', 'log'];\nconst OFFICE = ['docx', 'doc', 'xlsx', 'xls', 'pptx', 'ppt', 'odt', 'ods', 'odp', 'rtf'];\n\n/**\n * Lazy viewer map — extension → component loader. Each loader is a\n * dynamic import so the viewer chunk only ships when the file type\n * is actually opened. The PreviewModal mounts the resolved component\n * via `<component :is=\"ViewerCmp\" />` once the dynamic import settles.\n */\nconst VIEWER_MAP: Record<string, () => Promise<Component>> = {\n glb: () => import('../viewers/Viewer3D.vue'),\n gltf: () => import('../viewers/Viewer3D.vue'),\n obj: () => import('../viewers/Viewer3D.vue'),\n stl: () => import('../viewers/Viewer3D.vue'),\n fbx: () => import('../viewers/Viewer3D.vue'),\n '3ds': () => import('../viewers/Viewer3D.vue'),\n\n epub: () => import('../viewers/EpubViewer.vue'),\n\n mmd: () => import('../viewers/MermaidViewer.vue'),\n mermaid: () => import('../viewers/MermaidViewer.vue'),\n\n drawio: () => import('../viewers/DrawioViewer.vue'),\n dio: () => import('../viewers/DrawioViewer.vue'),\n\n tif: () => import('../viewers/TiffViewer.vue'),\n tiff: () => import('../viewers/TiffViewer.vue'),\n\n psd: () => import('../viewers/PsdViewer.vue'),\n\n // PDF deliberately uses the native browser viewer (`kind === 'pdf'`\n // branch in the template). PdfViewer.vue still exists for callers\n // that want the rich custom UI but the SFC default keeps things\n // minimal — the browser already paints search/zoom/page UI for free.\n\n ipynb: () => import('../viewers/IpynbViewer.vue'),\n\n csv: () => import('../viewers/CsvViewer.vue'),\n tsv: () => import('../viewers/CsvViewer.vue'),\n\n zip: () => import('../viewers/ArchiveViewer.vue'),\n};\n\ntype PreviewKind =\n | 'image' | 'video' | 'audio' | 'pdf' | 'markdown' | 'code'\n | 'office' | 'text' | 'viewer' | 'other';\n\nconst kind = computed<PreviewKind>(() => {\n const e = ext(props.file);\n if (!e) return 'other';\n if (IMAGE.includes(e)) return 'image';\n if (VIDEO.includes(e)) return 'video';\n if (AUDIO.includes(e)) return 'audio';\n // PDF always uses the native browser <object> renderer. The\n // PdfViewer SFC is no longer wired into the default map — the\n // browser-bundled toolbar is enough and removes a 600 KB pdfjs\n // worker chunk + a custom toolbar layer for parity with the rest\n // of the read-only viewers.\n if (e === 'pdf') return 'pdf';\n // Markdown stays in its own branch (gets the split view in edit mode);\n // plain text → code editor in edit mode, raw <pre> in view mode.\n const wantEdit = props.openMode !== 'view';\n if (e === 'md' || e === 'markdown') return 'markdown';\n if (e in CODE_LANGS) return 'code';\n if (e in VIEWER_MAP) return 'viewer';\n if (OFFICE.includes(e)) return 'office';\n if (TEXT_PLAIN.includes(e)) return wantEdit ? 'code' : 'text';\n return 'other';\n});\n\n// --- Rich viewer plumbing ---\n//\n// `viewerCmp` holds the dynamically-imported component once the load\n// resolves. Stored in a `shallowRef` because the component itself\n// shouldn't be deep-watched.\nconst viewerCmp = shallowRef<Component | null>(null);\nconst viewerLoadError = ref<string | null>(null);\nconst pdfFallbackToNative = ref(false);\n\nasync function loadViewerFor(extension: string): Promise<void> {\n viewerCmp.value = null;\n viewerLoadError.value = null;\n const loader = VIEWER_MAP[extension];\n if (!loader) return;\n try {\n const mod = (await loader()) as { default?: Component };\n viewerCmp.value = mod.default ?? (mod as unknown as Component);\n } catch (err) {\n viewerLoadError.value = err instanceof Error ? err.message : 'viewer load failed';\n if (extension === 'pdf') pdfFallbackToNative.value = true;\n }\n}\n\nfunction onPdfFallback(): void {\n pdfFallbackToNative.value = true;\n}\n\n/** Build the props bundle pushed into the active viewer component. */\nconst viewerProps = computed(() => {\n const e = ext(props.file);\n const base: Record<string, unknown> = {\n url: src.value,\n ext: e,\n mime: props.file?.mime_type,\n t,\n authHeaders: props.authHeaders,\n authCredentials: props.authCredentials,\n };\n if (props.file) {\n base.filePath = stripAdapter(props.file.path);\n // Archive viewer needs the adapter-qualified path because the\n // /api/files/archive/list handler falls back to storages[0] when\n // no adapter prefix is present — on multi-storage instances that\n // 500s for every non-default storage (sample.zip on fm s3-test).\n if (e === 'zip' || e === 'rar' || e === '7z' || e === 'tar' || e === 'gz' || e === 'tgz') {\n base.filePath = props.file.path;\n }\n }\n if (e === 'drawio' || e === 'dio') {\n base.drawioUrl = props.drawioUrl ?? undefined;\n base.saveUrl = props.saveTextEndpoint ?? undefined;\n base.readOnly = props.openMode === 'view';\n }\n if (e === 'pdf') {\n base.pdfWorkerUrl = props.pdfWorkerUrl ?? undefined;\n base.pdfSaveUrl = props.pdfSaveUrl ?? undefined;\n }\n return base;\n});\n\nfunction openInNewTab(): void {\n buildAndOpenStandalone(props.openMode || 'edit');\n}\n\nfunction openEditInNewTab(): void {\n buildAndOpenStandalone('edit');\n}\n\nfunction buildAndOpenStandalone(mode: 'view' | 'edit'): void {\n if (!props.file) return;\n const e = ext(props.file);\n // Keep the adapter-qualified path intact so the editor route\n // resolves the storage from the URL (stripping it falls back to\n // storages[0] and 404s for any non-default adapter). Default base\n // is the SFC's standalone /files/edit route; embedders override via\n // viewerBaseUrl when they mount us elsewhere.\n const base = props.viewerBaseUrl || '/files/edit';\n const sep = base.includes('?') ? '&' : '?';\n const url =\n `${base}${sep}path=${encodeURIComponent(props.file.path)}` +\n `&type=${encodeURIComponent(e)}` +\n `&mode=${encodeURIComponent(mode)}`;\n window.open(url, '_blank', 'noopener');\n}\n\n/**\n * Extensions that have a meaningful \"edit\" surface. Read-only kinds\n * (image/video/audio/3D/archive) don't surface a \"Düzenle\" button.\n */\nconst EDITABLE_EXTS = new Set([\n // OnlyOffice — open the in-page office editor (or new tab) with\n // edit permissions.\n 'docx', 'doc', 'xlsx', 'xls', 'pptx', 'ppt',\n 'odt', 'ods', 'odp', 'rtf',\n // Drawio / mermaid round-trip via the new-tab route.\n 'drawio', 'dio', 'mmd', 'mermaid',\n // Code / text / markdown — Monaco / split editor.\n 'md', 'markdown', 'txt', 'log',\n 'json', 'jsonc', 'yaml', 'yml', 'xml', 'svg', 'html', 'htm',\n 'js', 'mjs', 'cjs', 'ts', 'tsx', 'jsx', 'vue', 'svelte',\n 'css', 'scss', 'sass', 'less',\n 'php', 'py', 'rb', 'go', 'rs', 'java', 'kt', 'swift',\n 'cpp', 'c', 'h', 'hpp', 'cs', 'dart',\n 'sh', 'bash', 'sql',\n 'toml', 'ini', 'conf', 'cfg', 'env',\n 'dockerfile', 'graphql', 'gql',\n]);\n\nconst canEditKind = computed<boolean>(() =>\n !!props.file && EDITABLE_EXTS.has(ext(props.file)),\n);\n\n// Keep adapter prefix so backend resolves the right storage — stripping\n// it defaults to storages[0] and 404s on any non-default adapter.\nconst src = computed(() => (props.file ? props.previewUrl(props.file.path) : ''));\nconst download = computed(() => (props.file ? props.downloadUrl(props.file.path) : ''));\n\nfunction stripAdapter(p: string): string {\n const idx = p.indexOf('://');\n return idx === -1 ? p : p.slice(idx + 3);\n}\n\nconst loading = ref(false);\nconst fetchError = ref<string | null>(null);\nconst rawText = ref<string>('');\nconst MAX_TEXT_BYTES = 1_000_000;\nconst tooLarge = ref(false);\n\n// Markdown split-edit state — drives the side-by-side textarea+preview\n// layout inside the `kind === 'markdown'` template when openMode='edit'.\nconst mdDirty = ref(false);\nconst mdSaving = ref(false);\nlet mdReRenderTimer: ReturnType<typeof setTimeout> | undefined;\nlet mdAutosaveTimer: ReturnType<typeof setTimeout> | undefined;\nfunction onMdInput() {\n mdDirty.value = true;\n if (mdReRenderTimer) clearTimeout(mdReRenderTimer);\n mdReRenderTimer = setTimeout(() => {\n renderMarkdown(rawText.value);\n }, 250);\n // Autosave 1.5s after last keystroke — manual Kaydet button + Ctrl+S\n // still work; saveMarkdown() guards against overlap.\n if (mdAutosaveTimer) clearTimeout(mdAutosaveTimer);\n mdAutosaveTimer = setTimeout(() => {\n void saveMarkdown();\n }, 1500);\n}\nasync function saveMarkdown() {\n if (!props.saveTextEndpoint || !props.file || mdSaving.value) return;\n mdSaving.value = true;\n fetchError.value = null;\n try {\n const headers = {\n 'Content-Type': 'application/json',\n ...(await (props.authHeaders ?? (() => ({})))()),\n };\n const res = await fetch(props.saveTextEndpoint, {\n method: 'POST',\n headers,\n credentials: props.authCredentials || 'same-origin',\n body: JSON.stringify({ path: stripAdapter(props.file.path), content: rawText.value }),\n });\n if (!res.ok) {\n throw new Error(`save failed: ${res.status} ${await res.text()}`);\n }\n mdDirty.value = false;\n } catch (err) {\n fetchError.value = err instanceof Error ? err.message : String(err);\n } finally {\n mdSaving.value = false;\n }\n}\n\nasync function fetchText(url: string): Promise<void> {\n loading.value = true;\n fetchError.value = null;\n rawText.value = '';\n tooLarge.value = false;\n try {\n const headers: Record<string, string> = {};\n if (props.authHeaders) Object.assign(headers, props.authHeaders());\n const res = await fetch(url, {\n credentials: props.authCredentials || 'include',\n headers,\n });\n if (!res.ok) {\n throw new Error(`${res.status} ${res.statusText}`);\n }\n const len = Number(res.headers.get('content-length') || '0');\n if (len > MAX_TEXT_BYTES) {\n tooLarge.value = true;\n return;\n }\n const text = await res.text();\n if (text.length > MAX_TEXT_BYTES) {\n tooLarge.value = true;\n rawText.value = text.slice(0, MAX_TEXT_BYTES);\n } else {\n rawText.value = text;\n }\n } catch (err) {\n fetchError.value = err instanceof Error ? err.message : String(err);\n } finally {\n loading.value = false;\n }\n}\n\n// --- Markdown rendering (lazy markdown-it) ---\n//\n// Beyond the base markdown render we walk the resulting DOM for two\n// enrichments:\n// - ```mermaid``` fences → swap the `<pre>` for a rendered SVG via\n// the `mermaid` peer (when installed).\n// - ```math``` / `$$ … $$` blocks → render with `katex` (peer).\n// Both enrichments degrade gracefully when the peer isn't available\n// (the original `<pre>` stays in place).\n\nconst markdownHtml = ref<string>('');\nconst markdownEl = ref<HTMLDivElement | null>(null);\n\nasync function renderMarkdown(text: string): Promise<void> {\n try {\n const mod = (await import(/* @vite-ignore */ 'markdown-it').catch(() => null)) as any;\n if (!mod) {\n markdownHtml.value = '';\n return;\n }\n const Md = (mod as { default: any }).default ?? (mod as any);\n // html: true so inline HTML in README.md / docs renders (the\n // GitHub / GitLab contract — operators expect `<img>`, tables,\n // `<details>`, etc. to work). We sanitize the output below to\n // strip scripts / event handlers before injecting via v-html.\n const md = new Md({\n html: true,\n linkify: true,\n breaks: true,\n typographer: true,\n });\n const raw = md.render(text);\n markdownHtml.value = sanitizeHtml(raw);\n // Wait for Vue to flush the v-html into the DOM before walking it.\n await new Promise<void>((r) => setTimeout(r, 0));\n await enrichMarkdown();\n } catch (err) {\n markdownHtml.value = '';\n fetchError.value = err instanceof Error ? err.message : String(err);\n }\n}\n\n/**\n * Sanitize the markdown-it output before v-html injection.\n *\n * GitHub / GitLab let README authors embed inline HTML (img, table,\n * details, kbd …) so the viewer ships with `html: true`. This filter\n * strips the executable surface: `<script>`, `<iframe>`, `<object>`,\n * `<embed>`, any `on*` event-handler attribute, and `javascript:`\n * URLs. Conservative — README content with inline handlers is\n * exceptional and silent over-removal beats silent XSS.\n *\n * No external dep — keeping the package install-free is the trade\n * we want. Integrators who need a heavier sanitizer can run their\n * own DOMPurify pass on the rendered output before showing it.\n */\nfunction sanitizeHtml(html: string): string {\n return html\n .replace(/<\\s*script\\b[^<]*(?:(?!<\\s*\\/\\s*script\\s*>)<[^<]*)*<\\s*\\/\\s*script\\s*>/gi, '')\n .replace(/<\\s*iframe\\b[\\s\\S]*?<\\s*\\/\\s*iframe\\s*>/gi, '')\n .replace(/<\\s*object\\b[\\s\\S]*?<\\s*\\/\\s*object\\s*>/gi, '')\n .replace(/<\\s*embed\\b[^>]*>/gi, '')\n .replace(/\\son\\w+\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, '')\n .replace(/(href|src|action|formaction|xlink:href)\\s*=\\s*(?:\"\\s*javascript:[^\"]*\"|'\\s*javascript:[^']*')/gi, '$1=\"#\"');\n}\n\nasync function enrichMarkdown(): Promise<void> {\n if (!markdownEl.value) return;\n const root = markdownEl.value;\n const blocks = Array.from(root.querySelectorAll('pre > code')) as HTMLElement[];\n if (blocks.length === 0) return;\n\n let mermaid: any = undefined;\n let katex: any = undefined;\n\n for (const block of blocks) {\n const cls = block.className || '';\n const isMermaid =\n /\\blanguage-mermaid\\b/.test(cls) || /\\blanguage-mmd\\b/.test(cls);\n const isMath =\n /\\blanguage-math\\b/.test(cls) ||\n /\\blanguage-latex\\b/.test(cls) ||\n /\\blanguage-tex\\b/.test(cls);\n\n if (isMermaid) {\n if (mermaid === undefined) {\n try {\n const m = await import(/* @vite-ignore */ 'mermaid');\n mermaid = m.default ?? m;\n mermaid.initialize?.({\n startOnLoad: false,\n securityLevel: 'strict',\n });\n } catch {\n mermaid = null;\n }\n }\n if (!mermaid) continue;\n try {\n const id = `filex-md-mermaid-${Math.random().toString(36).slice(2)}`;\n const { svg } = await mermaid.render(id, block.textContent || '');\n const wrap = document.createElement('div');\n wrap.className = 'fe-preview__md-mermaid';\n wrap.innerHTML = svg;\n block.parentElement?.replaceWith(wrap);\n } catch {\n /* leave fenced block */\n }\n } else if (isMath) {\n if (katex === undefined) {\n try {\n const m = await import(/* @vite-ignore */ 'katex');\n katex = m.default ?? m;\n } catch {\n katex = null;\n }\n }\n if (!katex) continue;\n try {\n const html = katex.renderToString(block.textContent || '', {\n displayMode: true,\n throwOnError: false,\n });\n const wrap = document.createElement('div');\n wrap.className = 'fe-preview__md-math';\n wrap.innerHTML = html;\n block.parentElement?.replaceWith(wrap);\n } catch {\n /* leave fenced block */\n }\n }\n }\n}\n\n// --- Code highlight (highlight.js fallback) ---\n//\n// Used as the placeholder render until Monaco resolves, AND as the\n// permanent renderer when Monaco isn't installed at all (peer missing).\n\nconst codeHtml = ref<string>('');\n\nasync function highlightCode(text: string, language: string): Promise<void> {\n try {\n const mod = (await ensureHighlight()) as any;\n if (!mod) {\n codeHtml.value = '';\n return;\n }\n const hljs = mod.default ?? mod;\n if (hljs.getLanguage(language)) {\n const result = hljs.highlight(text, { language, ignoreIllegals: true });\n codeHtml.value = result.value;\n } else {\n const result = hljs.highlightAuto(text);\n codeHtml.value = result.value;\n }\n } catch (err) {\n codeHtml.value = '';\n fetchError.value = err instanceof Error ? err.message : String(err);\n }\n}\n\n// --- Monaco editor (lazy) ---\n//\n// We attempt to instantiate Monaco when the modal opens for a code/text\n// file. If the module isn't loaded yet, the highlight.js placeholder\n// renders first, and the editor mounts in-place once Monaco resolves.\n// Save endpoint required for editing — read-only Monaco still loads if\n// the user just wants the IDE-grade syntax/colour view.\n\nconst monacoEl = ref<HTMLDivElement | null>(null);\nlet monacoEditor: any = null;\nlet codeAutosaveTimer: ReturnType<typeof setTimeout> | undefined;\nconst monacoReady = ref(false);\nconst saving = ref(false);\nconst saveOk = ref(false);\nconst saveError = ref<string | null>(null);\n\nfunction disposeMonaco(): void {\n if (monacoEditor) {\n try {\n monacoEditor.dispose();\n } catch {\n /* ignore */\n }\n monacoEditor = null;\n }\n monacoReady.value = false;\n saveOk.value = false;\n saveError.value = null;\n}\n\n/**\n * Map an extension to a Monaco language id. Anything not in the map\n * just becomes 'plaintext' — Monaco still gives line numbers + Ctrl+S.\n */\nfunction monacoLanguageFor(extension: string): string {\n const map: Record<string, string> = {\n js: 'javascript', mjs: 'javascript', cjs: 'javascript',\n ts: 'typescript', tsx: 'typescript', jsx: 'javascript',\n json: 'json', jsonc: 'json',\n css: 'css', scss: 'scss', sass: 'scss', less: 'less',\n html: 'html', htm: 'html', vue: 'html', svelte: 'html',\n xml: 'xml', svg: 'xml',\n md: 'markdown', markdown: 'markdown',\n php: 'php', py: 'python',\n yml: 'yaml', yaml: 'yaml',\n go: 'go', rs: 'rust', sql: 'sql',\n cpp: 'cpp', c: 'c', h: 'cpp', hpp: 'cpp',\n sh: 'shell', bash: 'shell',\n dockerfile: 'dockerfile',\n toml: 'ini', ini: 'ini', conf: 'ini', cfg: 'ini',\n };\n return map[extension] ?? 'plaintext';\n}\n\nasync function tryMountMonaco(text: string, extension: string): Promise<boolean> {\n const monaco = (await ensureMonaco()) as any;\n if (!monaco || !monacoEl.value) return false;\n try {\n disposeMonaco();\n const editable = !!props.saveTextEndpoint && props.openMode !== 'view';\n // Honour the explicit theme prop when set; fall back to the OS\n // preference otherwise. Without this the Monaco editor stays on\n // vs-dark on OS-dark systems even when the host admin shell is\n // light, producing a jarring light-card + dark-code combo inside\n // the in-page preview modal.\n const dark = props.theme === 'dark'\n ? true\n : props.theme === 'light'\n ? false\n : window.matchMedia?.('(prefers-color-scheme: dark)').matches;\n monacoEditor = monaco.editor.create(monacoEl.value, {\n value: text,\n language: monacoLanguageFor(extension),\n readOnly: !editable,\n theme: dark ? 'vs-dark' : 'vs',\n automaticLayout: true,\n minimap: { enabled: false },\n fontSize: 13,\n });\n if (editable) {\n monacoEditor.addCommand(\n monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,\n () => void saveCode(),\n );\n // Autosave: 1.5s after the last keystroke we POST the buffer.\n // Ctrl+S still works for the impatient — saveCode() guards against\n // overlap, so a manual save during the debounce window just wins\n // and the queued autosave becomes a no-op.\n monacoEditor.onDidChangeModelContent(() => {\n if (codeAutosaveTimer) clearTimeout(codeAutosaveTimer);\n codeAutosaveTimer = setTimeout(() => {\n void saveCode();\n }, 1500);\n });\n }\n monacoReady.value = true;\n return true;\n } catch (err) {\n fetchError.value = `Monaco mount fail: ${(err as Error).message}`;\n return false;\n }\n}\n\nasync function saveCode(): Promise<void> {\n if (!props.saveTextEndpoint || !props.file) return;\n if (props.openMode === 'view') return;\n if (saving.value) return;\n saving.value = true;\n saveOk.value = false;\n saveError.value = null;\n try {\n const text = monacoEditor ? monacoEditor.getValue() : '';\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (props.authHeaders) Object.assign(headers, props.authHeaders());\n const res = await fetch(props.saveTextEndpoint, {\n method: 'POST',\n headers,\n credentials: props.authCredentials || 'same-origin',\n body: JSON.stringify({\n path: stripAdapter(props.file.path),\n content: text,\n }),\n });\n if (!res.ok) {\n const txt = await res.text().catch(() => '');\n throw new Error(`${res.status} ${res.statusText}${txt ? ' — ' + txt.slice(0, 150) : ''}`);\n }\n saveOk.value = true;\n setTimeout(() => {\n saveOk.value = false;\n }, 2500);\n } catch (err) {\n saveError.value = (err as Error).message;\n } finally {\n saving.value = false;\n }\n}\n\n// --- Orchestration: fetch + render when modal opens ---\n\nasync function runOrchestration(open: boolean, url: string, k: string): Promise<void> {\n rawText.value = '';\n markdownHtml.value = '';\n codeHtml.value = '';\n fetchError.value = null;\n officeError.value = null;\n viewerCmp.value = null;\n viewerLoadError.value = null;\n pdfFallbackToNative.value = false;\n disposeOnlyOfficeEditor();\n disposeMonaco();\n if (!open || !url) return;\n if (k === 'viewer') {\n await loadViewerFor(ext(props.file));\n return;\n }\n if (k === 'markdown' || k === 'code' || k === 'text') {\n await fetchText(url);\n if (tooLarge.value) return;\n if (k === 'markdown') {\n await renderMarkdown(rawText.value);\n return;\n }\n // For code/text — try Monaco first when the cached module is\n // already in memory. If not, render the highlight.js placeholder\n // immediately, then attempt to upgrade to Monaco when the import\n // settles.\n const lang = CODE_LANGS[ext(props.file)] || '';\n const monacoCached = getMonaco();\n if (monacoCached) {\n await new Promise<void>((r) => setTimeout(r, 0));\n const ok = await tryMountMonaco(rawText.value, ext(props.file));\n if (!ok) await highlightCode(rawText.value, lang);\n } else {\n // Render highlight.js immediately for read-only colour. Then\n // kick off the Monaco load and swap it in once ready.\n if (k === 'code') await highlightCode(rawText.value, lang);\n ensureMonaco().then(async (m) => {\n if (!m) return;\n if (!props.open) return;\n // Wait one tick so the placeholder DOM exists before swapping.\n await new Promise<void>((r) => setTimeout(r, 0));\n await tryMountMonaco(rawText.value, ext(props.file));\n });\n }\n } else if (k === 'office') {\n await new Promise<void>((r) => setTimeout(r, 0));\n await mountOnlyOfficeEditor();\n }\n}\n\nwatch(\n () => [props.open, src.value, kind.value, props.openMode] as const,\n ([open, url, k]) => {\n void runOrchestration(open, url, k);\n },\n);\n\n// Hand-fire on mount so the standalone Editor.vue route (which mounts\n// us with `open` already true) actually runs the orchestration. The\n// watcher itself is non-immediate because `immediate: true` would fire\n// before the rest of <script setup> finishes, hitting the TDZ on\n// `officeEditor`/Monaco state below. Doing this in onMounted+nextTick\n// guarantees every `let`/`function` in the file has been hoisted.\nonMounted(() => {\n void nextTick(() => {\n if (!props.open) return;\n void runOrchestration(props.open, src.value, kind.value);\n });\n});\n\nconst codeLanguage = computed(() => CODE_LANGS[ext(props.file)] || 'plaintext');\n\n// --- OnlyOffice DocEditor (real, JWT-signed) ---\n\nconst officeEl = ref<HTMLDivElement | null>(null);\nconst officeError = ref<string | null>(null);\nlet officeEditor: any = null;\n\nasync function mountOnlyOfficeEditor(): Promise<void> {\n officeError.value = null;\n if (!props.file || kind.value !== 'office') return;\n if (!props.onlyOfficeConfigEndpoint) {\n officeError.value = 'OnlyOffice yapılandırması yok';\n return;\n }\n if (!officeEl.value) return;\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (props.authHeaders) Object.assign(headers, props.authHeaders());\n const res = await fetch(props.onlyOfficeConfigEndpoint, {\n method: 'POST',\n headers,\n credentials: props.authCredentials || 'same-origin',\n body: JSON.stringify({\n // Send the FULL adapter-qualified path. The backend resolves\n // `<adapter>://<rel>` against ListEnabledStorages; passing the\n // bare relative path falls back to storages[0] which 404s for\n // anything sitting on a non-primary storage (e.g. s3-test).\n path: props.file.path,\n mode: props.openMode || 'edit',\n }),\n });\n if (!res.ok) {\n throw new Error(`Config fetch ${res.status}: ${(await res.text()).slice(0, 200)}`);\n }\n const { config, documentServerUrl } = (await res.json()) as {\n config: any;\n documentServerUrl: string;\n };\n\n await loadOnlyOfficeScript(documentServerUrl);\n disposeOnlyOfficeEditor();\n\n const mountId = 'fe-onlyoffice-mount';\n officeEl.value.id = mountId;\n\n config.events = {\n onError: (err: any) => {\n officeError.value = formatOnlyOfficeError(err);\n },\n };\n\n const W = window as any;\n if (!W.DocsAPI || !W.DocsAPI.DocEditor) {\n throw new Error('DocsAPI not available after script load');\n }\n officeEditor = new W.DocsAPI.DocEditor(mountId, config);\n } catch (err) {\n officeError.value = err instanceof Error ? err.message : String(err);\n }\n}\n\nfunction disposeOnlyOfficeEditor(): void {\n try {\n officeEditor?.destroyEditor?.();\n } catch {\n /* ignore */\n }\n officeEditor = null;\n}\n\nonBeforeUnmount(() => {\n disposeOnlyOfficeEditor();\n disposeMonaco();\n});\n\n/**\n * OnlyOffice fires onError with an event-like object:\n * { type:'error', data:{ errorCode, errorDescription, ... } }\n * The legacy stringification produced \"[object Object]\" for objects\n * whose `data` was itself an object. Walk one level deeper so the\n * user sees the actual error description instead of a useless cast.\n */\nfunction formatOnlyOfficeError(err: unknown): string {\n if (typeof err === 'string') return err;\n const e = err as { data?: unknown; message?: unknown; errorDescription?: unknown };\n if (e?.data && typeof e.data === 'object') {\n const d = e.data as { errorDescription?: unknown; errorCode?: unknown; message?: unknown };\n if (typeof d.errorDescription === 'string') return d.errorDescription;\n if (typeof d.message === 'string') return d.message;\n if (d.errorCode !== undefined) return `OnlyOffice error ${d.errorCode}`;\n }\n if (typeof e?.data === 'string') return e.data;\n if (typeof e?.errorDescription === 'string') return e.errorDescription;\n if (typeof e?.message === 'string') return e.message;\n try {\n return JSON.stringify(err);\n } catch {\n return 'OnlyOffice error';\n }\n}\n\nconst ONLYOFFICE_SCRIPT_ID = 'fe-onlyoffice-api-js';\nfunction loadOnlyOfficeScript(base: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if ((window as any).DocsAPI?.DocEditor) {\n resolve();\n return;\n }\n const existing = document.getElementById(ONLYOFFICE_SCRIPT_ID) as HTMLScriptElement | null;\n if (existing) {\n existing.addEventListener('load', () => resolve());\n existing.addEventListener('error', () => reject(new Error('OnlyOffice api.js load failed')));\n return;\n }\n const script = document.createElement('script');\n script.id = ONLYOFFICE_SCRIPT_ID;\n script.src = `${base.replace(/\\/$/, '')}/web-apps/apps/api/documents/api.js`;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('OnlyOffice api.js load failed'));\n document.head.appendChild(script);\n });\n}\n</script>\n\n<template>\n <Modal :open=\"open\" size=\"xl\" :title=\"file?.basename || ''\" :chromeless=\"chromeless\" :theme=\"theme\" @close=\"emit('close')\">\n <div v-if=\"file\" class=\"fe-preview\">\n <template v-if=\"kind === 'image'\">\n <img :src=\"src\" :alt=\"file.basename\" class=\"fe-preview__image\" />\n </template>\n <template v-else-if=\"kind === 'video'\">\n <video :src=\"src\" controls preload=\"metadata\" class=\"fe-preview__video\" />\n </template>\n <template v-else-if=\"kind === 'audio'\">\n <audio :src=\"src\" controls class=\"fe-preview__audio\" />\n </template>\n <template v-else-if=\"kind === 'pdf'\">\n <object :data=\"src\" type=\"application/pdf\" class=\"fe-preview__iframe\">\n <div class=\"fe-preview__fallback\">\n <span class=\"fe-preview__fallback-icon\">📕</span>\n <p>Tarayıcı PDF'i inline açamadı.</p>\n <a :href=\"download\" class=\"fe-btn fe-btn--primary\" target=\"_blank\" rel=\"noopener\">PDF'i Yeni Sekmede Aç</a>\n </div>\n </object>\n </template>\n\n <template v-else-if=\"kind === 'markdown'\">\n <div v-if=\"loading\" class=\"fe-preview__fallback\">{{ t('viewer.loading') }}</div>\n <div v-else-if=\"tooLarge\" class=\"fe-preview__fallback\">\n Dosya çok büyük (>1 MB). <a :href=\"download\" class=\"fe-btn\">{{ t('viewer.download') }}</a>\n </div>\n <div\n v-else-if=\"openMode === 'edit' && saveTextEndpoint\"\n class=\"fe-preview__md-split\"\n >\n <div class=\"fe-preview__md-split-bar\">\n <span class=\"fe-preview__md-split-label\">MARKDOWN</span>\n <span v-if=\"fetchError\" class=\"fe-preview__md-split-error\">{{ fetchError }}</span>\n <button\n type=\"button\"\n class=\"fe-btn fe-btn--primary\"\n :disabled=\"!mdDirty || mdSaving\"\n @click=\"saveMarkdown\"\n >\n {{ mdSaving ? t('viewer.saving') : (mdDirty ? t('viewer.save') : t('viewer.saved')) }}\n </button>\n </div>\n <div class=\"fe-preview__md-split-body\">\n <textarea\n class=\"fe-preview__md-split-input\"\n v-model=\"rawText\"\n @input=\"onMdInput\"\n @keydown.ctrl.s.prevent=\"saveMarkdown\"\n @keydown.meta.s.prevent=\"saveMarkdown\"\n spellcheck=\"false\"\n placeholder=\"# Markdown buraya…\"\n />\n <div\n ref=\"markdownEl\"\n class=\"fe-preview__md-split-output fe-preview__md\"\n v-html=\"markdownHtml\"\n ></div>\n </div>\n </div>\n <div v-else-if=\"fetchError\" class=\"fe-preview__fallback\">\n <p>{{ fetchError }}</p>\n <a :href=\"download\" class=\"fe-btn fe-btn--primary\">{{ t('viewer.download') }}</a>\n </div>\n <div v-else-if=\"markdownHtml\" ref=\"markdownEl\" class=\"fe-preview__md\" v-html=\"markdownHtml\"></div>\n <pre v-else class=\"fe-preview__pre\">{{ rawText }}</pre>\n </template>\n\n <template v-else-if=\"kind === 'viewer'\">\n <div v-if=\"viewerLoadError && !pdfFallbackToNative\" class=\"fe-preview__fallback\">\n <span class=\"fe-preview__fallback-icon\">⚠️</span>\n <p>{{ viewerLoadError }}</p>\n <a :href=\"download\" class=\"fe-btn fe-btn--primary\">{{ t('viewer.download') }}</a>\n </div>\n <div v-else-if=\"!viewerCmp\" class=\"fe-preview__fallback\">\n <span class=\"fe-preview__fallback-icon\">⏳</span>\n <p>{{ t('viewer.loading') }}</p>\n </div>\n <component\n v-else\n :is=\"viewerCmp\"\n v-bind=\"viewerProps\"\n class=\"fe-preview__viewer\"\n @fallback=\"onPdfFallback\"\n />\n </template>\n\n <template v-else-if=\"kind === 'code' || kind === 'text'\">\n <div v-if=\"loading\" class=\"fe-preview__fallback\">{{ t('viewer.loading') }}</div>\n <div v-else-if=\"tooLarge\" class=\"fe-preview__fallback\">\n Dosya çok büyük (>1 MB). <a :href=\"download\" class=\"fe-btn\">{{ t('viewer.download') }}</a>\n </div>\n <div v-else-if=\"fetchError\" class=\"fe-preview__fallback\">\n <p>{{ fetchError }}</p>\n <a :href=\"download\" class=\"fe-btn fe-btn--primary\">{{ t('viewer.download') }}</a>\n </div>\n <div v-else class=\"fe-preview__code-wrap\">\n <div class=\"fe-preview__code-toolbar\">\n <span class=\"fe-preview__code-lang\">{{ codeLanguage }}</span>\n <span v-if=\"!monacoReady && codeHtml\" class=\"fe-preview__code-status\">\n {{ saveTextEndpoint ? t('viewer.editor_loading') : t('viewer.read_only') }}\n </span>\n <span v-if=\"saveOk\" class=\"fe-preview__code-status fe-preview__code-status--ok\">✓ {{ t('viewer.saved') }}</span>\n <span v-if=\"saveError\" class=\"fe-preview__code-status fe-preview__code-status--err\" :title=\"saveError\">✗ {{ t('viewer.save_error') }}</span>\n <span v-if=\"openMode === 'view'\" class=\"fe-preview__code-status\">{{ t('viewer.read_only') }}</span>\n <button\n v-else-if=\"saveTextEndpoint && monacoReady\"\n type=\"button\"\n class=\"fe-btn fe-btn--primary\"\n :disabled=\"saving\"\n @click=\"saveCode\"\n >{{ saving ? t('viewer.saving') : t('viewer.save') }}</button>\n </div>\n <!-- Monaco target — hidden until ready, then occupies the slot. -->\n <div ref=\"monacoEl\" class=\"fe-preview__code-editor\" :class=\"{ 'is-hidden': !monacoReady }\" />\n <!-- Highlight.js read-only fallback — visible until Monaco mounts. -->\n <pre\n v-if=\"!monacoReady && codeHtml\"\n class=\"fe-preview__pre fe-preview__code hljs\"\n ><code :class=\"`language-${codeLanguage}`\" v-html=\"codeHtml\"></code></pre>\n <pre\n v-else-if=\"!monacoReady && !codeHtml\"\n class=\"fe-preview__pre\"\n :data-lang=\"codeLanguage\"\n >{{ rawText }}</pre>\n </div>\n </template>\n\n <template v-else-if=\"kind === 'office'\">\n <div v-if=\"officeError\" class=\"fe-preview__fallback\">\n <span class=\"fe-preview__fallback-icon\">📄</span>\n <p>{{ officeError }}</p>\n <a :href=\"download\" class=\"fe-btn fe-btn--primary\">{{ t('viewer.download') }}</a>\n </div>\n <div v-else ref=\"officeEl\" class=\"fe-preview__office\" />\n </template>\n\n <template v-else>\n <div class=\"fe-preview__fallback\">\n <span class=\"fe-preview__fallback-icon\">📎</span>\n <p>{{ t('viewer.no_preview') }}</p>\n <a :href=\"download\" class=\"fe-btn fe-btn--primary\">{{ t('viewer.download') }}</a>\n </div>\n </template>\n </div>\n <template #actions>\n <button\n v-if=\"file && openMode === 'view' && canEditKind\"\n type=\"button\"\n class=\"fe-btn fe-btn--primary\"\n @click=\"openEditInNewTab\"\n >✏ {{ t('viewer.edit') }}</button>\n <button\n v-if=\"file\"\n type=\"button\"\n class=\"fe-btn\"\n @click=\"openInNewTab\"\n >↗ {{ t('viewer.open_in_new_tab') }}</button>\n <a v-if=\"file\" :href=\"download\" class=\"fe-btn\">{{ t('viewer.download') }}</a>\n <button type=\"button\" class=\"fe-btn\" @click=\"emit('close')\">{{ t('viewer.close') }}</button>\n </template>\n </Modal>\n</template>\n\n<style>\n.fe-preview__code-editor.is-hidden {\n display: none;\n}\n/* Wrapper for the dynamic viewers — they render their own toolbars\n * inside the wrapper, so we just give them the full pane height. */\n.fe-preview__viewer {\n width: 100%;\n height: 100%;\n min-height: 70vh;\n display: flex;\n flex-direction: column;\n}\n.fe-preview .fe-preview__viewer {\n align-self: stretch;\n}\n.fe-preview__md-mermaid {\n display: flex;\n justify-content: center;\n margin: 16px 0;\n}\n.fe-preview__md-mermaid svg {\n max-width: 100%;\n height: auto;\n}\n.fe-preview__md-math {\n margin: 16px 0;\n text-align: center;\n overflow-x: auto;\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * ConvertModal — universal file converter via a hidden, embedded iframe to\n * the p2r3/convert fork running at `convertUrl` (loaded with `?embed=1`).\n *\n * The iframe performs the actual conversion in-browser (WASM handlers); we\n * drive it headlessly over postMessage (protocol defined in the fork's\n * `setupEmbedBridge`):\n * 1. iframe → { source:'convert-embed', event:'ready' }\n * 2. we → { target:'convert-embed', cmd:'listFormats', id }\n * iframe→ { source, id, ok, formats:[{index,ext,format,mime,name,from,to}] }\n * 3. user searches + picks a target format\n * 4. we fetch the source bytes, → { cmd:'convert', name, bytes, fromIndex, toIndex }\n * iframe→ { ok, name, ext, bytes:ArrayBuffer }\n * 5. we wrap the bytes in a File and upload it to the current folder.\n */\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue';\n\nconst props = defineProps<{\n /** Converter base, e.g. https://fm.example.com/convert */\n convertUrl: string;\n /** Source file name with extension, e.g. \"clip.avi\" */\n fileName: string;\n /** Lazily fetch the source file bytes (api.fetchArrayBuffer bound to the path). */\n fetchBytes: () => Promise<ArrayBuffer>;\n /** Upload the produced File into the current folder (api.uploadMultipart bound to dir). */\n upload: (file: File) => Promise<void>;\n t?: (key: string, fallback: string) => string;\n}>();\n\nconst emit = defineEmits<{ (e: 'close'): void; (e: 'done', name: string): void }>();\n\ninterface Fmt {\n index: number; ext: string; format: string; mime: string;\n name: string; from: boolean; to: boolean; category: string | null;\n}\n\nconst iframeRef = ref<HTMLIFrameElement | null>(null);\nconst status = ref<'loading' | 'ready' | 'converting' | 'done' | 'error'>('loading');\nconst error = ref<string | null>(null);\nconst formats = ref<Fmt[]>([]);\nconst search = ref('');\nconst selectedTo = ref<Fmt | null>(null);\n\nconst srcExt = computed(() => (props.fileName.split('.').pop() || '').toLowerCase());\n\nconst fromFmt = computed<Fmt | null>(() => {\n const ins = formats.value.filter((f) => f.from);\n return (\n ins.find((f) => (f.ext || '').toLowerCase() === srcExt.value) ||\n ins.find((f) => (f.format || '').toLowerCase() === srcExt.value) ||\n null\n );\n});\n\nconst toList = computed<Fmt[]>(() => {\n const q = search.value.trim().toLowerCase();\n const seen = new Set<string>();\n const uniq: Fmt[] = [];\n for (const f of formats.value) {\n if (!f.to) continue;\n const key = (f.ext || f.format || '').toLowerCase();\n if (!key || seen.has(key)) continue;\n seen.add(key);\n uniq.push(f);\n }\n uniq.sort((a, b) => (a.ext || a.format).localeCompare(b.ext || b.format));\n if (!q) return uniq;\n return uniq.filter(\n (f) =>\n (f.ext || '').toLowerCase().includes(q) ||\n (f.format || '').toLowerCase().includes(q) ||\n (f.name || '').toLowerCase().includes(q) ||\n (f.mime || '').toLowerCase().includes(q),\n );\n});\n\nconst iframeSrc = computed(() => `${props.convertUrl.replace(/\\/$/, '')}/?embed=1`);\n\nlet msgId = 0;\nconst pending = new Map<number, { resolve: (v: any) => void; reject: (e: any) => void }>();\n\nfunction send(cmd: string, extra: Record<string, unknown> = {}, transfer: Transferable[] = []): Promise<any> {\n const id = ++msgId;\n return new Promise((resolve, reject) => {\n pending.set(id, { resolve, reject });\n iframeRef.value?.contentWindow?.postMessage({ target: 'convert-embed', id, cmd, ...extra }, '*', transfer);\n setTimeout(() => {\n if (pending.has(id)) { pending.delete(id); reject(new Error('convert timeout')); }\n }, 180000);\n });\n}\n\nfunction onMessage(ev: MessageEvent) {\n const d = ev.data;\n if (!d || d.source !== 'convert-embed') return;\n if (d.event === 'ready') { void loadFormats(); return; }\n const p = pending.get(d.id);\n if (!p) return;\n pending.delete(d.id);\n if (d.ok) p.resolve(d); else p.reject(new Error(d.error || 'convert error'));\n}\n\nasync function loadFormats() {\n try {\n const res = await send('listFormats');\n formats.value = res.formats || [];\n status.value = 'ready';\n if (!fromFmt.value) {\n error.value = tt('convert.unsupportedInput', 'Bu dosya tipi için kaynak format bulunamadı.');\n }\n } catch (e) {\n error.value = (e as Error).message;\n status.value = 'error';\n }\n}\n\nasync function doConvert() {\n if (!selectedTo.value || !fromFmt.value) return;\n status.value = 'converting';\n error.value = null;\n try {\n const buf = await props.fetchBytes();\n const res = await send(\n 'convert',\n { name: props.fileName, bytes: buf, fromIndex: fromFmt.value.index, toIndex: selectedTo.value.index },\n [buf],\n );\n const base = props.fileName.replace(/\\.[^.]+$/, '');\n const ext = res.ext || selectedTo.value.ext || selectedTo.value.format;\n const outName = `${base}.${ext}`;\n const file = new File([res.bytes], outName, { type: selectedTo.value.mime || 'application/octet-stream' });\n await props.upload(file);\n status.value = 'done';\n emit('done', outName);\n } catch (e) {\n error.value = (e as Error).message;\n status.value = 'error';\n }\n}\n\nfunction tt(k: string, fb: string) { return props.t ? props.t(k, fb) : fb; }\n\nonMounted(() => window.addEventListener('message', onMessage));\nonBeforeUnmount(() => window.removeEventListener('message', onMessage));\n</script>\n\n<template>\n <div class=\"filex-cv__bg\" @click.self=\"emit('close')\">\n <div class=\"filex-cv\">\n <header class=\"filex-cv__head\">\n <h3>{{ tt('convert.title', 'Dönüştür') }} — {{ fileName }}</h3>\n <button class=\"filex-cv__x\" @click=\"emit('close')\">✕</button>\n </header>\n\n <div v-if=\"status === 'loading'\" class=\"filex-cv__msg\">\n {{ tt('convert.loading', 'Dönüştürücü yükleniyor…') }}\n </div>\n\n <div v-else-if=\"status === 'done'\" class=\"filex-cv__msg filex-cv__ok\">\n <p>✓ {{ tt('convert.done', 'Dönüştürüldü ve klasöre yüklendi.') }}</p>\n <button class=\"filex-cv__convert\" @click=\"emit('close')\">{{ tt('convert.close', 'Kapat') }}</button>\n </div>\n\n <template v-else>\n <p class=\"filex-cv__src\">\n {{ tt('convert.from', 'Kaynak') }}: <b>{{ srcExt || '?' }}</b>\n </p>\n <input\n v-model=\"search\"\n class=\"filex-cv__search\"\n :placeholder=\"tt('convert.searchFmt', 'Hedef format ara (pdf, mp4, png…)')\"\n />\n <div class=\"filex-cv__list\">\n <button\n v-for=\"f in toList\"\n :key=\"f.index\"\n :class=\"['filex-cv__fmt', { 'is-sel': selectedTo?.index === f.index }]\"\n @click=\"selectedTo = f\"\n >\n <b>{{ (f.ext || f.format).toUpperCase() }}</b>\n <small>{{ f.name }}</small>\n </button>\n <div v-if=\"toList.length === 0\" class=\"filex-cv__empty\">\n {{ tt('convert.noFmt', 'Eşleşen format yok.') }}\n </div>\n </div>\n <div v-if=\"error\" class=\"filex-cv__err\">{{ error }}</div>\n <footer class=\"filex-cv__foot\">\n <button\n class=\"filex-cv__convert\"\n :disabled=\"!selectedTo || !fromFmt || status === 'converting'\"\n @click=\"doConvert\"\n >\n {{ status === 'converting' ? tt('convert.converting', 'Dönüştürülüyor…') : tt('convert.convert', 'Dönüştür') }}\n </button>\n </footer>\n </template>\n\n <!-- hidden headless converter engine -->\n <iframe ref=\"iframeRef\" :src=\"iframeSrc\" class=\"filex-cv__frame\" title=\"converter\" />\n </div>\n </div>\n</template>\n\n<style scoped>\n.filex-cv__bg {\n position: fixed; inset: 0; z-index: 1000;\n background: rgba(0, 0, 0, 0.55);\n display: flex; align-items: center; justify-content: center;\n}\n.filex-cv {\n width: min(560px, 92vw); max-height: 80vh; overflow: hidden;\n display: flex; flex-direction: column;\n background: var(--fe-bg, #fff); color: var(--fe-text, #1a1f29);\n border: 1px solid var(--fe-border, #e2e6ed); border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);\n}\n.filex-cv__head {\n display: flex; align-items: center; justify-content: space-between;\n padding: 12px 16px; border-bottom: 1px solid var(--fe-border, #e2e6ed);\n}\n.filex-cv__head h3 { margin: 0; font-size: 14px; font-weight: 600; }\n.filex-cv__x { border: 0; background: none; cursor: pointer; font-size: 16px; color: var(--fe-text-muted, #5a6475); }\n.filex-cv__msg { padding: 28px; text-align: center; color: var(--fe-text-muted, #5a6475); }\n.filex-cv__ok { color: #059669; }\n.filex-cv__src { padding: 12px 16px 0; font-size: 13px; color: var(--fe-text-muted, #5a6475); }\n.filex-cv__search {\n margin: 8px 16px; padding: 8px 10px;\n border: 1px solid var(--fe-border, #e2e6ed); border-radius: 8px;\n background: var(--fe-bg-elev, #f7f8fa); color: inherit; font-size: 13px;\n}\n.filex-cv__list {\n flex: 1; overflow-y: auto; padding: 4px 12px 12px;\n display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px;\n}\n.filex-cv__fmt {\n display: flex; flex-direction: column; gap: 2px; align-items: flex-start;\n padding: 8px 10px; cursor: pointer; text-align: left;\n border: 1px solid var(--fe-border, #e2e6ed); border-radius: 8px;\n background: var(--fe-bg-elev, #f7f8fa); color: inherit;\n}\n.filex-cv__fmt small { color: var(--fe-text-muted, #5a6475); font-size: 11px; }\n.filex-cv__fmt.is-sel { border-color: #44c878; background: rgba(68, 200, 120, 0.12); }\n.filex-cv__empty { grid-column: 1 / -1; text-align: center; color: var(--fe-text-muted, #5a6475); padding: 16px; }\n.filex-cv__err { padding: 0 16px; color: var(--fe-danger, #dc2626); font-size: 13px; }\n.filex-cv__foot { padding: 12px 16px; border-top: 1px solid var(--fe-border, #e2e6ed); text-align: right; }\n.filex-cv__convert {\n padding: 8px 18px; border: 0; border-radius: 8px; cursor: pointer;\n background: #44c878; color: #03200f; font-weight: 600; font-size: 13px;\n}\n.filex-cv__convert:disabled { opacity: 0.5; cursor: default; }\n.filex-cv__frame { position: absolute; width: 0; height: 0; border: 0; left: -9999px; }\n</style>\n","<script setup lang=\"ts\">\n// Access modal — one popup combining \"İzinler\" (per-user RBAC grants,\n// owner-only) and \"Bağlantı ile paylaş\" (public share link, editor+). Opened\n// from the explorer's unified \"Paylaş / İzinler\" action. The layout is a fixed\n// header/tabs with a single scrollable body so the popup never grows into one\n// long scroll. Styling uses the SFC's --fe-* theme variables (light/dark).\nimport { ref, onMounted, onBeforeUnmount, computed } from 'vue';\nimport type { FileApi, Grant, UserSuggestion } from '../composables/useFileApi';\nimport type { ShareInfo } from '../types/FileNode';\n\nconst props = defineProps<{\n api: FileApi;\n path: string; // adapter://rel of the target item\n isDir?: boolean; // folder → grants cascade; file → no `/…` inheritance hint\n size?: number; // bytes, for the share-mail body (files only)\n locale?: 'tr' | 'en';\n}>();\nconst emit = defineEmits<{ (e: 'close'): void }>();\n\nconst tr = computed(() => (props.locale ?? 'tr') !== 'en');\nfunction L(t: string, e: string): string {\n return tr.value ? t : e;\n}\n\n// Split adapter://rel for a friendlier path chip.\nconst pathParts = computed(() => {\n const m = /^([^:]+):\\/\\/(.*)$/.exec(props.path);\n const adapter = m ? m[1] : '';\n const rel = m ? m[2] : props.path;\n const segs = rel.split('/').filter(Boolean);\n return { adapter, name: segs.length ? segs[segs.length - 1] : adapter, rel };\n});\n\ntype Tab = 'perms' | 'share' | 'drop';\nconst tab = ref<Tab>('perms');\nconst canManage = ref(false); // owner/admin → can see the permissions tab\n\n// ── permissions state ──\nconst loading = ref(true);\nconst err = ref('');\nconst direct = ref<Grant[]>([]);\nconst inherited = ref<Grant[]>([]);\nconst storageRbac = ref(true);\nconst email = ref('');\nconst level = ref<'viewer' | 'editor' | 'owner'>('viewer');\nconst busy = ref(false);\nconst notice = ref('');\nconst noAccount = ref(false);\nconst createRole = ref<'user' | 'viewer'>('user');\nconst inviteResult = ref<{ tempPassword?: string } | null>(null);\nconst suggestions = ref<UserSuggestion[]>([]);\nconst showSuggest = ref(false);\nlet searchTimer: ReturnType<typeof setTimeout> | undefined;\n\nconst levels: Array<{ v: 'viewer' | 'editor' | 'owner'; l: string; d: string }> = [\n { v: 'viewer', l: L('Görüntüleyen', 'Viewer'), d: L('görüntüle + indir', 'view + download') },\n { v: 'editor', l: L('Düzenleyen', 'Editor'), d: L('oku + yaz + sil', 'read + write + delete') },\n { v: 'owner', l: L('Sahip', 'Owner'), d: L('düzenle + izin yönet', 'edit + manage access') },\n];\nfunction levelLabel(v: string): string {\n return levels.find((o) => o.v === v)?.l ?? v;\n}\n\n// ── share state ──\nconst shares = ref<ShareInfo[]>([]);\nconst shareBusy = ref(false);\nconst sharePwd = ref(false);\nconst shareExpiry = ref(0); // days; 0 = never\nconst shareResult = ref<{ url: string; pin?: string | null } | null>(null);\nconst shareErr = ref('');\nconst copied = ref('');\n// prefilled recipient when the owner chose \"share link\" for a no-account email\nconst shareMailTo = ref('');\nconst shareMailBusy = ref(false);\nconst shareMailNotice = ref('');\n\nconst expiryOptions = [\n { v: 0, l: L('Süresiz', 'Never') },\n { v: 1, l: L('1 gün', '1 day') },\n { v: 7, l: L('7 gün', '7 days') },\n { v: 30, l: L('30 gün', '30 days') },\n];\n\n// ── file-drop (public upload link) state ──\nconst dropPwd = ref(false);\nconst dropExpiry = ref(0); // days; 0 = never\nconst dropShowAdv = ref(false);\nconst dropMaxFiles = ref<string>('');\nconst dropMaxSizeMB = ref<string>('');\nconst dropAllowedExt = ref<string>('');\nconst dropAskName = ref(true);\nconst dropBusy = ref(false);\nconst dropErr = ref('');\nconst dropResult = ref<{ url: string; pin?: string | null } | null>(null);\nconst dropMailTo = ref('');\nconst dropMailBusy = ref(false);\nconst dropMailNotice = ref('');\n\n// splitEmails turns a free-text recipient field into a deduped address list —\n// comma / semicolon / whitespace separated, so one input handles many people.\nfunction splitEmails(raw: string): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const part of raw.split(/[,;\\s]+/)) {\n const e = part.trim().toLowerCase();\n if (e && e.includes('@') && !seen.has(e)) {\n seen.add(e);\n out.push(e);\n }\n }\n return out;\n}\n\n// mailResultNotice renders a sent/failed summary from the share-mail response.\nfunction mailResultNotice(res: { sent?: string[]; failed?: string[] }): string {\n const sent = res.sent?.length ?? 0;\n const failed = res.failed?.length ?? 0;\n if (failed === 0) return L(`E-posta gönderildi ✓ (${sent})`, `Email sent ✓ (${sent})`);\n return L(`${sent} gönderildi, ${failed} başarısız`, `${sent} sent, ${failed} failed`);\n}\n\nasync function reload() {\n loading.value = true;\n err.value = '';\n try {\n const r = await props.api.listPermissions(props.path);\n direct.value = r.direct ?? [];\n inherited.value = r.inherited ?? [];\n storageRbac.value = r.storage_rbac;\n canManage.value = true;\n } catch (e) {\n // 403 = caller is editor (not owner): no permissions tab, share only.\n const st = (e as { status?: number }).status;\n if (st === 403) {\n canManage.value = false;\n // Editor (not owner): no permissions tab → fall back to the link tab.\n tab.value = 'share';\n } else {\n err.value = e instanceof Error ? e.message : String(e);\n }\n } finally {\n loading.value = false;\n }\n}\nasync function reloadShares() {\n try {\n const r = await props.api.listShares(props.path);\n shares.value = r.shares ?? [];\n } catch {\n shares.value = [];\n }\n}\nonMounted(async () => {\n await reload();\n await reloadShares();\n});\nonBeforeUnmount(() => {\n if (searchTimer) clearTimeout(searchTimer);\n});\n\nfunction onEmailInput() {\n noAccount.value = false;\n inviteResult.value = null;\n notice.value = '';\n const q = email.value.trim();\n if (searchTimer) clearTimeout(searchTimer);\n if (q.length < 1) {\n suggestions.value = [];\n showSuggest.value = false;\n return;\n }\n searchTimer = setTimeout(async () => {\n try {\n const r = await props.api.searchUsers(q);\n suggestions.value = r.users ?? [];\n showSuggest.value = suggestions.value.length > 0;\n } catch {\n showSuggest.value = false;\n }\n }, 180);\n}\nasync function pickUser(u: UserSuggestion) {\n showSuggest.value = false;\n email.value = u.email;\n let lvl = level.value;\n if (u.role === 'viewer' && lvl !== 'viewer') lvl = 'viewer';\n busy.value = true;\n notice.value = '';\n try {\n await props.api.addPermission({ path: props.path, user_id: u.id, level: lvl, is_dir: !!props.isDir });\n email.value = '';\n suggestions.value = [];\n await reload();\n notice.value = L('Yetki verildi.', 'Access granted.');\n } catch (e) {\n notice.value = e instanceof Error ? e.message : String(e);\n } finally {\n busy.value = false;\n }\n}\nasync function submitEmail() {\n const addr = email.value.trim().toLowerCase();\n if (!addr || !addr.includes('@')) {\n notice.value = L('Geçerli bir e-posta girin.', 'Enter a valid email.');\n return;\n }\n showSuggest.value = false;\n busy.value = true;\n notice.value = '';\n inviteResult.value = null;\n try {\n const res = await props.api.resolveEmail(addr);\n if (res.found && res.user) {\n let lvl = level.value;\n if (res.user.role === 'viewer' && lvl !== 'viewer') lvl = 'viewer';\n await props.api.addPermission({ path: props.path, user_id: res.user.id, level: lvl, is_dir: !!props.isDir });\n email.value = '';\n await reload();\n notice.value = L('Yetki verildi.', 'Access granted.');\n } else {\n noAccount.value = true;\n }\n } catch (e) {\n notice.value = e instanceof Error ? e.message : String(e);\n } finally {\n busy.value = false;\n }\n}\nasync function inviteCreateUser() {\n busy.value = true;\n notice.value = '';\n try {\n const r = await props.api.invitePermission({\n path: props.path, email: email.value.trim().toLowerCase(),\n level: level.value, create_user: true, role: createRole.value, is_dir: !!props.isDir,\n locale: props.locale ?? 'tr',\n });\n inviteResult.value = { tempPassword: r.temp_password };\n notice.value = r.emailed\n ? L('Kullanıcı açıldı, davet e-postası gönderildi.', 'User created, invite emailed.')\n : L('Kullanıcı açıldı. Geçici parolayı iletin.', 'User created. Share the temp password.');\n noAccount.value = false; email.value = '';\n await reload();\n } catch (e) {\n notice.value = e instanceof Error ? e.message : String(e);\n } finally {\n busy.value = false;\n }\n}\n// \"Sadece paylaş\" → jump to the share tab with the address prefilled so the\n// owner creates a link (with their chosen expiry/PIN) and mails it there.\nfunction gotoShareWithMail() {\n shareMailTo.value = email.value.trim().toLowerCase();\n noAccount.value = false;\n notice.value = '';\n tab.value = 'share';\n}\nasync function changeLevel(g: Grant, newLevel: string) {\n if (newLevel === g.level) return;\n busy.value = true;\n try { await props.api.updatePermission(g.id, newLevel); await reload(); }\n catch (e) { notice.value = e instanceof Error ? e.message : String(e); }\n finally { busy.value = false; }\n}\nasync function removeGrant(g: Grant) {\n busy.value = true;\n try { await props.api.deletePermission(g.id); await reload(); }\n catch (e) { notice.value = e instanceof Error ? e.message : String(e); }\n finally { busy.value = false; }\n}\nfunction glabel(g: Grant): string {\n return g.user_display_name || g.user_email || `#${g.user_id}`;\n}\nfunction ginitial(g: Grant): string {\n return (g.user_display_name || g.user_email || '?').charAt(0).toUpperCase();\n}\n\n// ── share actions ──\nfunction expiresAtISO(): string | null {\n if (!shareExpiry.value) return null;\n return new Date(Date.now() + shareExpiry.value * 86400000).toISOString();\n}\nasync function createLink() {\n shareBusy.value = true;\n shareErr.value = '';\n shareResult.value = null;\n shareMailNotice.value = '';\n try {\n const r = await props.api.createShare({\n path: props.path,\n password: sharePwd.value,\n expires_at: expiresAtISO(),\n });\n shareResult.value = { url: r.share.url, pin: r.share.password_pin ?? null };\n await reloadShares();\n } catch (e) {\n shareErr.value = e instanceof Error ? e.message : String(e);\n } finally {\n shareBusy.value = false;\n }\n}\nasync function sendShareMail() {\n const list = splitEmails(shareMailTo.value);\n if (!list.length) {\n shareMailNotice.value = L('Geçerli bir e-posta girin.', 'Enter a valid email.');\n return;\n }\n if (!shareResult.value?.url) return;\n shareMailBusy.value = true;\n shareMailNotice.value = '';\n try {\n const res = await props.api.shareMail({\n path: props.path, emails: list, url: shareResult.value.url,\n pin: shareResult.value.pin ?? undefined,\n expires_days: shareExpiry.value || undefined,\n locale: props.locale ?? 'tr',\n is_dir: !!props.isDir,\n size: props.size,\n });\n shareMailNotice.value = mailResultNotice(res);\n } catch (e) {\n const detail = (e as { detail?: string }).detail ?? '';\n if (detail.includes('not_configured')) {\n shareMailNotice.value = L('SMTP ayarlı/doğrulanmış değil — linki elle iletin.', 'SMTP not set up/verified — share the link manually.');\n } else if (detail.includes('send_failed')) {\n shareMailNotice.value = L('Gönderilemedi (geçici hata) — tekrar deneyin.', 'Send failed (temporary) — please retry.');\n } else {\n shareMailNotice.value = e instanceof Error ? e.message : String(e);\n }\n } finally {\n shareMailBusy.value = false;\n }\n}\n\n// ── file-drop (upload link) actions ──\nfunction dropExpiresAtISO(): string | null {\n if (!dropExpiry.value) return null;\n return new Date(Date.now() + dropExpiry.value * 86400000).toISOString();\n}\nasync function createDropLink() {\n dropBusy.value = true;\n dropErr.value = '';\n dropResult.value = null;\n dropMailNotice.value = '';\n try {\n const drop_settings: Record<string, unknown> = { ask_name: dropAskName.value };\n if (dropMaxFiles.value) drop_settings.max_files = Number(dropMaxFiles.value);\n if (dropMaxSizeMB.value) drop_settings.max_file_size_mb = Number(dropMaxSizeMB.value);\n const exts = dropAllowedExt.value.split(/[,\\s]+/).map((s) => s.trim().replace(/^\\./, '')).filter(Boolean);\n if (exts.length) drop_settings.allowed_ext = exts;\n const r = await props.api.createShare({\n path: props.path,\n kind: 'drop',\n password: dropPwd.value,\n expires_at: dropExpiresAtISO(),\n drop_settings,\n });\n dropResult.value = { url: r.share.url, pin: r.share.password_pin ?? null };\n } catch (e) {\n dropErr.value = e instanceof Error ? e.message : String(e);\n } finally {\n dropBusy.value = false;\n }\n}\nasync function sendDropMail() {\n const list = splitEmails(dropMailTo.value);\n if (!list.length) {\n dropMailNotice.value = L('Geçerli bir e-posta girin.', 'Enter a valid email.');\n return;\n }\n if (!dropResult.value?.url) return;\n dropMailBusy.value = true;\n dropMailNotice.value = '';\n try {\n const res = await props.api.shareMail({\n path: props.path, emails: list, url: dropResult.value.url,\n pin: dropResult.value.pin ?? undefined,\n expires_days: dropExpiry.value || undefined,\n locale: props.locale ?? 'tr',\n is_dir: true,\n mode: 'drop',\n });\n dropMailNotice.value = mailResultNotice(res);\n } catch (e) {\n const detail = (e as { detail?: string }).detail ?? '';\n if (detail.includes('not_configured')) {\n dropMailNotice.value = L('SMTP ayarlı/doğrulanmış değil — linki elle iletin.', 'SMTP not set up/verified — share the link manually.');\n } else {\n dropMailNotice.value = e instanceof Error ? e.message : String(e);\n }\n } finally {\n dropMailBusy.value = false;\n }\n}\nasync function revoke(s: ShareInfo) {\n shareBusy.value = true;\n try { await props.api.revokeShare(s.uuid); await reloadShares(); }\n catch (e) { shareErr.value = e instanceof Error ? e.message : String(e); }\n finally { shareBusy.value = false; }\n}\nfunction copy(text: string, tag = 'url') {\n navigator.clipboard?.writeText(text);\n copied.value = tag;\n setTimeout(() => { if (copied.value === tag) copied.value = ''; }, 1400);\n}\n\n// ── native share (Web Share API) ──\n// Same OS share sheet the fishapp uses (Windows share / Android share). Only\n// shown when the browser supports it (secure context + navigator.share, e.g.\n// Chrome/Edge on Windows, Android). The shared text mirrors the invite email\n// body (see backend mail_templates.go) so a WhatsApp/mail forward reads the\n// same as an emailed link.\nconst canShare = computed(() => typeof navigator !== 'undefined' && typeof navigator.share === 'function');\n\n// humanSize mirrors the Go humanSize() used in the email body (1.4 MB).\nfunction humanSize(b?: number): string {\n if (!b || b <= 0) return '';\n const unit = 1024;\n if (b < unit) return `${b} B`;\n const units = ['K', 'M', 'G', 'T', 'P', 'E'];\n let div = unit, exp = 0;\n for (let n = b / unit; n >= unit; n /= unit) { div *= unit; exp++; }\n return `${(b / div).toFixed(1)} ${units[exp]}B`;\n}\n\nfunction expiryLine(days: number): string {\n if (days > 0) return L(`Bu bağlantı ${days} gün geçerlidir.`, `This link is valid for ${days} day(s).`);\n return L('Bu bağlantının süresi yoktur.', 'This link does not expire.');\n}\n\n// Text + title for a download-share link, mirroring shareMailText().\nfunction shareBody(): { title: string; text: string } {\n const name = pathParts.value.name;\n const url = shareResult.value?.url ?? '';\n const pin = shareResult.value?.pin ?? '';\n const kind = props.isDir ? L('klasör', 'folder') : L('dosya', 'file');\n const title = tr.value\n ? `${name} ${props.isDir ? 'klasörü' : 'dosyası'} sizinle paylaşıldı`\n : `${name} has been shared with you`;\n const lines: string[] = [];\n lines.push(L('Merhaba,', 'Hello,'), '');\n lines.push(L(`Sizinle bir ${kind} paylaşıldı:`, `A ${kind} has been shared with you:`), '');\n if (props.isDir) {\n lines.push(L(`Klasör: ${name}`, `Folder: ${name}`));\n } else {\n lines.push(L(`Dosya: ${name}`, `File: ${name}`));\n const sz = humanSize(props.size);\n if (sz) lines.push(L(`Boyut: ${sz}`, `Size: ${sz}`));\n }\n lines.push('', L('İndirmek için:', 'Download it here:'), url);\n if (pin) lines.push('', L(`PIN (erişim kodu): ${pin}`, `PIN (access code): ${pin}`));\n lines.push('', expiryLine(shareExpiry.value));\n return { title, text: lines.join('\\n') };\n}\n\n// Text + title for a file-drop (upload) link, mirroring dropInviteMailText().\nfunction dropBody(): { title: string; text: string } {\n const folder = pathParts.value.name;\n const url = dropResult.value?.url ?? '';\n const pin = dropResult.value?.pin ?? '';\n const maxFiles = Number(dropMaxFiles.value) || 20;\n const maxMB = Number(dropMaxSizeMB.value) || 500;\n const exts = dropAllowedExt.value.split(/[,\\s]+/).map((s) => s.trim().replace(/^\\./, '')).filter(Boolean);\n const title = L(`${folder} adlı klasöre dosya eklemeniz istendi`, `You've been asked to add files to ${folder}`);\n const lines: string[] = [];\n lines.push(L('Merhaba,', 'Hello,'), '');\n lines.push(L('Dosya yüklemeniz istendi.', \"You've been invited to upload files.\"), '');\n lines.push(L(`Klasör: ${folder}`, `Folder: ${folder}`));\n lines.push(L(`Sınır: en fazla ${maxFiles} dosya, dosya başına ${maxMB} MB.`, `Limit: up to ${maxFiles} file(s), ${maxMB} MB per file.`));\n lines.push(exts.length\n ? L(`İzinli türler: ${exts.join(', ')}`, `Allowed types: ${exts.join(', ')}`)\n : L('İzinli türler: tüm türler', 'Allowed types: all'));\n lines.push('', L('Dosyalarınızı buradan yükleyebilirsiniz:', 'Upload your files here:'), url);\n if (pin) lines.push('', L(`PIN (erişim kodu): ${pin}`, `PIN (access code): ${pin}`));\n lines.push('', expiryLine(dropExpiry.value));\n return { title, text: lines.join('\\n') };\n}\n\nasync function nativeShare(body: { title: string; text: string }) {\n if (!canShare.value) return;\n try {\n await navigator.share(body);\n } catch {\n // user cancelled (AbortError) or the target rejected — nothing to do.\n }\n}\n</script>\n\n<template>\n <div class=\"fx-perm-overlay\" @click.self=\"emit('close')\">\n <div class=\"fx-perm-modal\">\n <header class=\"fx-perm-head\">\n <div class=\"fx-perm-title\">\n <span class=\"fx-perm-ico\" aria-hidden=\"true\">{{ isDir ? '📁' : '📄' }}</span>\n <div class=\"fx-perm-titletext\">\n <h3>{{ L('Paylaş / İzinler', 'Share / Permissions') }}</h3>\n <span class=\"fx-perm-sub\" :title=\"path\">{{ pathParts.name }}<span class=\"fx-perm-subdim\"> · {{ pathParts.adapter }}</span></span>\n </div>\n </div>\n <button class=\"fx-perm-x\" @click=\"emit('close')\" aria-label=\"close\">✕</button>\n </header>\n\n <div class=\"fx-perm-tabs\">\n <button\n v-if=\"canManage\"\n class=\"fx-perm-tab\"\n :class=\"{ 'is-active': tab === 'perms' }\"\n @click=\"tab = 'perms'\"\n >{{ L('Kişiler', 'People') }}</button>\n <button\n class=\"fx-perm-tab\"\n :class=\"{ 'is-active': tab === 'share' }\"\n @click=\"tab = 'share'\"\n >{{ L('Bağlantı', 'Link') }}</button>\n <button\n v-if=\"isDir\"\n class=\"fx-perm-tab\"\n :class=\"{ 'is-active': tab === 'drop' }\"\n @click=\"tab = 'drop'\"\n >{{ L('Dosya İste', 'Request files') }}</button>\n </div>\n\n <div class=\"fx-perm-body\">\n <!-- ───────── Permissions tab ───────── -->\n <template v-if=\"tab === 'perms' && canManage\">\n <div v-if=\"!storageRbac\" class=\"fx-perm-warn\">\n {{ L('Bu diskte RBAC kapalı — izinler yalnızca RBAC açık disklerde geçerli.', 'RBAC is off on this storage — grants only apply when RBAC is enabled.') }}\n </div>\n <div v-if=\"err\" class=\"fx-perm-warn\">{{ err }}</div>\n <div v-if=\"loading\" class=\"fx-perm-muted\">{{ L('Yükleniyor…', 'Loading…') }}</div>\n <template v-else>\n <!-- Add person (primary action, on top) -->\n <div class=\"fx-perm-addcard\">\n <div class=\"fx-perm-add\">\n <div class=\"fx-perm-emailwrap\">\n <input v-model=\"email\" type=\"email\" class=\"fx-perm-input\" autocomplete=\"off\"\n :placeholder=\"L('İsim veya e-posta', 'Name or email')\"\n @input=\"onEmailInput\" @keyup.enter=\"submitEmail\" @focus=\"onEmailInput\" />\n <ul v-if=\"showSuggest\" class=\"fx-perm-suggest\">\n <li v-for=\"u in suggestions\" :key=\"u.id\" @mousedown.prevent=\"pickUser(u)\">\n <span class=\"fx-perm-suggest-av\">{{ (u.display_name || u.email).charAt(0).toUpperCase() }}</span>\n <span class=\"fx-perm-suggest-txt\">\n <span class=\"fx-perm-suggest-name\">{{ u.display_name || u.email }}</span>\n <span class=\"fx-perm-suggest-meta\">{{ u.email }} · {{ u.role }}</span>\n </span>\n </li>\n </ul>\n </div>\n <select v-model=\"level\" class=\"fx-perm-sel\" :title=\"levels.find(o => o.v === level)?.d\">\n <option v-for=\"o in levels\" :key=\"o.v\" :value=\"o.v\">{{ o.l }}</option>\n </select>\n <button class=\"fx-perm-btn fx-perm-btn--primary\" :disabled=\"busy\" @click=\"submitEmail\">\n {{ L('Ekle', 'Add') }}\n </button>\n </div>\n\n <div v-if=\"noAccount\" class=\"fx-perm-invite\">\n <p class=\"fx-perm-muted\">{{ L('Bu e-postada hesap yok. Ne yapmak istersiniz?', 'No account for this email — what next?') }}</p>\n <div class=\"fx-perm-invite-actions\">\n <div class=\"fx-perm-invite-row\">\n <select v-model=\"createRole\" class=\"fx-perm-sel\">\n <option value=\"user\">{{ L('Kullanıcı', 'User') }}</option>\n <option value=\"viewer\">{{ L('Görüntüleyen', 'Viewer') }}</option>\n </select>\n <button class=\"fx-perm-btn fx-perm-btn--primary\" :disabled=\"busy\" @click=\"inviteCreateUser\">\n {{ L('Kullanıcı oluştur + yetki ver', 'Create user + grant') }}\n </button>\n </div>\n <button class=\"fx-perm-btn fx-perm-btn--ghost\" :disabled=\"busy\" @click=\"gotoShareWithMail\">\n {{ L('Sadece paylaşım linki gönder →', 'Just send a share link →') }}\n </button>\n </div>\n </div>\n <div v-if=\"notice\" class=\"fx-perm-notice\">{{ notice }}</div>\n <div v-if=\"inviteResult?.tempPassword\" class=\"fx-perm-reveal\">\n {{ L('Geçici parola:', 'Temp password:') }} <code>{{ inviteResult.tempPassword }}</code>\n </div>\n </div>\n\n <!-- People with access -->\n <div class=\"fx-perm-section\">\n <h4>{{ L('Erişimi olanlar', 'People with access') }}</h4>\n <div v-if=\"!direct.length && !inherited.length\" class=\"fx-perm-empty\">\n {{ L('Henüz kimseyle paylaşılmadı.', 'Not shared with anyone yet.') }}\n </div>\n <div v-for=\"g in direct\" :key=\"'d' + g.id\" class=\"fx-perm-person\">\n <span class=\"fx-perm-av\">{{ ginitial(g) }}</span>\n <span class=\"fx-perm-user\" :title=\"g.user_email\">{{ glabel(g) }}</span>\n <select class=\"fx-perm-sel fx-perm-sel--sm\" :value=\"g.level\"\n @change=\"changeLevel(g, ($event.target as HTMLSelectElement).value)\">\n <option v-for=\"o in levels\" :key=\"o.v\" :value=\"o.v\">{{ o.l }}</option>\n </select>\n <button class=\"fx-perm-del\" :disabled=\"busy\" :title=\"L('Kaldır', 'Remove')\" @click=\"removeGrant(g)\">✕</button>\n </div>\n <div v-for=\"g in inherited\" :key=\"'i' + g.id\" class=\"fx-perm-person fx-perm-inh\">\n <span class=\"fx-perm-av fx-perm-av--dim\">{{ ginitial(g) }}</span>\n <span class=\"fx-perm-user\" :title=\"g.user_email\">{{ glabel(g) }}</span>\n <span class=\"fx-perm-badge\">{{ levelLabel(g.level) }}</span>\n <span class=\"fx-perm-from\" :title=\"L('Üst klasörden gelir', 'Inherited from') + ': ' + (g.path_prefix || '/')\">\n ↳ {{ g.path_prefix || '/' }}\n </span>\n </div>\n </div>\n </template>\n </template>\n\n <!-- ───────── Share tab ───────── -->\n <template v-if=\"tab === 'share'\">\n <div class=\"fx-perm-addcard\">\n <div class=\"fx-perm-share-opts\">\n <label class=\"fx-perm-check\">\n <input type=\"checkbox\" v-model=\"sharePwd\" />\n {{ L('PIN ile koru', 'Protect with a PIN') }}\n </label>\n <label class=\"fx-perm-expiry\">\n <span class=\"fx-perm-muted\">{{ L('Süre', 'Expiry') }}</span>\n <select v-model.number=\"shareExpiry\" class=\"fx-perm-sel fx-perm-sel--sm\">\n <option v-for=\"o in expiryOptions\" :key=\"o.v\" :value=\"o.v\">{{ o.l }}</option>\n </select>\n </label>\n <button class=\"fx-perm-btn fx-perm-btn--primary\" :disabled=\"shareBusy\" @click=\"createLink\">\n {{ L('Bağlantı oluştur', 'Create link') }}\n </button>\n </div>\n\n <div v-if=\"shareErr\" class=\"fx-perm-warn\">{{ shareErr }}</div>\n\n <div v-if=\"shareResult\" class=\"fx-perm-result\">\n <div class=\"fx-perm-linkrow\">\n <a :href=\"shareResult.url\" target=\"_blank\" rel=\"noopener\" class=\"fx-perm-link\">{{ shareResult.url }}</a>\n <button class=\"fx-perm-btn fx-perm-btn--sm\" @click=\"copy(shareResult.url, 'new')\">\n {{ copied === 'new' ? L('Kopyalandı ✓', 'Copied ✓') : L('Kopyala', 'Copy') }}\n </button>\n </div>\n <div v-if=\"shareResult.pin\" class=\"fx-perm-pin\">\n <span>PIN: <code>{{ shareResult.pin }}</code></span>\n <button class=\"fx-perm-btn fx-perm-btn--sm\" @click=\"copy(shareResult.pin, 'sharepin')\">\n {{ copied === 'sharepin' ? L('Kopyalandı ✓', 'Copied ✓') : L('Kopyala', 'Copy') }}\n </button>\n </div>\n\n <!-- send by email (one or more, comma/space separated) -->\n <div class=\"fx-perm-mailrow\">\n <input v-model=\"shareMailTo\" type=\"text\" class=\"fx-perm-input\" autocomplete=\"off\"\n :placeholder=\"L('e-posta(lar) — virgülle ayırın', 'email(s) — comma separated')\" @keyup.enter=\"sendShareMail\" />\n <button class=\"fx-perm-btn\" :disabled=\"shareMailBusy\" @click=\"sendShareMail\">\n {{ L('Gönder', 'Send') }}\n </button>\n </div>\n <div v-if=\"shareMailNotice\" class=\"fx-perm-notice\">{{ shareMailNotice }}</div>\n\n <!-- native share (OS share sheet) — same as the fishapp Paylaş button -->\n <button v-if=\"canShare\" type=\"button\" class=\"fx-perm-btn fx-perm-btn--ghost fx-perm-sharebtn\" @click=\"nativeShare(shareBody())\">\n <span aria-hidden=\"true\">📤</span> {{ L('Paylaş', 'Share') }}\n </button>\n </div>\n <p v-else-if=\"shareMailTo\" class=\"fx-perm-hint\">\n {{ L('Aşağıdan bir bağlantı oluşturun, ardından', 'Create a link below, then it will be sent to') }}\n <strong>{{ shareMailTo }}</strong> {{ L('adresine gönderin.', '.') }}\n </p>\n </div>\n\n <div class=\"fx-perm-section\">\n <h4>{{ L('Mevcut bağlantılar', 'Existing links') }}</h4>\n <div v-if=\"!shares.length\" class=\"fx-perm-empty\">{{ L('Yok', 'None') }}</div>\n <div v-for=\"s in shares\" :key=\"s.uuid\" class=\"fx-perm-person\">\n <span class=\"fx-perm-user fx-perm-link\" :title=\"s.url\">{{ s.url }}</span>\n <button class=\"fx-perm-btn fx-perm-btn--sm\" @click=\"copy(s.url, s.uuid)\">\n {{ copied === s.uuid ? L('✓', '✓') : L('Kopyala', 'Copy') }}\n </button>\n <button class=\"fx-perm-del\" :disabled=\"shareBusy\" :title=\"L('İptal', 'Revoke')\" @click=\"revoke(s)\">✕</button>\n </div>\n </div>\n </template>\n\n <!-- ───────── File-drop (upload link) tab ───────── -->\n <template v-if=\"tab === 'drop'\">\n <div class=\"fx-perm-addcard\">\n <p class=\"fx-perm-muted fx-perm-dropintro\">\n {{ L('Bu klasöre herkesin dosya YÜKLEYEBİLECEĞİ herkese açık bir bağlantı. Yükleyenler klasördeki mevcut dosyaları göremez.', 'A public link that lets anyone UPLOAD files into this folder. Uploaders never see the folder\\'s existing files.') }}\n </p>\n <div class=\"fx-perm-share-opts\">\n <label class=\"fx-perm-check\">\n <input type=\"checkbox\" v-model=\"dropPwd\" />\n {{ L('PIN ile koru', 'Protect with a PIN') }}\n </label>\n <label class=\"fx-perm-expiry\">\n <span class=\"fx-perm-muted\">{{ L('Süre', 'Expiry') }}</span>\n <select v-model.number=\"dropExpiry\" class=\"fx-perm-sel fx-perm-sel--sm\">\n <option v-for=\"o in expiryOptions\" :key=\"o.v\" :value=\"o.v\">{{ o.l }}</option>\n </select>\n </label>\n <button class=\"fx-perm-btn fx-perm-btn--primary\" :disabled=\"dropBusy\" @click=\"createDropLink\">\n {{ L('Bağlantı oluştur', 'Create link') }}\n </button>\n </div>\n\n <button type=\"button\" class=\"fx-perm-btn fx-perm-btn--ghost fx-perm-advtoggle\" @click=\"dropShowAdv = !dropShowAdv\">\n {{ dropShowAdv ? L('Gelişmiş ▲', 'Advanced ▲') : L('Gelişmiş ▼', 'Advanced ▼') }}\n </button>\n <div v-if=\"dropShowAdv\" class=\"fx-perm-adv\">\n <label class=\"fx-perm-adv-row\">\n <span class=\"fx-perm-muted\">{{ L('En fazla dosya', 'Max files') }}</span>\n <input v-model=\"dropMaxFiles\" type=\"number\" min=\"1\" class=\"fx-perm-input fx-perm-input--sm\" placeholder=\"20\" />\n </label>\n <label class=\"fx-perm-adv-row\">\n <span class=\"fx-perm-muted\">{{ L('Dosya başı MB', 'MB / file') }}</span>\n <input v-model=\"dropMaxSizeMB\" type=\"number\" min=\"1\" class=\"fx-perm-input fx-perm-input--sm\" placeholder=\"500\" />\n </label>\n <label class=\"fx-perm-adv-row\">\n <span class=\"fx-perm-muted\">{{ L('İzinli türler', 'Allowed types') }}</span>\n <input v-model=\"dropAllowedExt\" type=\"text\" class=\"fx-perm-input fx-perm-input--sm\" :placeholder=\"L('hepsi (örn. pdf, jpg)', 'all (e.g. pdf, jpg)')\" />\n </label>\n <label class=\"fx-perm-check\">\n <input type=\"checkbox\" v-model=\"dropAskName\" />\n {{ L('Yükleyenin adını sor', 'Ask uploader name') }}\n </label>\n </div>\n\n <div v-if=\"dropErr\" class=\"fx-perm-warn\">{{ dropErr }}</div>\n\n <div v-if=\"dropResult\" class=\"fx-perm-result\">\n <div class=\"fx-perm-linkrow\">\n <a :href=\"dropResult.url\" target=\"_blank\" rel=\"noopener\" class=\"fx-perm-link\">{{ dropResult.url }}</a>\n <button class=\"fx-perm-btn fx-perm-btn--sm\" @click=\"copy(dropResult.url, 'drop')\">\n {{ copied === 'drop' ? L('Kopyalandı ✓', 'Copied ✓') : L('Kopyala', 'Copy') }}\n </button>\n </div>\n <div v-if=\"dropResult.pin\" class=\"fx-perm-pin\">\n <span>PIN: <code>{{ dropResult.pin }}</code></span>\n <button class=\"fx-perm-btn fx-perm-btn--sm\" @click=\"copy(dropResult.pin, 'droppin')\">\n {{ copied === 'droppin' ? L('Kopyalandı ✓', 'Copied ✓') : L('Kopyala', 'Copy') }}\n </button>\n </div>\n\n <!-- email the upload link to one or more people -->\n <div class=\"fx-perm-mailrow\">\n <input v-model=\"dropMailTo\" type=\"text\" class=\"fx-perm-input\" autocomplete=\"off\"\n :placeholder=\"L('e-posta(lar) — virgülle ayırın', 'email(s) — comma separated')\" @keyup.enter=\"sendDropMail\" />\n <button class=\"fx-perm-btn\" :disabled=\"dropMailBusy\" @click=\"sendDropMail\">\n {{ L('Gönder', 'Send') }}\n </button>\n </div>\n <div v-if=\"dropMailNotice\" class=\"fx-perm-notice\">{{ dropMailNotice }}</div>\n\n <!-- native share (OS share sheet) — same as the fishapp Paylaş button -->\n <button v-if=\"canShare\" type=\"button\" class=\"fx-perm-btn fx-perm-btn--ghost fx-perm-sharebtn\" @click=\"nativeShare(dropBody())\">\n <span aria-hidden=\"true\">📤</span> {{ L('Paylaş', 'Share') }}\n </button>\n </div>\n </div>\n </template>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fx-perm-overlay {\n position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5);\n display: flex; align-items: center; justify-content: center; z-index: 10000;\n font-family: var(--fe-font);\n}\n.fx-perm-modal {\n display: flex; flex-direction: column;\n background: var(--fe-bg); color: var(--fe-text);\n width: min(520px, 94vw); max-height: 86vh;\n border: 1px solid var(--fe-border); border-radius: var(--fe-radius-lg, 14px);\n box-shadow: var(--fe-shadow); font-size: 14px; overflow: hidden;\n}\n/* header + tabs are fixed; only the body scrolls */\n.fx-perm-head {\n display: flex; align-items: center; justify-content: space-between; gap: 10px;\n padding: 16px 18px 12px; flex: none;\n}\n.fx-perm-title { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.fx-perm-ico { font-size: 22px; line-height: 1; }\n.fx-perm-titletext { display: flex; flex-direction: column; min-width: 0; }\n.fx-perm-title h3 { margin: 0; font-size: 15px; font-weight: 600; color: var(--fe-text); }\n.fx-perm-sub {\n font-size: 12px; color: var(--fe-text); max-width: 340px;\n overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n}\n.fx-perm-subdim { color: var(--fe-text-muted); }\n.fx-perm-x {\n background: none; border: none; font-size: 17px; cursor: pointer;\n color: var(--fe-text-muted); flex: none; line-height: 1; padding: 2px 4px; border-radius: 6px;\n}\n.fx-perm-x:hover { color: var(--fe-text); background: var(--fe-bg-hover); }\n.fx-perm-tabs { display: flex; gap: 2px; padding: 0 18px; border-bottom: 1px solid var(--fe-border); flex: none; }\n.fx-perm-tab {\n background: none; border: none; border-bottom: 2px solid transparent;\n padding: 8px 12px; cursor: pointer; color: var(--fe-text-muted); font-size: 13px;\n font-family: inherit; font-weight: 500;\n}\n.fx-perm-tab:hover { color: var(--fe-text); }\n.fx-perm-tab.is-active { color: var(--fe-primary); border-bottom-color: var(--fe-primary); }\n.fx-perm-body { flex: 1 1 auto; overflow-y: auto; padding: 14px 18px 18px; }\n\n.fx-perm-addcard {\n padding: 12px; border-radius: var(--fe-radius-md, 10px);\n background: var(--fe-bg-elev); border: 1px solid var(--fe-border);\n}\n.fx-perm-section { margin-top: 16px; }\n.fx-perm-section h4 {\n margin: 0 0 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--fe-text-muted);\n}\n.fx-perm-empty { color: var(--fe-text-muted); font-size: 13px; padding: 8px 2px; }\n\n/* person rows */\n.fx-perm-person { display: flex; align-items: center; gap: 10px; padding: 7px 2px; }\n.fx-perm-person + .fx-perm-person { border-top: 1px solid var(--fe-border); }\n.fx-perm-inh { color: var(--fe-text-muted); }\n.fx-perm-av {\n width: 28px; height: 28px; flex: none; border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n background: var(--fe-primary); color: var(--fe-text-on-primary, #fff);\n font-size: 12px; font-weight: 600;\n}\n.fx-perm-av--dim { background: var(--fe-bg-hover); color: var(--fe-text-muted); }\n.fx-perm-user { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fe-text); min-width: 0; }\n.fx-perm-from { font-size: 11px; color: var(--fe-text-muted); white-space: nowrap; }\n.fx-perm-badge {\n font-size: 11px; padding: 2px 9px; border-radius: 999px;\n background: var(--fe-bg-hover); color: var(--fe-text);\n}\n\n/* inputs / selects / buttons */\n.fx-perm-sel, .fx-perm-input {\n padding: 7px 9px; border-radius: var(--fe-radius-sm, 7px); border: 1px solid var(--fe-border);\n background: var(--fe-bg); color: var(--fe-text); font-size: 13px; font-family: inherit;\n}\n.fx-perm-sel--sm { padding: 5px 7px; font-size: 12px; }\n.fx-perm-sel:focus, .fx-perm-input:focus { outline: none; border-color: var(--fe-primary); }\n.fx-perm-add { display: flex; gap: 8px; align-items: stretch; }\n.fx-perm-emailwrap { position: relative; flex: 1; min-width: 120px; }\n.fx-perm-input { width: 100%; box-sizing: border-box; }\n.fx-perm-suggest {\n position: absolute; top: calc(100% + 3px); left: 0; right: 0; z-index: 5; margin: 0; padding: 4px;\n list-style: none; background: var(--fe-bg); border: 1px solid var(--fe-border);\n border-radius: var(--fe-radius-sm, 7px); box-shadow: var(--fe-shadow); max-height: 210px; overflow: auto;\n}\n.fx-perm-suggest li { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 6px; cursor: pointer; }\n.fx-perm-suggest li:hover { background: var(--fe-bg-hover); }\n.fx-perm-suggest-av {\n width: 24px; height: 24px; flex: none; border-radius: 50%; display: flex; align-items: center; justify-content: center;\n background: var(--fe-bg-hover); color: var(--fe-text); font-size: 11px; font-weight: 600;\n}\n.fx-perm-suggest-txt { display: flex; flex-direction: column; min-width: 0; }\n.fx-perm-suggest-name { color: var(--fe-text); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fx-perm-suggest-meta { color: var(--fe-text-muted); font-size: 11px; }\n.fx-perm-check { display: inline-flex; gap: 6px; align-items: center; font-size: 13px; color: var(--fe-text); cursor: pointer; }\n.fx-perm-btn {\n padding: 7px 13px; border-radius: var(--fe-radius-sm, 7px); border: 1px solid var(--fe-border);\n background: var(--fe-bg); color: var(--fe-text); font-size: 13px; font-family: inherit; cursor: pointer; white-space: nowrap;\n}\n.fx-perm-btn:hover:not(:disabled) { background: var(--fe-bg-hover); }\n.fx-perm-btn:disabled { opacity: 0.55; cursor: default; }\n.fx-perm-btn--sm { padding: 5px 10px; font-size: 12px; }\n.fx-perm-btn--primary { background: var(--fe-primary); border-color: var(--fe-primary); color: var(--fe-text-on-primary, #fff); }\n.fx-perm-btn--primary:hover:not(:disabled) { background: var(--fe-primary-hover, var(--fe-primary)); filter: brightness(1.05); }\n.fx-perm-btn--ghost { background: none; border-color: transparent; color: var(--fe-primary); padding-left: 2px; }\n.fx-perm-btn--ghost:hover:not(:disabled) { background: none; text-decoration: underline; }\n.fx-perm-del { background: none; border: none; color: var(--fe-danger); cursor: pointer; font-size: 14px; flex: none; padding: 2px 4px; }\n.fx-perm-del:hover:not(:disabled) { filter: brightness(1.15); }\n\n/* invite sub-flow */\n.fx-perm-invite {\n margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--fe-border);\n}\n.fx-perm-invite-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }\n.fx-perm-invite-row { display: flex; gap: 8px; align-items: stretch; }\n.fx-perm-invite-row .fx-perm-btn--primary { flex: 1; }\n\n/* share result */\n.fx-perm-share-opts { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }\n.fx-perm-expiry { display: inline-flex; gap: 6px; align-items: center; font-size: 13px; }\n.fx-perm-share-opts .fx-perm-btn--primary { margin-left: auto; }\n.fx-perm-result { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--fe-border); }\n.fx-perm-linkrow { display: flex; gap: 8px; align-items: center; }\n.fx-perm-link { color: var(--fe-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; text-decoration: none; }\n.fx-perm-link:hover { text-decoration: underline; }\n.fx-perm-pin { margin: 8px 0 0; font-size: 13px; color: var(--fe-text); display: flex; align-items: center; gap: 8px; }\n.fx-perm-pin code, .fx-perm-reveal code { font-family: var(--fe-font-mono, monospace); background: var(--fe-bg-hover); padding: 1px 6px; border-radius: 5px; }\n.fx-perm-mailrow { display: flex; gap: 8px; margin-top: 10px; }\n.fx-perm-mailrow .fx-perm-input { flex: 1; }\n.fx-perm-hint { font-size: 13px; color: var(--fe-text-muted); margin: 10px 0 0; }\n/* native \"Paylaş\" button — sits under the mail row, full width */\n.fx-perm-sharebtn { display: flex; width: 100%; align-items: center; justify-content: center; gap: 6px; margin-top: 8px; }\n\n/* file-drop tab */\n.fx-perm-dropintro { margin: 0 0 12px; line-height: 1.4; }\n.fx-perm-advtoggle { margin-top: 10px; padding-left: 2px; }\n.fx-perm-adv {\n margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--fe-border);\n display: flex; flex-direction: column; gap: 8px;\n}\n.fx-perm-adv-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; }\n.fx-perm-input--sm { width: 130px; padding: 5px 8px; font-size: 12px; }\n\n.fx-perm-warn {\n background: rgba(245, 158, 11, 0.14); border: 1px solid rgba(245, 158, 11, 0.4);\n border-radius: var(--fe-radius-sm, 7px); padding: 8px 10px; font-size: 13px; margin-bottom: 10px; color: var(--fe-text);\n}\n.fx-perm-notice { margin-top: 8px; font-size: 13px; color: var(--fe-text-muted); }\n.fx-perm-reveal { margin-top: 8px; font-size: 13px; word-break: break-all; color: var(--fe-text); }\n.fx-perm-muted { color: var(--fe-text-muted); font-size: 13px; }\n</style>\n","<script setup lang=\"ts\">\n/**\n * FileExplorer — the public Vue component, panel + PWA + standalone use.\n *\n * Orchestrates:\n * - Directory listing (useFileApi)\n * - Chunked multipart upload (useUploadChunked) + drag & drop\n * - Selection + keyboard shortcuts\n * - Context menu (Teleport-based) with per-target actions\n * - Modal flows: newFolder / rename / delete / share / preview\n * - Eager Monaco preload so the code-edit path is snappy\n *\n * All backend endpoints arrive via the `config` prop. Auth is bearer\n * (PWA / OIDC) / CSRF (panel) / basic / none — `useFileApi` swallows\n * the difference.\n */\nimport { computed, customRef, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';\nimport type { ExplorerConfig } from './types/ExplorerConfig';\nimport type {\n FileNode,\n ShareInfo,\n ViewMode,\n ClipboardState,\n Capabilities,\n} from './types/FileNode';\nimport { isExternalUsable } from './types/FileNode';\nimport { useFileApi, type GlobalSearchHit } from './composables/useFileApi';\nimport { useUploadChunked, type UploadJob } from './composables/useUploadChunked';\nimport { useSelection } from './composables/useSelection';\nimport { useKeyboardShortcuts } from './composables/useKeyboardShortcuts';\nimport { useLocale } from './composables/useLocale';\nimport { usePendingOps, type PendingOp } from './composables/usePendingOps';\nimport { useRealtime } from './composables/useRealtime';\nimport { useThumbs } from './composables/useThumbs';\nimport { preloadEditor } from './composables/useMonacoLoader';\nimport PresenceBar from './components/PresenceBar.vue';\n\nimport Toolbar, { type SelectionMode } from './components/Toolbar.vue';\nimport StarButton from './components/StarButton.vue';\nimport TagPicker from './components/TagPicker.vue';\nimport RecentlyOpened from './components/RecentlyOpened.vue';\nimport Breadcrumb from './components/Breadcrumb.vue';\nimport ListView from './components/ListView.vue';\nimport GridView from './components/GridView.vue';\nimport ContextMenu, { type ContextAction } from './components/ContextMenu.vue';\nimport UploadProgress from './components/UploadProgress.vue';\nimport PendingOpsTray from './components/PendingOpsTray.vue';\nimport InspectorPanel from './components/InspectorPanel.vue'; /* koru:k1 */\n/* cila:c wiring */\nimport CommandPalette from './components/CommandPalette.vue';\nimport ShortcutsHelp from './components/ShortcutsHelp.vue';\n/* /cila:c wiring */\n\nimport NewFolderModal from './modals/NewFolderModal.vue';\nimport RenameModal from './modals/RenameModal.vue';\nimport DeleteConfirmModal from './modals/DeleteConfirmModal.vue';\nimport ShareModal from './modals/ShareModal.vue';\nimport PreviewModal from './modals/PreviewModal.vue';\nimport ConvertModal from './modals/ConvertModal.vue';\nimport PermissionsModal from './modals/PermissionsModal.vue';\n\nconst props = defineProps<{\n config: ExplorerConfig;\n}>();\n\nconst emit = defineEmits<{\n (e: 'share-created', payload: { path: string; url: string; pin: string | null }): void;\n (e: 'file-opened', file: { path: string; basename: string }): void;\n (e: 'error', err: { message: string; context?: unknown }): void;\n (e: 'upload-progress', p: { uploadId: string; percent: number; done: boolean }): void;\n (\n e: 'selection-change',\n items: Array<{ path: string; basename: string; type: 'file' | 'dir' }>,\n ): void;\n // Fires whenever the viewed folder changes (virtual `<storage>/<rel>` form).\n // Lets a host (e.g. the Explore page's realtime layer) track the current\n // folder without reaching into internal state.\n (e: 'navigate', p: { path: string }): void;\n}>();\n\n// --------------------------------------------------------------------\n// State\n// --------------------------------------------------------------------\n\nconst api = useFileApi(props.config);\n\n// Locale up-front: the pendingOps onSettled callback below (and the undo-toast\n// helpers) need `t()` at runtime, so the catalogue must be constructed before\n// they are wired. Depends only on props — safe this early.\nconst locale = computed(() => props.config.locale || 'tr');\nconst { t } = useLocale(locale);\n\n// Live collaboration (WebSocket file-change events + presence), bundled into the\n// core so every consumer — the native panel AND the embedded webcomponent —\n// gets it. Auth is a short-lived ticket fetched through the same API (works\n// same-origin and proxied cross-origin); it degrades to polling when no live\n// socket is available.\nconst realtime = useRealtime(api, { reload: () => load() });\nconst presenceUsers = realtime.presenceUsers;\n// True while the live socket is unavailable and the explorer runs on the\n// polling fallback — drives the small \"no live connection\" badge. Healthy\n// connections show nothing.\nconst realtimeDegraded = realtime.degraded;\nfunction realtimeRoom(vp: string): string | null {\n const p = (vp || '').replace(/^\\/+|\\/+$/g, '');\n if (p === '.trash' || p.startsWith('.trash/')) return null;\n // The wire form must go through the mode-aware qualify(), exactly like every\n // API call: in single-storage mode currentPath is a BARE relative path\n // (\"projeler/5\") — virtualToWire would mistake its first segment for an\n // adapter (\"projeler://5\") and subscribe a nonexistent room, so presence and\n // live changes silently missed the real folder. An empty p is the storage\n // root — a real room (\"main://\") — not \"no room\"; only the multi-storage\n // drives list (no adapter yet) has none.\n const wire = qualify(p);\n if (!wire || !wire.includes('://') || wire.startsWith('://')) return null;\n return wire;\n}\nonMounted(() => {\n realtime.start();\n realtime.subscribe(realtimeRoom(currentPath.value));\n});\nonBeforeUnmount(() => realtime.stop());\n\n// Authenticated thumbnails — raw thumb_url is root-relative + header-less,\n// which only ever worked for the native same-origin SPA (embedded hosts got\n// empty/broken <img>s). See useThumbs.\nconst thumbs = useThumbs(props.config.apiBase, api);\n\nconst chunked = useUploadChunked(props.config, api);\n\n// Undo registry for async pending ops: when a cleanly-invertible operation\n// (move → reverse move, trash-delete → restore) is queued, its inverse is\n// registered under the op id; once the op settles OK the toast grows a\n// \"Geri Al\" action. Ops without an entry keep the plain settled toast.\nconst opUndo = new Map<number, { message: string; fn: () => Promise<void> }>();\n\nconst pendingOps = usePendingOps(props.config, api, {\n onSettled: (op: PendingOp) => {\n const undo = opUndo.get(op.id);\n opUndo.delete(op.id);\n if (op.status === 'error') {\n flashToast(op.error_message || 'İşlem başarısız');\n } else if (undo) {\n undoToast(`${undo.message} (${op.progress_total})`, undo.fn);\n } else {\n const verb =\n op.op_type === 'copy'\n ? 'Kopyalandı'\n : op.op_type === 'move'\n ? 'Taşındı'\n : 'Silindi';\n flashToast(`${verb} (${op.progress_total})`);\n }\n void load();\n },\n});\n\nconst loading = ref(false);\n// rootPath confinement (UX): when set, the explorer treats this folder as its\n// floor — it opens there, never lists the drives root, and can't navigate\n// above it. Security is enforced server-side (X-Filex-Root / token root scope);\n// this is purely the clean-embed presentation. `rootFloor` is the virtual form\n// (`<storage>/<rel>`) used for path comparisons in multi-storage mode.\nconst rootPathProp = (props.config.rootPath || '').trim(); // qualified `<adapter>://<rel>`\nconst rootFloor = rootPathProp.replace('://', '/').replace(/^\\/+|\\/+$/g, '');\nconst initialFloorPath = rootFloor || props.config.initialPath || '';\nconst currentPath = ref<string>(initialFloorPath);\nconst adapter = ref<string>(props.config.defaultAdapter || 'brf');\nconst dirname = ref<string>(initialFloorPath);\nconst files = ref<FileNode[]>([]);\n// RBAC effective level for the current directory ('' = ACL not enforced on\n// this storage → no gating). Drives which write/manage actions are offered.\nconst dirPerm = ref<string>('');\n// The dead deep-link state: set to the requested path when a listing came\n// back 404 (folder doesn't exist) or 403 (RBAC-hidden — rendered identically\n// on purpose so a denied folder doesn't reveal that it exists). '' = none.\nconst notFoundPath = ref<string>('');\n// Listing failure that is NOT a dead link (network error, 5xx): remembered so\n// the body can render a retryable error state instead of a misleading \"this\n// folder is empty\". Only shown when no listing is visible — a failed\n// navigation away from a healthy listing keeps the current list + toast,\n// exactly as before.\nconst loadError = ref<string>('');\nlet loadErrorPath: string | undefined;\nfunction retryLoad() {\n void load(loadErrorPath);\n}\n\nconst VIEW_MODE_KEY = 'brf-file-explorer:view-mode';\nconst viewMode = customRef<ViewMode>((track, trigger) => {\n let value: ViewMode = (() => {\n try {\n const stored = localStorage.getItem(VIEW_MODE_KEY);\n if (stored === 'list' || stored === 'grid') return stored;\n } catch {\n /* private mode */\n }\n return props.config.viewMode ?? 'list';\n })();\n return {\n get() {\n track();\n return value;\n },\n set(next) {\n if (next === value) return;\n value = next;\n try {\n localStorage.setItem(VIEW_MODE_KEY, next);\n } catch {\n /* quota */\n }\n trigger();\n },\n };\n});\n/* cila:a density — Toolbar owns the persisted preference (filex.density);\n mirrored here only so the root `.fe` can carry fe--density-compact. */\nconst density = ref<'comfortable' | 'compact'>('comfortable');\nconst searchQuery = ref('');\n// trashMode — true while viewing the filex trash (soft-deleted nodes from the\n// backend trash endpoint), entered by opening the virtual `.trash` row and\n// exited by any normal navigation (load() resets it). Replaces a brittle\n// `currentPath.startsWith('fileman/.trash')` check that never matched the\n// filex backend's storage layout, so trash always looked empty.\nconst trashMode = ref(false);\n// The storage the trash view was entered from, so \"up\" returns there (not the\n// global root). Set in loadTrash().\nconst trashOrigin = ref<string>('');\nconst trashActive = computed(() => trashMode.value);\n\n// canGoUp/goUp — toolbar's \"↑ Up one level\" button. In single-storage\n// mode \"\" means the storage root; in multi-storage mode \"\" means\n// the global root (storage list). Both → no parent → button hidden.\nconst canGoUp = computed(() => {\n const p = (currentPath.value ?? '').replace(/^\\/+|\\/+$/g, '');\n if (rootFloor && p === rootFloor) return false; // at the confined floor — nowhere above\n return p.length > 0;\n});\n\n// True when the explorer is showing the synthetic storage list and\n// there's no real backend folder to mutate. New Folder / Upload /\n// Paste are hidden in this state.\nconst atVirtualRoot = computed(() => {\n if (!multiStorageRoot.value) return false;\n return !((currentPath.value ?? '').replace(/^\\/+|\\/+$/g, ''));\n});\n\nfunction goUp() {\n // Leaving the trash view returns to the storage it was opened from, not the\n // global storage-list root.\n if (trashMode.value) {\n void load(trashOrigin.value);\n return;\n }\n const cur = (currentPath.value ?? '').replace(/^\\/+|\\/+$/g, '');\n if (!cur || cur === rootFloor) return;\n const idx = cur.lastIndexOf('/');\n let parent = idx === -1 ? '' : cur.slice(0, idx);\n // Never step above the confined floor.\n if (rootFloor && !(parent === rootFloor || parent.startsWith(rootFloor + '/'))) parent = rootFloor;\n void load(parent);\n}\n\nconst selection = useSelection(() => files.value);\nwatch(\n () => [...selection.selected.value],\n () => {\n emit(\n 'selection-change',\n selection.nodes.value.map((n) => ({ path: n.path, basename: n.basename, type: n.type })),\n );\n // Presence focus: a single selected file is what the user is \"on\"; a\n // multi-select or folder selection clears it.\n const focusFiles = selection.nodes.value.filter((n) => n.type === 'file');\n realtime.setFocus(focusFiles.length === 1 ? focusFiles[0].basename : null);\n },\n);\n\nconst clipboard = ref<ClipboardState>({ mode: null, items: [], sourcePath: null });\n\nconst capabilitiesData = ref<Capabilities | null>(null);\n\n// Creative UI state: starred / tags / recently-opened. The component\n// helpers (StarButton, TagPicker, RecentlyOpened) handle their own\n// API calls — the explorer just tracks the cross-row state needed to\n// render inline stars and keep the recents tray in sync.\nconst starredIds = ref(new Set<number>());\nconst showRecents = ref(false);\nconst showTagPicker = ref(false);\nconst tagPickerNode = ref<FileNode | null>(null);\nconst recentRefreshKey = ref(0);\n\nasync function loadStarred() {\n try {\n const headers = await buildAuthHeaders();\n const base = props.config.apiBase ?? '';\n const res = await fetch(`${base}/api/files/manager/star/list?limit=500`, {\n headers,\n credentials: 'include',\n });\n if (!res.ok) return;\n const body = await res.json();\n const rows: { id?: number }[] = Array.isArray(body)\n ? body\n : Array.isArray(body?.entries)\n ? body.entries\n : Array.isArray(body?.nodes)\n ? body.nodes\n : [];\n starredIds.value = new Set(rows.map((n) => n.id).filter((id): id is number => typeof id === 'number'));\n } catch {\n // Silent — backend may be older without the meta routes.\n }\n}\n\nfunction onStarChange(n: FileNode, value: boolean) {\n if (typeof n.id !== 'number') return;\n const next = new Set(starredIds.value);\n if (value) next.add(n.id);\n else next.delete(n.id);\n starredIds.value = next;\n}\n\nasync function markRecent(n: FileNode) {\n if (typeof n.id !== 'number') return;\n try {\n const base = props.config.apiBase ?? '';\n await fetch(`${base}/api/files/manager/recent`, {\n method: 'POST',\n headers: await buildAuthHeaders({ 'Content-Type': 'application/json' }),\n credentials: 'include',\n body: JSON.stringify({ node_id: n.id }),\n });\n recentRefreshKey.value += 1;\n } catch {\n // Silent — the open succeeds, recent tracking is best-effort.\n }\n}\n\nfunction openTagPickerFor(n: FileNode) {\n if (typeof n.id !== 'number') return;\n tagPickerNode.value = n;\n showTagPicker.value = true;\n}\n\nfunction onRecentOpen(entry: { id: number; storage_id?: number; path: string; name: string }) {\n // RecentlyOpened emits the bare row — synthesize a FileNode shaped\n // enough for openNode to route into the editor / preview.\n const node = {\n type: 'file',\n path: entry.path,\n basename: entry.name,\n extension: (entry.name.split('.').pop() || '').toLowerCase(),\n id: entry.id,\n } as unknown as FileNode;\n showRecents.value = false;\n openNode(node);\n}\n\n// Resolution order for each external viewer: explicit config override → live\n// backend probe. The probe is the source of truth: an operator can flip the\n// service \"on\" but if last_check failed (state='error') we still hide the\n// entry so users don't get 503s on click. Explicit config wins because\n// embedders sometimes terminate TLS in front of filex and the backend can't\n// see the public URL.\nconst effectiveOnlyOfficeBase = computed<string | null>(() => {\n if (props.config.onlyOfficeBase) return props.config.onlyOfficeBase;\n const ext = capabilitiesData.value?.external?.onlyoffice;\n if (ext && !isExternalUsable(ext)) return null;\n return capabilitiesData.value?.onlyoffice_url || null;\n});\n\nconst effectiveOnlyOfficeConfigEndpoint = computed<string | null>(() => {\n if (!effectiveOnlyOfficeBase.value) return null;\n return api.endpoints.onlyOfficeConfig || null;\n});\n\nconst effectiveDrawioUrl = computed<string | null>(() => {\n const override = props.config.drawioUrl || props.config.drawioBase;\n if (override) return override;\n const ext = capabilitiesData.value?.external?.drawio;\n if (ext && !isExternalUsable(ext)) return null;\n return capabilitiesData.value?.drawio_url || null;\n});\n\n// Universal converter (p2r3/convert fork). convert_url is only populated by\n// the backend when the \"convert\" external service is enabled, so a simple\n// presence check is enough gating.\nconst effectiveConvertUrl = computed<string | null>(\n () => props.config.convertBase || capabilitiesData.value?.convert_url || null,\n);\n\n// Upload\nconst uploadJobs = ref<UploadJob[]>([]);\nconst fileInputEl = ref<HTMLInputElement | null>(null);\n\n// Modals\nconst showNewFolder = ref(false);\nconst showRename = ref(false);\nconst showDelete = ref(false);\nconst showShare = ref(false);\nconst showPreview = ref(false);\nconst renameTarget = ref<FileNode | null>(null);\nconst shareTarget = ref<FileNode | null>(null);\nconst activeShare = ref<(ShareInfo & { url: string; filename?: string }) | null>(null);\nconst previewTarget = ref<FileNode | null>(null);\nconst previewMode = ref<'edit' | 'view'>('edit');\nconst showConvert = ref(false);\nconst convertTarget = ref<FileNode | null>(null);\nconst showPerm = ref(false);\nconst permTarget = ref<FileNode | null>(null);\n\n/* === koru:k1 — inspector (details) panel ===\n * Open/closed preference persists under `filex.inspector`; the panel itself\n * mounts with v-if so the closed state leaves zero DOM behind. */\nconst INSPECTOR_LS_KEY = 'filex.inspector';\nconst showInspector = ref<boolean>(\n (() => {\n try {\n return localStorage.getItem(INSPECTOR_LS_KEY) === '1';\n } catch {\n return false;\n }\n })(),\n);\nfunction persistInspector(v: boolean) {\n try {\n localStorage.setItem(INSPECTOR_LS_KEY, v ? '1' : '0');\n } catch {\n /* quota / private mode */\n }\n}\nfunction toggleInspector() {\n showInspector.value = !showInspector.value;\n persistInspector(showInspector.value);\n}\nfunction openInspector() {\n if (!showInspector.value) {\n showInspector.value = true;\n persistInspector(true);\n }\n}\nfunction closeInspector() {\n if (showInspector.value) {\n showInspector.value = false;\n persistInspector(false);\n }\n}\n// Folder summary label for the no-selection state.\nconst inspectorDirLabel = computed(() => {\n if (trashMode.value) return t('node.trash');\n const p = (currentPath.value ?? '').replace(/^\\/+|\\/+$/g, '');\n if (!p) return adapter.value || t('breadcrumb.root');\n return p.split('/').pop() || p;\n});\nfunction onInspectorManage(n: FileNode) {\n permTarget.value = n;\n showPerm.value = true;\n}\n/* === /koru:k1 === */\n\n// RBAC helpers. '' means ACL is not enforced on this storage → full access\n// (the pre-RBAC default). Otherwise 'editor'/'owner' may write; only 'owner'\n// manages permissions. Enforcement is server-side; this just shapes the menu.\nfunction permCanEdit(p: string | undefined): boolean {\n // undefined = ACL not enforced (dev / unwired) → full access. In production\n // the backend always sends a level; 'none'/'viewer' cannot write, only\n // 'editor'/'owner' can.\n return p === undefined || p === 'editor' || p === 'owner';\n}\nfunction permIsOwner(p: string | undefined): boolean {\n return p === 'owner';\n}\n// Effective perm for a selection: a single entry's own perm (falls back to the\n// directory perm), else the directory perm for multi-select / background.\nfunction selPerm(sel: FileNode[]): string {\n if (sel.length === 1 && typeof sel[0]?.perm === 'string') return sel[0].perm as string;\n return dirPerm.value;\n}\n// Can the current user write into the directory being viewed? Gates the\n// toolbar New Folder / Upload / Paste + drag-drop upload.\nconst canWriteHere = computed(() => permCanEdit(dirPerm.value));\n// Empty-state affordances: the \"drop files here\" hint + upload button only\n// make sense in a real writable folder (not the virtual drives root, not the\n// trash view).\nconst emptyCanUpload = computed(\n () => canWriteHere.value && !atVirtualRoot.value && !trashMode.value,\n);\n\n// Context menu\nconst ctxRef = ref<InstanceType<typeof ContextMenu> | null>(null);\nconst rootEl = ref<HTMLElement | null>(null);\nconst toolbarRef = ref<InstanceType<typeof Toolbar> | null>(null);\n\n/* bag:b4 — narrow/embed mini mode.\n * isNarrow: container width < 560px (ResizeObserver on the .fe root, so it\n * tracks the EMBED container, not the viewport) → root gets `fe--narrow`,\n * the toolbar collapses and the upload FAB appears.\n * isCoarse: touch-first device → context menus render as a bottom sheet. */\nconst isNarrow = ref(false);\nconst isCoarse = ref(false);\nlet narrowRO: ResizeObserver | undefined;\nlet coarseMq: MediaQueryList | undefined;\nfunction syncCoarsePointer(e?: MediaQueryListEvent | MediaQueryList) {\n isCoarse.value = !!(e && 'matches' in e && e.matches);\n}\nonMounted(() => {\n if (typeof ResizeObserver !== 'undefined' && rootEl.value) {\n narrowRO = new ResizeObserver((entries) => {\n const w = entries[0]?.contentRect?.width ?? rootEl.value?.clientWidth ?? 0;\n isNarrow.value = w > 0 && w < 560;\n });\n narrowRO.observe(rootEl.value);\n }\n if (typeof window !== 'undefined' && window.matchMedia) {\n coarseMq = window.matchMedia('(pointer: coarse)');\n syncCoarsePointer(coarseMq);\n coarseMq.addEventListener?.('change', syncCoarsePointer);\n }\n});\nonBeforeUnmount(() => {\n narrowRO?.disconnect();\n narrowRO = undefined;\n coarseMq?.removeEventListener?.('change', syncCoarsePointer);\n coarseMq = undefined;\n});\n/* /bag:b4 */\n\n// Toast (tiny, no lib). Evolved into a snackbar: plain messages keep the old\n// 2.5s auto-hide; messages carrying an action (\"Geri Al\") stay 8s and can be\n// dismissed by click or Esc.\ninterface ToastState {\n message: string;\n actionLabel?: string;\n action?: () => void | Promise<void>;\n}\nconst toast = ref<ToastState | null>(null);\nlet toastTimer: ReturnType<typeof setTimeout> | undefined;\nfunction showToast(state: ToastState, ms: number) {\n toast.value = state;\n if (toastTimer) clearTimeout(toastTimer);\n toastTimer = setTimeout(() => (toast.value = null), ms);\n}\nfunction flashToast(msg: string) {\n showToast({ message: msg }, 2500);\n}\nfunction undoToast(message: string, undo: () => Promise<void>) {\n showToast({ message, actionLabel: t('toast.undo'), action: undo }, 8000);\n}\nfunction dismissToast() {\n if (toastTimer) {\n clearTimeout(toastTimer);\n toastTimer = undefined;\n }\n toast.value = null;\n}\nasync function runToastAction() {\n const act = toast.value?.action;\n dismissToast();\n if (!act) return;\n try {\n await act();\n flashToast(t('toast.undone'));\n await load();\n } catch {\n flashToast(t('toast.undo_failed'));\n }\n}\n\n// --------------------------------------------------------------------\n// Data loading\n// --------------------------------------------------------------------\n\n// multiStorageRoot — when on, \"/\" is a virtual folder listing every\n// configured storage as a clickable dir. Path semantics shift:\n//\n// \"\" → global root, list storages\n// \"<storage>\" → that storage's root (api: `<storage>://`)\n// \"<storage>/<rel>\" → deeper folder (api: `<storage>://<rel>`)\n//\n// `qualify()` is overridden inside this mode to translate the\n// slash-separated user path into the wire `<adapter>://<rel>` form.\nconst multiStorageRoot = computed(() => props.config.multiStorageRoot === true);\n\nfunction splitVirtualPath(p: string): { adapter: string; rel: string } {\n const clean = p.replace(/^\\/+|\\/+$/g, '');\n if (!clean) return { adapter: '', rel: '' };\n const slash = clean.indexOf('/');\n if (slash === -1) return { adapter: clean, rel: '' };\n return { adapter: clean.slice(0, slash), rel: clean.slice(slash + 1) };\n}\n\nfunction virtualToWire(p: string): string {\n // Convert `s3-test/example` → `s3-test://example`. Pass-through\n // when the input already carries `://` (legacy callers).\n if (p.includes('://')) return p;\n const { adapter, rel } = splitVirtualPath(p);\n if (!adapter) return ''; // global root — no wire form\n return rel ? `${adapter}://${rel}` : `${adapter}://`;\n}\n\nfunction wireToVirtual(p: string): string {\n // Convert `s3-test://example` → `s3-test/example`.\n const idx = p.indexOf('://');\n if (idx === -1) return p.replace(/^\\/+|\\/+$/g, '');\n const adapter = p.slice(0, idx);\n const rel = p.slice(idx + 3).replace(/^\\/+|\\/+$/g, '');\n return rel ? `${adapter}/${rel}` : adapter;\n}\n\nfunction virtualStorageRows(): FileNode[] {\n // Synthesize a FileNode for every configured storage. Used as the\n // \"/\" listing in multi-storage mode.\n const list = props.config.storages ?? [];\n return list.map((s) => ({\n type: 'dir',\n path: s.name, // virtual path (no adapter prefix)\n basename: s.label || s.name,\n extension: '',\n storage: s.name,\n visibility: 'private',\n file_size: 0,\n mime_type: 'inode/storage',\n extra_metadata: { driver: s.driver, readOnly: s.readOnly },\n } as unknown as FileNode));\n}\n\nasync function load(path?: string) {\n loading.value = true;\n // Any normal navigation exits trash mode (the trash view is entered only\n // by opening the virtual `.trash` row, which calls loadTrash()).\n trashMode.value = false;\n let requested = path ?? currentPath.value ?? '';\n try {\n notFoundPath.value = '';\n loadError.value = '';\n // Clamp to the confined floor: an empty/above-floor request (incl. a stale\n // persisted path or the drives root) snaps back to rootPath. This both\n // suppresses the multi-storage drives list and blocks up-navigation.\n if (rootFloor) {\n const p = String(requested).replace(/^\\/+|\\/+$/g, '');\n if (!p || !(p === rootFloor || p.startsWith(rootFloor + '/'))) requested = rootFloor;\n }\n\n // Multi-storage virtual root — synthesize a list of storages\n // instead of calling the backend.\n if (multiStorageRoot.value && !virtualToWire(requested)) {\n currentPath.value = '';\n adapter.value = '';\n dirname.value = '';\n files.value = virtualStorageRows();\n return;\n }\n\n const target = multiStorageRoot.value\n ? virtualToWire(requested)\n : qualify(requested);\n\n const resp = searchQuery.value\n ? await api.search(target, searchQuery.value)\n : await api.index(target);\n adapter.value = resp.adapter;\n dirname.value = resp.dirname;\n dirPerm.value = (resp.perm as string) || '';\n files.value = (resp.files || []).filter((f) => {\n if (f.path.includes('.thumbs')) return false;\n if (f.path.includes('.versions') || f.basename === '.versions') return false;\n if (f.basename === '.trash') return false;\n if (f.basename === '.keepdir') return false;\n return true;\n });\n // Inject virtual `.trash` entry at root only.\n const dirRel = stripAdapter(resp.dirname);\n const inRoot = dirRel === 'fileman' || dirRel === '';\n const isTrashListing = dirRel.startsWith('fileman/.trash');\n const trashEntryEnabled = props.config.trashVisible !== false;\n if (!isTrashListing && inRoot && trashEntryEnabled) {\n files.value.unshift({\n type: 'dir',\n path: `${resp.adapter}://fileman/.trash`,\n basename: '.trash',\n extension: '',\n storage: resp.adapter,\n visibility: 'private',\n size: 0,\n file_size: 0,\n mime_type: 'inode/directory',\n extra_metadata: {},\n } as unknown as FileNode);\n void hydrateTrashRow(resp.adapter);\n }\n // currentPath is the user-facing form: `s3-test/example` in\n // multi-storage mode, the bare relative path otherwise.\n currentPath.value = multiStorageRoot.value\n ? wireToVirtual(resp.dirname)\n : stripAdapter(resp.dirname);\n } catch (err) {\n const e = err instanceof Error ? err.message : String(err);\n const status = (err as { status?: number }).status;\n if (status === 404 || status === 403) {\n // Dead deep link (deleted folder, phantom path or RBAC-hidden dir):\n // show the dedicated not-found state instead of a toast over a stale\n // listing that reads as \"this folder is empty\".\n notFoundPath.value = String(requested);\n files.value = [];\n emit('error', { message: e, context: { path } });\n return;\n }\n // Real failure (network, 5xx). Never swallowed: the error still emits, and\n // it surfaces either as the retryable error state (nothing else on screen)\n // or as the classic toast over the still-visible previous listing.\n loadError.value = e;\n loadErrorPath = typeof requested === 'string' ? requested : undefined;\n emit('error', { message: e, context: { path } });\n if (files.value.length > 0) flashToast(e);\n } finally {\n loading.value = false;\n }\n}\n\nfunction stripAdapter(p: string): string {\n const idx = p.indexOf('://');\n return idx === -1 ? p : p.slice(idx + 3);\n}\n\n// \"Go to root\" escape hatch on the not-found state. load('') clamps to the\n// confined rootFloor on embeds, so this is safe everywhere.\nfunction leaveNotFound() {\n notFoundPath.value = '';\n void load('');\n}\n\n// hydrateTrashRow — the virtual `.trash` row is synthesized with no size/date;\n// fill both from the backend trash listing (total bytes + newest deletion) so\n// the row reads like a real folder instead of \"— / —\". Best-effort and\n// non-blocking: the row appears immediately and updates when the listing lands.\nasync function hydrateTrashRow(storage: string) {\n try {\n const { entries } = await api.listTrash(storage);\n const row = files.value.find((f) => f.basename === '.trash');\n if (!row) return;\n let total = 0;\n let newest = 0;\n for (const e of entries) {\n total += e.size || 0;\n const ts = Date.parse(e.deleted_at);\n if (!Number.isNaN(ts) && ts > newest) newest = ts;\n }\n row.size = total;\n if (newest > 0) row.last_modified = newest;\n } catch {\n /* keep the bare row */\n }\n}\n\n// loadTrash — show the backend trash (soft-deleted nodes) as a flat listing.\n// Entered by opening the virtual `.trash` row. Each row keeps its node `id`\n// so restore can target it. Permanent delete is admin-only / auto-purge, so\n// the only mutation offered here is Restore.\nasync function loadTrash() {\n loading.value = true;\n trashOrigin.value = adapter.value || '';\n trashMode.value = true;\n selection.clear();\n try {\n const { entries } = await api.listTrash();\n files.value = entries.map(\n (e) =>\n ({\n type: 'file',\n id: e.id,\n path: e.storage_name ? `${e.storage_name}://${e.path}` : e.path,\n basename: e.name,\n extension: e.name.includes('.') ? e.name.split('.').pop() || '' : '',\n storage: e.storage_name || '',\n visibility: 'private',\n file_size: e.size,\n mime_type: e.mime || '',\n extra_metadata: { deleted_at: e.deleted_at, ttl_days: e.ttl_days ?? null },\n }) as unknown as FileNode,\n );\n dirname.value = '.trash';\n currentPath.value = '.trash';\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n emit('error', { message: msg, context: { op: 'trash-list' } });\n flashToast(msg);\n } finally {\n loading.value = false;\n }\n}\n\n/**\n * qualify — return `<adapter>://<rel>` for backend calls.\n *\n * The backend's manager handler picks a storage by parsing the\n * adapter prefix. Without one it falls back to `storages[0]`,\n * which 404s on every non-default storage (S3/SFTP/WebDAV in a\n * multi-storage install). All API callers (rename/move/delete/\n * upload/preview/download/share/copy) must use a qualified path.\n *\n * In multi-storage mode `currentPath` is `<storage>/<rel>` (no\n * `://`), so qualify forwards through `virtualToWire` which\n * splits the first segment off as the adapter. In single-storage\n * mode the legacy bare-relative path is glued onto `adapter.value`.\n *\n * `stripAdapter()` stays for cosmetic display logic only\n * (breadcrumb root check, inRoot computation, openPageBase).\n */\nfunction qualify(p: string): string {\n if (p && p.includes('://')) return p;\n if (multiStorageRoot.value) {\n const wire = virtualToWire(p ?? '');\n if (wire) return wire;\n return adapter.value ? `${adapter.value}://` : '';\n }\n if (!p) return `${adapter.value}://`;\n return `${adapter.value}://${p.replace(/^\\/+/, '')}`;\n}\n\n// ----------------------------------------------------------------\n// Undo helpers — compute the inverse of cleanly-invertible operations\n// (move → reverse move, rename → rename back, trash → restore). All\n// paths here are wire form (`<adapter>://<rel>`).\n// ----------------------------------------------------------------\n\nfunction wireBasename(p: string): string {\n const idx = p.indexOf('://');\n const rel = (idx === -1 ? p : p.slice(idx + 3)).replace(/\\/+$/, '');\n const slash = rel.lastIndexOf('/');\n return slash === -1 ? rel : rel.slice(slash + 1);\n}\n\nfunction wireParent(p: string): string {\n const idx = p.indexOf('://');\n const prefix = idx === -1 ? '' : p.slice(0, idx + 3);\n const rel = (idx === -1 ? p : p.slice(idx + 3)).replace(/\\/+$/, '');\n const slash = rel.lastIndexOf('/');\n return slash === -1 ? prefix : prefix + rel.slice(0, slash);\n}\n\nfunction wireJoin(dir: string, name: string): string {\n if (!dir) return name;\n return dir.endsWith('://') || dir.endsWith('/') ? dir + name : `${dir}/${name}`;\n}\n\n// Register the inverse of a queued async move under its op id: once the op\n// settles OK, the toast offers \"Geri Al\" which queues the reverse move. The\n// inverse op deliberately gets NO undo entry of its own (no redo ping-pong).\nfunction registerMoveUndo(\n opId: number,\n sources: string[],\n targetWire: string,\n originWire: string | undefined,\n) {\n if (!originWire || !targetWire) return;\n const movedPaths = sources.map((p) => wireJoin(targetWire, wireBasename(p)));\n if (movedPaths.length === 0) return;\n opUndo.set(opId, {\n message: t('toast.moved'),\n fn: async () => {\n const { op } = await api.moveAsync(movedPaths, originWire, targetWire);\n pendingOps.register(op);\n },\n });\n}\n\nwatch(\n () => searchQuery.value,\n () => void load(),\n);\n\n// ----------------------------------------------------------------\n// Path persistence\n// ----------------------------------------------------------------\nconst PATH_LS_KEY = 'brf-file-explorer:path';\n\nfunction persistMode(): 'hash' | 'localStorage' | 'hash+localStorage' | 'none' {\n return props.config.pathPersist ?? 'hash';\n}\n\nfunction hashPersistEnabled(): boolean {\n const m = persistMode();\n return m === 'hash' || m === 'hash+localStorage';\n}\n\n// A pasted/hand-edited hash can carry a stray `%` (a folder literally named\n// \"100%\") that decodeURIComponent rejects — fall back to the raw text.\nfunction safeDecode(s: string): string {\n try {\n return decodeURIComponent(s);\n } catch {\n return s;\n }\n}\n\nfunction readLsPath(): string {\n try {\n return localStorage.getItem(PATH_LS_KEY) || '';\n } catch {\n return '';\n }\n}\n\nfunction readHashPath(): string {\n const h = window.location.hash || '';\n if (!h.startsWith('#')) return '';\n return safeDecode(h.slice(1)).replace(/^\\/+|\\/+$/g, '');\n}\n\nfunction readPersistedPath(): string {\n if (typeof window === 'undefined') return '';\n const mode = persistMode();\n if (mode === 'none') return '';\n if (mode === 'localStorage') return readLsPath();\n const fromHash = readHashPath();\n if (fromHash || mode === 'hash') return fromHash;\n // hash+localStorage with an empty hash: an explicit start path\n // (?storage= deep link / rootPath floor) outranks the remembered folder.\n if (initialFloorPath) return '';\n return readLsPath();\n}\n\nfunction writePersistedPath(path: string) {\n if (typeof window === 'undefined') return;\n const mode = persistMode();\n if (mode === 'none') return;\n if (mode === 'localStorage' || mode === 'hash+localStorage') {\n try {\n if (path) localStorage.setItem(PATH_LS_KEY, path);\n else localStorage.removeItem(PATH_LS_KEY);\n } catch {\n /* private mode / quota */\n }\n if (mode === 'localStorage') return;\n }\n // Encode per segment so folder names with `%`/`#`/`?` survive the URL\n // round-trip while `/` separators stay readable.\n const encoded = path ? path.split('/').map(encodeURIComponent).join('/') : '';\n const target = encoded ? `#${encoded}` : '';\n if ((window.location.hash || '') === target) return;\n // replaceState never fires `hashchange`, so onHashChange only ever sees\n // genuine external edits (paste, back/forward) — no self-echo to suppress.\n history.replaceState(\n null,\n '',\n target || window.location.pathname + window.location.search,\n );\n}\n\nfunction onHashChange() {\n if (!hashPersistEnabled()) return;\n const p = readHashPath();\n if (p && p !== currentPath.value) {\n void load(p);\n }\n}\n\nwatch(currentPath, (p) => {\n writePersistedPath(p);\n emit('navigate', { path: p });\n realtime.subscribe(realtimeRoom(p));\n});\n\n// Let a host force a soft re-fetch of the current folder (reusing the existing\n// list-fetch) — used by the realtime layer to refresh on live change events\n// without a full component remount.\ndefineExpose({ reload: () => load() });\n\nonMounted(async () => {\n // Eagerly start fetching Monaco — the user doesn't pay for it\n // perceptually; click-to-edit hits an in-memory cache.\n preloadEditor();\n\n const fromPersist = readPersistedPath();\n await load(fromPersist || undefined);\n await nextTick();\n rootEl.value?.focus();\n // Best-effort initial fetch — silent if the older backend doesn't\n // expose /api/files/manager/starred. Without this stars never light\n // up on first render even when the row IS starred server-side.\n void loadStarred();\n if (hashPersistEnabled()) {\n window.addEventListener('hashchange', onHashChange);\n }\n if (api.endpoints.opsList) {\n pendingOps.startPolling();\n }\n if (api.endpoints.capabilities) {\n api\n .capabilities()\n .then((cap) => {\n capabilitiesData.value = cap;\n })\n .catch(() => {\n /* swallow — `onlyoffice_url` falls back to null */\n });\n }\n});\n\n// --------------------------------------------------------------------\n// Keyboard\n// --------------------------------------------------------------------\n\n/* cila:c wiring — command palette (Ctrl/Cmd+K) + shortcuts help (?) state */\nconst showPalette = ref(false);\nconst showShortcutsHelp = ref(false);\n/* /cila:c wiring */\n\n/* bul:s3 — palette \"everywhere\" search + open-hit navigation */\n\n// Debounce/min-chars live in the palette; this is just the API call.\nfunction paletteGlobalSearch(q: string): Promise<GlobalSearchHit[]> {\n return api.globalSearch(q, { limit: 8, scope: 'all' });\n}\n\n/**\n * Open a global-search hit: navigate to the file's folder, then select +\n * preview it through the existing openNode mechanics. Hits come back as raw\n * node rows (in-storage relative `path`, numeric `storage_id`), so the\n * storage segment for multi-storage mode is resolved best-effort: an\n * explicit name on the hit (future backends) > the only configured storage\n * > the storage currently open. A wrong guess lands on the existing\n * \"folder not found\" state, which is already a graceful dead-end.\n */\nasync function openSearchHit(hit: GlobalSearchHit) {\n const rel = String(hit.path ?? '').replace(/^\\/+|\\/+$/g, '');\n if (!rel) return;\n const isDir = hit.type === 'dir';\n const slash = rel.lastIndexOf('/');\n const targetRel = isDir ? rel : slash === -1 ? '' : rel.slice(0, slash);\n let target = targetRel;\n if (multiStorageRoot.value) {\n const configured = props.config.storages ?? [];\n const storageName =\n (typeof hit.storage === 'string' && hit.storage) ||\n (typeof hit.storage_name === 'string' && hit.storage_name) ||\n (configured.length === 1 ? configured[0].name : '') ||\n adapter.value;\n if (!storageName) return;\n target = targetRel ? `${storageName}/${targetRel}` : storageName;\n }\n await load(target);\n if (isDir) return;\n const name = String(hit.name ?? rel.slice(slash + 1));\n const node = files.value.find((f) => f.type === 'file' && f.basename === name);\n if (node) {\n selection.click(node.path);\n openNode(node);\n }\n}\n/* /bul:s3 */\n\nuseKeyboardShortcuts(rootEl, {\n onDelete: () => {\n if (!selection.isEmpty.value) showDelete.value = true;\n },\n onRename: () => {\n if (selection.nodes.value.length === 1) {\n renameTarget.value = selection.nodes.value[0];\n showRename.value = true;\n }\n },\n onSelectAll: () => selection.selectAll(),\n onOpen: () => {\n const n = selection.nodes.value[0];\n if (n) openNode(n);\n },\n onClose: () => {\n showNewFolder.value = false;\n showRename.value = false;\n showDelete.value = false;\n showShare.value = false;\n showPreview.value = false;\n ctxRef.value?.hide();\n dismissToast();\n /* koru:k1 — Esc closes the narrow-mode inspector overlay only; the wide\n side panel is a persistent surface toggled by `i` / the toolbar. */\n if (isNarrow.value) closeInspector();\n },\n onFocusSearch: () => toolbarRef.value?.focusSearch(),\n onCut: () => cut(),\n onCopy: () => copyToClipboard(),\n onPaste: () => paste(),\n onGoUp: () => goUp(),\n /* cila:c wiring */\n onPathJump: () => {\n showPalette.value = true;\n },\n onShowHelp: () => {\n showShortcutsHelp.value = true;\n },\n /* /cila:c wiring */\n onToggleInspector: () => toggleInspector() /* koru:k1 */,\n hasSelection: () => !selection.isEmpty.value,\n});\n\n// --------------------------------------------------------------------\n// Actions\n// --------------------------------------------------------------------\n\nconst OFFICE_EXTS = new Set([\n 'docx', 'xlsx', 'pptx',\n 'doc', 'xls', 'ppt',\n 'odt', 'ods', 'odp',\n]);\nconst TEXT_CODE_EXTS = new Set([\n 'txt', 'md', 'markdown', 'log', 'csv', 'tsv', 'conf', 'ini',\n 'env', 'toml', 'cfg',\n 'json', 'jsonc', 'yaml', 'yml', 'xml', 'svg',\n 'js', 'mjs', 'cjs', 'ts', 'tsx', 'jsx',\n 'css', 'scss', 'sass', 'less',\n 'html', 'htm', 'vue', 'svelte',\n 'php', 'py', 'rb', 'rs', 'go', 'java', 'kt', 'swift',\n 'cpp', 'c', 'h', 'hpp', 'cs', 'dart',\n 'sh', 'bash', 'zsh', 'sql', 'lua', 'pl', 'r',\n 'dockerfile', 'gradle', 'gitignore',\n]);\n\nfunction openNode(n: FileNode) {\n // The virtual `.trash` row opens the backend trash listing, not a real dir.\n if (n.basename === '.trash') {\n void loadTrash();\n return;\n }\n if (n.type === 'dir') {\n // Multi-storage virtual rows have a bare path (`s3-test`); pass\n // them straight to load() which will treat them as the wire form\n // for that storage's root. Real backend rows still come back as\n // `<adapter>://<rel>` and stripAdapter turns them into the user\n // path semantics load() expects.\n const target = multiStorageRoot.value\n ? wireToVirtual(n.path)\n : stripAdapter(n.path);\n void load(target);\n return;\n }\n // \"Aç\" / double-click contract: open in a new tab against the\n // standalone editor route, regardless of file type. The editor page\n // picks the right viewer (OnlyOffice for office, Monaco for code/\n // text, drawio iframe for .drawio, image/PDF/3D viewers otherwise)\n // and wires save-on-change. This is the shape brf-mono ships and\n // what users expect from a Files-style file manager.\n //\n // Capability gate: if we already know the required backend is offline\n // (OnlyOffice for office docs, drawio for diagrams), don't launch a\n // new tab that we'd just render a \"service not configured\" fallback\n // inside — drop into the in-page preview instead, which is the same\n // dead-end UI but without the tab-switching whiplash.\n // Double-click contract: in-page modal preview. Office docs and\n // other read-only kinds open in view mode so a quick peek doesn't\n // mount an editing surface on top of the content. Code/markdown\n // open in edit so the user gets the fast \"open, tweak, Ctrl+S\"\n // loop. Modal's \"Yeni sekmede aç\" button still launches the\n // standalone fullscreen editor route when richer editing is wanted.\n const ext = (n.extension || '').toLowerCase();\n // RBAC: viewers (no edit on this item) always get the read-only preview\n // modal — never the editable surface. This is the \"view vs edit\" split.\n previewMode.value = permCanEdit((n.perm as string) ?? dirPerm.value)\n ? previewModeForExt(ext)\n : 'view';\n previewTarget.value = n;\n showPreview.value = true;\n emit('file-opened', { path: n.path, basename: n.basename });\n void markRecent(n);\n}\n\nconst VIEW_DEFAULT_EXTS = new Set<string>([\n ...OFFICE_EXTS,\n 'drawio', 'dio',\n 'pdf', 'epub', 'ipynb', 'tiff', 'tif', 'psd',\n 'mmd', 'mermaid',\n 'glb', 'gltf', 'obj', 'stl', 'fbx', '3ds',\n 'zip', 'rar', '7z', 'tar', 'gz', 'tgz',\n 'jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'avif', 'svg', 'heic',\n 'mp4', 'webm', 'mov', 'mkv', 'm4v', 'ogv',\n 'mp3', 'wav', 'ogg', 'flac', 'm4a', 'aac', 'opus',\n]);\n\nfunction previewModeForExt(ext: string): 'view' | 'edit' {\n if (VIEW_DEFAULT_EXTS.has(ext)) return 'view';\n return 'edit';\n}\n\nasync function restoreSelection(targets?: FileNode[]) {\n const nodes = targets ?? selection.nodes.value;\n if (nodes.length === 0) return;\n try {\n // filex trash: restore by node id, then refresh the trash listing.\n if (trashMode.value) {\n const ids = nodes\n .map((n) => (n as { id?: number }).id)\n .filter((x): x is number => typeof x === 'number');\n const { restored } = await api.restoreIds(ids);\n flashToast(`${restored} öğe geri getirildi`);\n selection.clear();\n await loadTrash();\n return;\n }\n // Legacy path-based restore (brf-mono `.trash/` convention).\n if (!api.endpoints.restore) return;\n const items = nodes.map((n) => n.path); // qualified\n const { restored } = await api.restore(items);\n flashToast(`${restored} öğe geri getirildi`);\n selection.clear();\n await load();\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: 'restore' } });\n }\n}\n\nfunction previewNode(n: FileNode) {\n previewMode.value = 'view';\n previewTarget.value = n;\n showPreview.value = true;\n void markRecent(n);\n}\n\n/**\n * openNodeInNewTab — launches the standalone /files/edit route in a\n * fresh tab. Used by the context-menu \"Aç\" action; double-click stays\n * on the in-page modal path. Dirs still navigate inline (no editor for\n * directories). Falls back to the modal if no `openPageBase` is wired\n * by the embedder.\n */\nfunction openNodeInNewTab(n: FileNode) {\n if (n.type === 'dir') {\n const target = multiStorageRoot.value\n ? wireToVirtual(n.path)\n : stripAdapter(n.path);\n void load(target);\n return;\n }\n // RBAC: a viewer (no edit on this item) can't use the editable \"Aç\"\n // surface — drop to the read-only in-page preview instead.\n if (!permCanEdit((n.perm as string) ?? dirPerm.value)) {\n previewNode(n);\n return;\n }\n const ext = (n.extension || '').toLowerCase();\n const base = props.config.openPageBase;\n if (!base) {\n // Embedder didn't supply a standalone editor route — keep the\n // in-page modal as the only available affordance.\n openNode(n);\n return;\n }\n // Context-menu \"Aç\" is the intent-to-edit action — request edit\n // mode so OnlyOffice / Monaco mount with write permissions.\n // Read-only inspection lives on the \"Önizle\" entry + the dbl-click\n // in-page modal.\n const sep = base.includes('?') ? '&' : '?';\n const url =\n `${base}${sep}path=${encodeURIComponent(n.path)}` +\n `&type=${encodeURIComponent(ext)}` +\n `&mode=edit`;\n window.open(url, '_blank', 'noopener');\n emit('file-opened', { path: n.path, basename: n.basename });\n void markRecent(n);\n}\n\ntype ContextMode = 'selection' | 'breadcrumb';\nconst ctxMode = ref<ContextMode>('selection');\nconst breadcrumbCtxPath = ref<string>('');\nconst breadcrumbCtxLabel = ref<string>('');\n\nconst selectionMode = computed<SelectionMode>(() => {\n const sel = selection.nodes.value;\n if (sel.length === 0) return 'none';\n if (sel.length === 1) return sel[0].type === 'dir' ? 'single-dir' : 'single-file';\n return 'multi';\n});\n\nasync function onToolbarAction(key: string) {\n const sel = selection.nodes.value;\n // The toolbar's \"Aç\" opens the in-page preview/editor modal (quick peek);\n // everything else shares dispatchItemAction with the context menu so the two\n // identical menus also behave identically.\n if (key === 'open') {\n if (sel[0]) openNode(sel[0]);\n return;\n }\n await dispatchItemAction(key, sel);\n}\n\nasync function onContextTarget(node: FileNode, ev: MouseEvent) {\n ctxMode.value = 'selection';\n if (!selection.has(node.path)) {\n selection.click(node.path);\n await nextTick();\n }\n ctxRef.value?.show({ clientX: ev.clientX, clientY: ev.clientY }, selection.nodes.value);\n}\n\nfunction onContextCanvas(ev: MouseEvent) {\n ev.preventDefault();\n ctxMode.value = 'selection';\n selection.clear();\n ctxRef.value?.show({ clientX: ev.clientX, clientY: ev.clientY }, []);\n}\n\nfunction onCrumbContext(payload: { x: number; y: number; adapterPath: string; label: string }) {\n ctxMode.value = 'breadcrumb';\n breadcrumbCtxPath.value = payload.adapterPath;\n breadcrumbCtxLabel.value = payload.label;\n ctxRef.value?.show({ clientX: payload.x, clientY: payload.y }, []);\n}\n\nconst contextActions = computed<ContextAction[]>(() => {\n if (ctxMode.value === 'breadcrumb') {\n return [\n { key: 'open', label: t('ctx.open'), icon: '↗' },\n { key: 'copy-path', label: t('breadcrumb.copy_path'), icon: '📋' },\n ];\n }\n\n const sel = selection.nodes.value;\n const any = sel.length > 0;\n const single = sel.length === 1;\n\n if (trashActive.value) {\n if (!any) return [];\n return [\n { key: 'restore', label: t('ctx.restore'), icon: '↩' },\n { divider: true, key: 'sep1', label: '' },\n { key: 'delete', label: t('ctx.delete_perm'), icon: '🗑', danger: true },\n ];\n }\n\n // Storage roots (the virtual rows shown at the multi-storage \"/\"\n // overview) aren't real filesystem entries — they're mount points.\n // Hide every mutation entry (rename/delete/share/cut/copy/new-folder/\n // paste) and only offer \"Aç\" so the menu doesn't surface actions\n // that would 4xx on the backend.\n //\n // PRIOR BUG: this used `currentPath === '/'` but the load() branch\n // for the virtual root sets currentPath to EMPTY string, not '/'.\n // So the guard never fired and every mutation action leaked into\n // the menu at the depo listing — including new-folder + paste,\n // which Burak called out in the most direct possible terms. Use\n // the same empty-after-trim test as `atVirtualRoot` above.\n const trimmedPath = (currentPath.value ?? '').replace(/^\\/+|\\/+$/g, '');\n const inStorageRoot = multiStorageRoot.value && trimmedPath === '';\n if (inStorageRoot) {\n if (!any) return [];\n if (!single) return [];\n return [\n { key: 'open', label: t('ctx.open'), icon: '↗' },\n ];\n }\n\n // Empty background right-click: folder-level actions only. Viewers (no edit\n // on this dir) get nothing here.\n if (!any) {\n if (!permCanEdit(dirPerm.value)) return [];\n return [\n { key: 'new-folder', label: t('toolbar.new_folder'), icon: '📁' },\n { key: 'paste', label: t('ctx.paste'), icon: '📋', disabled: !clipboard.value.mode },\n ];\n }\n\n return selectionActionList(sel);\n});\n\n// selectionActionList — the SINGLE source of truth for the actions offered on a\n// selection. BOTH the right-click context menu AND the top toolbar render this\n// exact list so they can never drift apart (Burak: \"sağ klik menüyle üst menü\n// tutmuyor\"). The toolbar filters out dividers/hidden; the context menu shows\n// them. Action handling is unified in dispatchItemAction().\nfunction selectionActionList(sel: FileNode[]): ContextAction[] {\n const any = sel.length > 0;\n const single = sel.length === 1;\n const isFile = single && sel[0]?.type === 'file';\n const tagsLabel = locale.value === 'en' ? 'Tags…' : 'Etiketler…';\n const singleHasId = single && typeof sel[0]?.id === 'number';\n const copyIdLabel = locale.value === 'en' ? 'Copy node id' : \"Node id'yi kopyala\";\n // RBAC: gate mutating actions when the caller lacks edit on the target. The\n // \"İzinler\" (permissions) action shows only for owners on RBAC-on storages.\n const p = selPerm(sel);\n const w = permCanEdit(p); // may write here\n // Unified \"Paylaş / İzinler\" popup: public share link (editor+) + per-user\n // permissions (owner-only, decided inside the modal).\n // Unified \"Paylaş / İzinler\" popup carries the public share link, per-user\n // permissions AND the folder-only \"Dosya İste\" (file-drop) tab — the user\n // picks the action from inside the modal, so there's no separate button.\n const accessLabel = locale.value === 'en' ? 'Share / Permissions' : 'Paylaş / İzinler';\n return [\n { key: 'open', label: t('ctx.open'), icon: '↗', hidden: !single },\n { key: 'preview', label: t('ctx.preview'), icon: '👁', hidden: !single, disabled: !isFile },\n { key: 'download', label: t('ctx.download'), icon: '⬇', hidden: !single, disabled: !isFile },\n { key: 'convert', label: t('ctx.convert'), icon: '🔄', hidden: !single || !effectiveConvertUrl.value || !w, disabled: !isFile },\n { key: 'access', label: accessLabel, icon: '🔗', hidden: !single || !w },\n { key: 'details', label: t('ctx.details'), icon: 'ℹ', hidden: !any } /* koru:k1 */,\n { key: 'copy-id', label: copyIdLabel, icon: '🆔', hidden: !singleHasId, disabled: !singleHasId },\n { divider: true, key: 'sep1', label: '', hidden: !w },\n { key: 'rename', label: t('ctx.rename'), icon: '✎', hidden: !single || !w, disabled: !single },\n { key: 'cut', label: t('ctx.cut'), icon: '✂', hidden: !any || !w, disabled: !any },\n { key: 'copy', label: t('ctx.copy'), icon: '❐', hidden: !any, disabled: !any },\n { key: 'paste', label: t('ctx.paste'), icon: '📋', hidden: !w, disabled: !clipboard.value.mode },\n { divider: true, key: 'sep-meta', label: '', hidden: !singleHasId },\n { key: 'tags', label: tagsLabel, icon: '🏷', hidden: !singleHasId, disabled: !singleHasId },\n { divider: true, key: 'sep2', label: '', hidden: !w },\n { key: 'delete', label: t('ctx.delete'), icon: '🗑', danger: true, hidden: !any || !w, disabled: !any },\n ];\n}\n\n// toolbarActions — what the top toolbar shows. Mirrors the context menu so the\n// two stay identical for a selection; the empty/trash/virtual-root cases match\n// the context menu's special branches.\nconst toolbarActions = computed<ContextAction[]>(() => {\n const sel = selection.nodes.value;\n if (trashActive.value) {\n if (sel.length === 0) return [];\n return [\n { key: 'restore', label: t('ctx.restore'), icon: '↩' },\n { key: 'delete', label: t('ctx.delete_perm'), icon: '🗑', danger: true },\n ];\n }\n const trimmedPath = (currentPath.value ?? '').replace(/^\\/+|\\/+$/g, '');\n if (multiStorageRoot.value && trimmedPath === '') {\n return sel.length === 1 ? [{ key: 'open', label: t('ctx.open'), icon: '↗' }] : [];\n }\n if (sel.length === 0) return [];\n return selectionActionList(sel);\n});\n\nasync function onContextAction(action: ContextAction, targets: FileNode[]) {\n if (ctxMode.value === 'breadcrumb') {\n if (action.key === 'open') {\n void load(stripAdapter(breadcrumbCtxPath.value));\n } else if (action.key === 'copy-path') {\n await onCopyPath(breadcrumbCtxPath.value);\n }\n return;\n }\n await dispatchItemAction(action.key, targets);\n}\n\n// dispatchItemAction — unified handler for an action key on a target set. Both\n// the right-click menu (onContextAction) and the toolbar (onToolbarAction)\n// route here, so the two menus that now render the SAME list also behave the\n// same. (Toolbar \"Aç\" is the one deliberate exception — see onToolbarAction.)\nasync function dispatchItemAction(key: string, targets: FileNode[]) {\n switch (key) {\n case 'open':\n // Context-menu \"Aç\" launches the standalone fullscreen route\n // in a new tab. Double-click (openNode) opens the in-page\n // modal — two distinct affordances on purpose: quick peek vs\n // dedicated editing surface.\n if (targets[0]) openNodeInNewTab(targets[0]);\n break;\n case 'preview':\n if (targets[0]) previewNode(targets[0]);\n break;\n case 'download':\n if (targets[0]) downloadFile(targets[0]);\n break;\n case 'convert':\n if (targets[0]) openConvert(targets[0]);\n break;\n case 'share':\n if (targets[0]) openShare(targets[0]);\n break;\n case 'access':\n if (targets[0]) {\n permTarget.value = targets[0];\n showPerm.value = true;\n }\n break;\n case 'details' /* koru:k1 */:\n openInspector();\n break;\n case 'copy-id':\n if (targets[0] && typeof targets[0].id === 'number') {\n const id = targets[0].id;\n navigator.clipboard?.writeText(String(id)).then(\n () => flashToast(locale.value === 'en' ? `Node id ${id} copied` : `Node id ${id} kopyalandı`),\n () => flashToast(`#${id}`),\n );\n }\n break;\n case 'tags':\n if (targets[0]) openTagPickerFor(targets[0]);\n break;\n case 'rename':\n if (targets[0]) {\n renameTarget.value = targets[0];\n showRename.value = true;\n }\n break;\n case 'cut':\n clipboard.value = { mode: 'cut', items: targets, sourcePath: currentPath.value };\n flashToast('Kes → Yapıştır hazır');\n break;\n case 'copy':\n clipboard.value = { mode: 'copy', items: targets, sourcePath: currentPath.value };\n flashToast('Kopyala → Yapıştır hazır');\n break;\n case 'paste':\n await paste();\n break;\n case 'delete':\n showDelete.value = true;\n break;\n case 'restore':\n if (targets.length > 0) await restoreSelection(targets);\n break;\n case 'new-folder':\n showNewFolder.value = true;\n break;\n case 'duplicate':\n if (targets[0]) await duplicate(targets[0]);\n break;\n }\n}\n\nfunction cut() {\n if (selection.isEmpty.value) return;\n clipboard.value = { mode: 'cut', items: selection.nodes.value, sourcePath: currentPath.value };\n flashToast('Kesildi');\n}\n\nfunction copyToClipboard() {\n if (selection.isEmpty.value) return;\n clipboard.value = { mode: 'copy', items: selection.nodes.value, sourcePath: currentPath.value };\n flashToast('Kopyalandı');\n}\n\nasync function paste() {\n const cb = clipboard.value;\n if (!cb.mode || cb.items.length === 0) return;\n try {\n const items = cb.items.map((n) => n.path); // already qualified (adapter://rel)\n const sourceDir = cb.sourcePath || '';\n const sameDir = cb.mode === 'cut' && sourceDir === currentPath.value;\n if (sameDir) {\n flashToast('Aynı klasöre kesilemez');\n return;\n }\n\n if (cb.mode === 'cut') {\n const targetWire = qualify(currentPath.value);\n const originWire = qualify(sourceDir) || undefined;\n const { op } = await api.moveAsync(items, targetWire, originWire);\n registerMoveUndo(op.id, items, targetWire, originWire);\n pendingOps.register(op);\n flashToast('Taşıma kuyruğa alındı');\n } else {\n const { op } = await api.copy(items, qualify(currentPath.value));\n pendingOps.register(op);\n flashToast('Kopyalama kuyruğa alındı');\n }\n clipboard.value = { mode: null, items: [], sourcePath: null };\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: 'paste' } });\n }\n}\n\nasync function duplicate(n: FileNode) {\n try {\n const { op } = await api.copy([n.path], qualify(currentPath.value));\n pendingOps.register(op);\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: 'duplicate' } });\n }\n}\n\nfunction downloadFile(n: FileNode) {\n // Keep `<adapter>://<rel>` so backend resolves the right storage\n // (stripping it would default to the first storage, which 404s for\n // any non-default storage like S3/SFTP/WebDAV).\n const url = api.downloadUrl(n.path);\n window.open(url, '_blank');\n}\n\n// ------- Modals -------\n\nasync function submitNewFolder(name: string) {\n try {\n await api.newFolder(qualify(currentPath.value), name);\n showNewFolder.value = false;\n await load();\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: 'newfolder' } });\n }\n}\n\nasync function submitRename(name: string) {\n const target = renameTarget.value;\n if (!target) return;\n try {\n const dirWire = qualify(currentPath.value);\n const oldPath = target.path; // qualified\n const oldName = target.basename;\n await api.rename(dirWire, oldPath, name);\n showRename.value = false;\n renameTarget.value = null;\n await load();\n // Clean inverse: rename the new path back to the old basename.\n if (name && name !== oldName) {\n const newPath = wireJoin(wireParent(oldPath), name);\n undoToast(t('toast.renamed'), async () => {\n await api.rename(dirWire, newPath, oldName);\n });\n }\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: 'rename' } });\n }\n}\n\nasync function confirmDelete() {\n // In the trash view, items are already soft-deleted. Permanent removal is\n // admin-only (and the backend auto-purges after the retention window), so\n // offer Restore here rather than a delete that would just re-trash a path.\n if (trashMode.value) {\n showDelete.value = false;\n flashToast('Çöpteki öğeler saklama süresi sonunda otomatik silinir. Kalıcı silme yönetici panelinden yapılır.');\n return;\n }\n const targets = selection.nodes.value;\n const items = targets.map((n) => n.path);\n if (items.length === 0) {\n showDelete.value = false;\n return;\n }\n // Trash-delete is invertible via node-id restore — but only when EVERY\n // selected node carries a backend id and the restore endpoint exists.\n // A partial-undo offer would be a lie, so all-or-nothing.\n const nodeIds = targets\n .map((n) => (n as { id?: number }).id)\n .filter((x): x is number => typeof x === 'number');\n const restoreUndo =\n api.endpoints.trashRestore && nodeIds.length === targets.length\n ? async () => {\n const { restored } = await api.restoreIds(nodeIds);\n if (restored === 0) throw new Error('restore failed');\n }\n : null;\n try {\n if (api.endpoints.deleteAsync) {\n const { op } = await api.deleteAsync(items, qualify(currentPath.value));\n if (restoreUndo) {\n opUndo.set(op.id, { message: t('toast.trashed'), fn: restoreUndo });\n }\n pendingOps.register(op);\n flashToast('Silme kuyruğa alındı');\n } else {\n await api.deleteItems(qualify(currentPath.value), items);\n await load();\n if (restoreUndo) undoToast(t('toast.trashed'), restoreUndo);\n }\n showDelete.value = false;\n selection.clear();\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: 'delete' } });\n }\n}\n\nfunction openShare(n: FileNode) {\n shareTarget.value = n;\n activeShare.value = null;\n showShare.value = true;\n}\n\nfunction openConvert(n: FileNode) {\n convertTarget.value = n;\n showConvert.value = true;\n}\n\nfunction onConvertDone(name: string) {\n flashToast(locale.value === 'en' ? `Converted → ${name}` : `Dönüştürüldü → ${name}`);\n void load();\n}\n\nasync function submitShare(payload: {\n password: boolean;\n expires_at: string | null;\n max_downloads: number | null;\n}) {\n const target = shareTarget.value;\n if (!target) return;\n try {\n const { share } = await api.createShare({\n path: target.path, // qualified `<adapter>://<rel>`\n password: payload.password,\n expires_at: payload.expires_at,\n max_downloads: payload.max_downloads,\n });\n activeShare.value = share;\n emit('share-created', { path: target.path, url: share.url, pin: share.password_pin ?? null });\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: 'share' } });\n }\n}\n\nfunction closeShare() {\n showShare.value = false;\n shareTarget.value = null;\n activeShare.value = null;\n}\n\n// ------- Upload -------\n\nfunction triggerUpload() {\n if (!canWriteHere.value) {\n flashToast(locale.value === 'en' ? 'Read-only here' : 'Burada yazma yetkiniz yok');\n return;\n }\n fileInputEl.value?.click();\n}\n\nfunction onFilePicked(ev: Event) {\n const input = ev.target as HTMLInputElement;\n const list = input.files ? Array.from(input.files) : [];\n input.value = '';\n void uploadFiles(list);\n}\n\nasync function uploadFiles(list: File[]) {\n if (list.length === 0) return;\n const canChunk = !!(api.endpoints.uploadInit && api.endpoints.uploadFinalize);\n for (const f of list) {\n // Chunked (S3 multipart) only when the endpoints exist AND the file is\n // large. If chunked isn't viable (storage has no multipart support —\n // e.g. the local driver — or init errors out) fall back to the legacy\n // single-POST upload, which works for any storage / file size.\n if (canChunk && f.size >= 10 * 1024 * 1024) {\n if (await chunkedUpload(f)) continue;\n }\n await legacyUpload(f);\n }\n await load();\n}\n\nasync function legacyUpload(file: File) {\n // Register a progress row so the corner badge tracks the upload — large files\n // fall back here from the chunked path, and previously showed no progress at\n // all (the chunked placeholder was removed on init failure and the legacy\n // POST tracked nothing, so the badge vanished mid-upload).\n const id = crypto.randomUUID();\n const target = qualify(currentPath.value);\n uploadJobs.value = [\n ...uploadJobs.value,\n { id, file, path: target, totalBytes: file.size, uploadedBytes: 0, percent: 0, status: 'uploading', cancel() {} },\n ];\n const patch = (p: Partial<UploadJob>) => {\n const idx = uploadJobs.value.findIndex((j) => j.id === id);\n if (idx === -1) return;\n const next = [...uploadJobs.value];\n next[idx] = { ...next[idx], ...p };\n uploadJobs.value = next;\n };\n try {\n await api.uploadMultipart(target, [file], (percent) => {\n patch({ percent, uploadedBytes: Math.round((percent / 100) * file.size) });\n emit('upload-progress', { uploadId: id, percent, done: percent >= 100 });\n });\n patch({ percent: 100, uploadedBytes: file.size, status: 'done' });\n emit('upload-progress', { uploadId: id, percent: 100, done: true });\n } catch (err) {\n patch({ status: 'error' });\n emit('error', {\n message: (err as Error).message,\n context: { op: 'upload', file: file.name },\n });\n }\n}\n\n/**\n * Attempt an S3 multipart (chunked) upload. Returns `true` on success,\n * `false` when the storage can't do multipart (local driver, init 4xx/5xx)\n * so the caller can transparently fall back to the legacy single-POST\n * upload. On failure the progress placeholder is removed — no stuck error\n * row, no error toast, because the fallback path will report any real error.\n */\nasync function chunkedUpload(file: File): Promise<boolean> {\n // Register the progress row LAZILY — only once init succeeded and bytes are\n // actually moving. A doomed init (local driver / 4xx) then shows no badge at\n // all, so the legacy fallback's own badge is the only one the user sees (no\n // appear-then-vanish flicker).\n const id = crypto.randomUUID();\n let registered = false;\n try {\n await chunked.uploadFile({\n path: qualify(currentPath.value),\n file,\n onProgress: (job) => {\n if (!registered) {\n if (job.status !== 'uploading' && job.uploadedBytes <= 0) return;\n uploadJobs.value = [...uploadJobs.value, { ...job, id } as UploadJob];\n registered = true;\n } else {\n const idx = uploadJobs.value.findIndex((j) => j.id === id);\n if (idx !== -1) {\n const next = [...uploadJobs.value];\n next[idx] = { ...job, id } as UploadJob;\n uploadJobs.value = next;\n }\n }\n emit('upload-progress', {\n uploadId: job.uploadId ?? id,\n percent: job.percent,\n done: job.status === 'done',\n });\n },\n });\n return true;\n } catch {\n if (registered) uploadJobs.value = uploadJobs.value.filter((j) => j.id !== id);\n return false;\n }\n}\n\nconst dragCounter = ref(0);\nconst dragOver = ref(false);\n\n/**\n * isExternalFileDrag — `true` only when the user is dragging files\n * INTO the page from the OS (file picker, finder, etc.). Filters out:\n * - internal row drags (FE_DND_MIME present)\n * - browser image drags (`<img draggable=true>` on this page or\n * across pages). HTML5 `Files` type is leaky — it appears when\n * dragging any image element even though no real file is moving;\n * `dataTransfer.items[*].kind === 'file'` is the canonical signal\n * for an actual OS file.\n */\nfunction isExternalFileDrag(ev: DragEvent): boolean {\n const dt = ev.dataTransfer;\n if (!dt) return false;\n if (dt.types && dt.types.includes(FE_DND_MIME)) return false;\n // Some browsers expose `items` early in the drag, others only on\n // drop. When `items` is available we use it as the authoritative\n // signal — `kind === 'file'` means a real OS file. When unavailable\n // (Firefox during dragover sometimes returns 0 items), fall back to\n // the legacy `Files` type check.\n if (dt.items && dt.items.length > 0) {\n let hasFile = false;\n for (const it of Array.from(dt.items)) {\n if (it.kind === 'file') {\n hasFile = true;\n break;\n }\n }\n return hasFile;\n }\n return dt.types ? dt.types.includes('Files') : false;\n}\n\nfunction onDragEnter(ev: DragEvent) {\n if (!isExternalFileDrag(ev)) return;\n ev.preventDefault();\n dragCounter.value++;\n dragOver.value = true;\n}\nfunction onDragLeave() {\n dragCounter.value = Math.max(0, dragCounter.value - 1);\n if (dragCounter.value === 0) dragOver.value = false;\n}\nfunction onDragOver(ev: DragEvent) {\n if (isExternalFileDrag(ev)) {\n ev.preventDefault();\n }\n}\nfunction onDropUpload(ev: DragEvent) {\n // Internal row drag — nothing to do here, the row drop handler\n // in GridView/ListView already resolved the move.\n if (ev.dataTransfer?.types.includes(FE_DND_MIME)) {\n dragCounter.value = 0;\n dragOver.value = false;\n return;\n }\n // Browser-internal image drag without real files — bail before\n // we accidentally synthesise an upload from a 0-length file list\n // (some browsers populate `files` with zero-byte placeholders).\n if (!isExternalFileDrag(ev)) {\n dragCounter.value = 0;\n dragOver.value = false;\n return;\n }\n ev.preventDefault();\n dragCounter.value = 0;\n dragOver.value = false;\n // RBAC: block drag-drop upload where the user can't write.\n if (!canWriteHere.value) {\n flashToast(locale.value === 'en' ? 'Read-only here' : 'Burada yazma yetkiniz yok');\n return;\n }\n const list = ev.dataTransfer?.files ? Array.from(ev.dataTransfer.files) : [];\n if (list.length === 0) return;\n void uploadFiles(list);\n}\n\nfunction onWindowDragOver(ev: DragEvent) {\n if (ev.dataTransfer?.types.includes('Files')) ev.preventDefault();\n}\nfunction onWindowDrop(ev: DragEvent) {\n const root = rootEl.value;\n const target = ev.target as Node | null;\n if (root && target && !root.contains(target)) {\n ev.preventDefault();\n }\n}\nonMounted(() => {\n window.addEventListener('dragover', onWindowDragOver);\n window.addEventListener('drop', onWindowDrop);\n});\nonBeforeUnmount(() => {\n window.removeEventListener('dragover', onWindowDragOver);\n window.removeEventListener('drop', onWindowDrop);\n window.removeEventListener('hashchange', onHashChange);\n});\n\nconst clippedPaths = computed<Set<string>>(() => {\n if (clipboard.value.mode !== 'cut') return new Set();\n return new Set(clipboard.value.items.map((n) => n.path));\n});\n\n// --------------------------------------------------------------------\n// Item drag&drop move\n// --------------------------------------------------------------------\n\nconst FE_DND_MIME = 'application/x-brf-files';\n\nfunction onItemDragStart(node: FileNode, ev: DragEvent) {\n if (!ev.dataTransfer) return;\n if (node.basename === '.trash') {\n ev.preventDefault();\n return;\n }\n if (!selection.has(node.path)) {\n selection.click(node.path);\n }\n const items = selection.nodes.value\n .filter((n) => !clippedPaths.value.has(n.path))\n .filter((n) => n.basename !== '.trash')\n .map((n) => ({ path: n.path, basename: n.basename, type: n.type })); // qualified\n ev.dataTransfer.setData(FE_DND_MIME, JSON.stringify(items));\n ev.dataTransfer.setData('text/plain', items.map((i) => i.path).join('\\n'));\n ev.dataTransfer.effectAllowed = 'move';\n}\n\nasync function moveSourcesAsync(sources: string[], targetDir: string, opLabel: string): Promise<void> {\n try {\n const originWire = qualify(currentPath.value);\n if (api.endpoints.moveAsync) {\n const { op } = await api.moveAsync(sources, targetDir, originWire);\n registerMoveUndo(op.id, sources, targetDir, originWire);\n pendingOps.register(op);\n flashToast('Taşıma kuyruğa alındı');\n } else {\n await api.move(originWire, sources, targetDir);\n await load();\n // Sync move (no async endpoint): offer the reverse move right away.\n const movedPaths = sources.map((p) => wireJoin(targetDir, wireBasename(p)));\n undoToast(t('toast.moved'), async () => {\n await api.move(targetDir, movedPaths, originWire);\n });\n }\n selection.clear();\n } catch (err) {\n emit('error', { message: (err as Error).message, context: { op: opLabel, targetDir } });\n }\n}\n\nasync function onItemDropInto(target: FileNode, ev: DragEvent) {\n if (target.type !== 'dir') return;\n const raw = ev.dataTransfer?.getData(FE_DND_MIME);\n if (!raw) return;\n let items: Array<{ path: string }> = [];\n try {\n items = JSON.parse(raw);\n } catch {\n return;\n }\n if (items.length === 0) return;\n\n const targetDir = target.path; // qualified\n const sources = items\n .map((i) => i.path)\n .filter((p) => p && p !== targetDir && !targetDir.startsWith(p + '/'));\n if (sources.length === 0) {\n flashToast('Aynı klasöre taşınamaz');\n return;\n }\n await moveSourcesAsync(sources, targetDir, 'move-dnd');\n}\n\nasync function onCrumbDropInto(adapterPath: string, ev: DragEvent) {\n const raw = ev.dataTransfer?.getData(FE_DND_MIME);\n if (!raw) return;\n let items: Array<{ path: string }> = [];\n try {\n items = JSON.parse(raw);\n } catch {\n return;\n }\n if (items.length === 0) return;\n\n const targetDir = adapterPath; // already qualified by breadcrumb\n const sources = items\n .map((i) => i.path)\n .filter((p) => p && p !== targetDir && !targetDir.startsWith(p + '/'));\n if (sources.length === 0) return;\n await moveSourcesAsync(sources, targetDir, 'move-dnd-crumb');\n}\n\nfunction onCancelUpload(job: UploadJob) {\n job.cancel();\n}\n\nfunction onDismissUpload(job: UploadJob) {\n uploadJobs.value = uploadJobs.value.filter((j) => j.id !== job.id);\n}\n\n// ------- Breadcrumb -------\n\nfunction onNavigate(adapterPath: string) {\n // Multi-storage emits empty string for the global \"/\" crumb. The\n // load() function recognises that as the storage-list virtual root.\n if (multiStorageRoot.value && !adapterPath) {\n void load('');\n return;\n }\n if (multiStorageRoot.value) {\n void load(wireToVirtual(adapterPath));\n return;\n }\n void load(stripAdapter(adapterPath));\n}\n\nasync function onCopyPath(adapterPath: string) {\n try {\n await navigator.clipboard.writeText(adapterPath);\n flashToast(t('breadcrumb.copy_path'));\n } catch {\n /* no-op */\n }\n}\n\n// Sync auth-headers builder for PreviewModal — fetches against the\n// OnlyOffice config endpoint and the saveText endpoint need real\n// headers, not promises. Function-token bearers will use the cached\n// token; first-call resolution happens via the async path elsewhere.\nfunction buildAuthHeaders(extra: Record<string, string> = {}) {\n return api.authHeadersSync({ ...extra });\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"fe\"\n :class=\"{\n 'fe--theme-light': config.theme === 'light',\n 'fe--theme-dark': config.theme === 'dark',\n 'fe--is-dragover': dragOver,\n 'fe--density-compact': density === 'compact' /* cila:a density */,\n 'fe--narrow': isNarrow /* bag:b4 */,\n }\"\n tabindex=\"-1\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDropUpload\"\n @contextmenu=\"onContextCanvas\"\n >\n <Toolbar\n ref=\"toolbarRef\"\n :view-mode=\"viewMode\"\n :search-query=\"searchQuery\"\n :trash-active=\"trashActive\"\n :actions=\"toolbarActions\"\n :selection-mode=\"selectionMode\"\n :paste-enabled=\"!!clipboard.mode\"\n :convert-enabled=\"!!effectiveConvertUrl\"\n :can-go-up=\"canGoUp\"\n :at-virtual-root=\"atVirtualRoot\"\n :can-write=\"canWriteHere\"\n :locale=\"locale\"\n :narrow=\"isNarrow /* bag:b4 */\"\n :theme=\"config.theme || 'auto' /* bag:b4 */\"\n :inspector-open=\"showInspector /* koru:k1 */\"\n @toggle-inspector=\"toggleInspector /* koru:k1 */\"\n @update:view-mode=\"viewMode = $event\"\n @update:search-query=\"searchQuery = $event\"\n @update:density=\"density = $event\"\n @new-folder=\"showNewFolder = true\"\n @upload=\"triggerUpload\"\n @refresh=\"() => load()\"\n @go-up=\"goUp\"\n @action=\"onToolbarAction\"\n @open-recents=\"showRecents = true\"\n />\n\n <Breadcrumb\n :dirname=\"dirname\"\n :adapter=\"adapter\"\n :root-label=\"adapter\"\n :locale=\"locale\"\n :multi-storage-root=\"multiStorageRoot\"\n :root-path=\"rootPathProp\"\n @navigate=\"onNavigate\"\n @copy-path=\"onCopyPath\"\n @crumb-context=\"onCrumbContext\"\n @crumb-drop=\"onCrumbDropInto\"\n />\n\n <!-- Live presence: who else is viewing this folder (empty → nothing shown).\n When the live socket is unavailable the same strip carries a small\n degraded-connection badge instead (presence is empty in fallback);\n a healthy connection shows nothing extra. -->\n <div v-if=\"presenceUsers.length || realtimeDegraded\" class=\"fe__presence\">\n <PresenceBar v-if=\"presenceUsers.length\" :users=\"presenceUsers\" :locale=\"locale\" />\n <span\n v-if=\"realtimeDegraded\"\n class=\"fe-connbadge\"\n role=\"status\"\n :title=\"t('conn.tooltip')\"\n >\n <span class=\"fe-connbadge__dot\" aria-hidden=\"true\"></span>\n {{ t('conn.offline') }}\n </span>\n </div>\n\n <!-- koru:k1 — fe__main lays the listing body and the inspector panel out\n as flex siblings (row). Without the inspector open it is visually\n identical to the previous direct-child fe__body. -->\n <div class=\"fe__main\">\n <div class=\"fe__body\" @click.self=\"selection.clear()\">\n <!-- Initial load: skeleton ghosts (view-mode aware) instead of an\n empty/\"no files\" flash. Only when there's nothing yet — navigation\n keeps the current list, exactly as before. -->\n <div v-if=\"loading && files.length === 0\" class=\"fe__skeleton\" role=\"status\">\n <span class=\"fe-sr-only\">{{ t('loading') }}</span>\n <div v-if=\"viewMode === 'grid'\" class=\"fe-skel-grid\" aria-hidden=\"true\">\n <div v-for=\"i in 8\" :key=\"i\" class=\"fe-skel-card\">\n <div class=\"fe-skel fe-skel--thumb\"></div>\n <div class=\"fe-skel fe-skel--label\"></div>\n </div>\n </div>\n <div v-else class=\"fe-skel-list\" aria-hidden=\"true\">\n <div v-for=\"i in 8\" :key=\"i\" class=\"fe-skel-row\">\n <div class=\"fe-skel fe-skel--icon\"></div>\n <div class=\"fe-skel fe-skel--name\"></div>\n <div class=\"fe-skel fe-skel--size\"></div>\n <div class=\"fe-skel fe-skel--date\"></div>\n </div>\n </div>\n </div>\n <!-- Dead deep link (404) or RBAC-hidden dir (403, shown identically):\n a dedicated state instead of a misleading \"this folder is empty\". -->\n <div v-else-if=\"notFoundPath\" class=\"fe-state\">\n <svg\n class=\"fe-state__art\"\n viewBox=\"0 0 120 100\"\n width=\"110\"\n height=\"92\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 36v42a6 6 0 0 0 6 6h72a6 6 0 0 0 6-6V44a6 6 0 0 0-6-6H62l-9-10H24a6 6 0 0 0-6 6z\" />\n <path d=\"M52 55c0-4.6 3.6-8 8-8s8 3.4 8 8c0 5.5-8 4.8-8 11\" />\n <circle cx=\"60\" cy=\"73\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n <p class=\"fe-state__title\">{{ t('notFound.title') }}</p>\n <p class=\"fe-state__path\">{{ notFoundPath }}</p>\n <p class=\"fe-state__hint\">{{ t('notFound.desc') }}</p>\n <div class=\"fe-state__actions\">\n <button type=\"button\" class=\"fe-btn\" @click=\"leaveNotFound\">\n {{ t('notFound.goRoot') }}\n </button>\n </div>\n </div>\n <!-- Listing failed (network / 5xx) with nothing else to show: retryable\n error state in the same visual language. -->\n <div v-else-if=\"loadError && files.length === 0\" class=\"fe-state\">\n <svg\n class=\"fe-state__art\"\n viewBox=\"0 0 120 100\"\n width=\"110\"\n height=\"92\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"60\" cy=\"50\" r=\"28\" />\n <path d=\"M60 36v18\" />\n <circle cx=\"60\" cy=\"63\" r=\"1.8\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M24 88h72\" stroke-dasharray=\"3 5\" />\n </svg>\n <p class=\"fe-state__title\">{{ t('error.title') }}</p>\n <p class=\"fe-state__hint\">{{ loadError }}</p>\n <div class=\"fe-state__actions\">\n <button type=\"button\" class=\"fe-btn fe-btn--primary\" @click=\"retryLoad\">\n {{ t('error.retry') }}\n </button>\n </div>\n </div>\n <!-- Search with zero hits — its own message, not \"folder is empty\". -->\n <div v-else-if=\"!loading && files.length === 0 && searchQuery\" class=\"fe-state\">\n <svg\n class=\"fe-state__art\"\n viewBox=\"0 0 120 100\"\n width=\"110\"\n height=\"92\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"52\" cy=\"44\" r=\"22\" />\n <path d=\"M68 61l20 20\" />\n <path d=\"M46 38l12 12M58 38l-12 12\" />\n </svg>\n <p class=\"fe-state__title\">{{ t('empty.search.title') }}</p>\n <p class=\"fe-state__hint\">{{ t('empty.search.hint') }}</p>\n </div>\n <!-- Empty trash view. -->\n <div v-else-if=\"!loading && files.length === 0 && trashMode\" class=\"fe-state\">\n <svg\n class=\"fe-state__art\"\n viewBox=\"0 0 120 100\"\n width=\"110\"\n height=\"92\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M38 34l4 48a6 6 0 0 0 6 5.6h24a6 6 0 0 0 6-5.6l4-48\" />\n <path d=\"M32 34h56\" />\n <path d=\"M50 34v-6a6 6 0 0 1 6-6h8a6 6 0 0 1 6 6v6\" />\n <path d=\"M52 44v32M60 44v32M68 44v32\" opacity=\"0.5\" />\n </svg>\n <p class=\"fe-state__title\">{{ t('empty.trash.title') }}</p>\n </div>\n <!-- Loaded, zero files, no search: the real empty-folder state. The\n upload affordances follow write permission (RBAC viewers only get\n the title). -->\n <div v-else-if=\"!loading && files.length === 0\" class=\"fe-state\">\n <svg\n class=\"fe-state__art\"\n viewBox=\"0 0 120 100\"\n width=\"110\"\n height=\"92\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 36v42a6 6 0 0 0 6 6h72a6 6 0 0 0 6-6V44a6 6 0 0 0-6-6H62l-9-10H24a6 6 0 0 0-6 6z\" />\n <g v-if=\"emptyCanUpload\">\n <path d=\"M60 50v14\" stroke-dasharray=\"3 4\" />\n <path d=\"M53 59l7 8 7-8\" />\n </g>\n </svg>\n <p class=\"fe-state__title\">{{ t('empty.folder') }}</p>\n <p v-if=\"emptyCanUpload\" class=\"fe-state__hint\">{{ t('empty.hint') }}</p>\n <div v-if=\"emptyCanUpload\" class=\"fe-state__actions\">\n <button type=\"button\" class=\"fe-btn fe-btn--primary\" @click=\"triggerUpload\">\n {{ t('empty.upload') }}\n </button>\n </div>\n </div>\n <ListView\n v-else-if=\"viewMode === 'list'\"\n :files=\"files\"\n :selected=\"selection.selected.value\"\n :clipped=\"clippedPaths\"\n :show-parent-path=\"!!searchQuery\"\n :locale=\"locale\"\n :loading=\"loading\"\n :starred-ids=\"starredIds\"\n :api-base=\"props.config.apiBase ?? ''\"\n :auth-headers=\"() => buildAuthHeaders()\"\n @click-row=\"(n, m) => selection.click(n.path, m)\"\n @dbl-row=\"openNode\"\n @context-row=\"onContextTarget\"\n @item-drag-start=\"onItemDragStart\"\n @item-drop-into=\"onItemDropInto\"\n @star-change=\"onStarChange\"\n />\n <GridView\n v-else\n :files=\"files\"\n :selected=\"selection.selected.value\"\n :clipped=\"clippedPaths\"\n :show-parent-path=\"!!searchQuery\"\n :locale=\"locale\"\n :loading=\"loading\"\n :thumb-src=\"thumbs.src\"\n @click-card=\"(n, m) => selection.click(n.path, m)\"\n @dbl-card=\"openNode\"\n @context-card=\"onContextTarget\"\n @item-drag-start=\"onItemDragStart\"\n @item-drop-into=\"onItemDropInto\"\n />\n </div>\n\n <!-- koru:k1 — inspector (details) panel; v-if keeps the closed state\n free of any DOM. Narrow mode renders it as a full-size overlay. -->\n <InspectorPanel\n v-if=\"showInspector\"\n :api=\"api\"\n :nodes=\"selection.nodes.value\"\n :dir-label=\"inspectorDirLabel\"\n :dir-count=\"files.length\"\n :dir-perm=\"dirPerm\"\n :locale=\"locale\"\n :narrow=\"isNarrow\"\n :thumb-src=\"thumbs.src\"\n @close=\"closeInspector\"\n @manage-permissions=\"onInspectorManage\"\n @toast=\"flashToast\"\n @changed=\"() => load()\"\n />\n </div>\n <!-- /koru:k1 fe__main -->\n\n <div v-if=\"dragOver\" class=\"fe__dragover\">\n <div class=\"fe__dragover-card\">\n <span class=\"fe-icon\">⬆</span>\n <p>Dosyaları buraya bırak</p>\n </div>\n </div>\n\n <UploadProgress\n :jobs=\"uploadJobs\"\n :locale=\"locale\"\n @cancel=\"onCancelUpload\"\n @dismiss=\"onDismissUpload\"\n />\n\n <PendingOpsTray\n :ops=\"pendingOps.ops.value\"\n :locale=\"locale\"\n @dismiss=\"(id) => pendingOps.dismiss(id)\"\n />\n\n <!-- bag:b4 — narrow-mode upload FAB (hidden in trash / read-only /\n virtual root; PendingOpsTray+UploadProgress shift up via CSS). -->\n <button\n v-if=\"isNarrow && emptyCanUpload\"\n type=\"button\"\n class=\"fe-fab\"\n :title=\"t('toolbar.upload')\"\n :aria-label=\"t('toolbar.upload')\"\n @click=\"triggerUpload\"\n >\n <svg\n class=\"fe-ficon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M12 5v14M5 12h14\" />\n </svg>\n </button>\n\n <ContextMenu\n ref=\"ctxRef\"\n :locale=\"locale\"\n :theme=\"config.theme || 'auto'\"\n :sheet=\"isCoarse /* bag:b4 */\"\n :actions=\"contextActions\"\n @select=\"onContextAction\"\n />\n\n <NewFolderModal\n :open=\"showNewFolder\"\n :locale=\"locale\"\n @close=\"showNewFolder = false\"\n @submit=\"submitNewFolder\"\n />\n <RenameModal\n :open=\"showRename\"\n :locale=\"locale\"\n :current-name=\"renameTarget?.basename || ''\"\n @close=\"showRename = false\"\n @submit=\"submitRename\"\n />\n <DeleteConfirmModal\n :open=\"showDelete\"\n :locale=\"locale\"\n :count=\"selection.size.value\"\n @close=\"showDelete = false\"\n @confirm=\"confirmDelete\"\n />\n <ShareModal\n :open=\"showShare\"\n :locale=\"locale\"\n :share=\"activeShare\"\n @close=\"closeShare\"\n @submit=\"submitShare\"\n @toast=\"flashToast\"\n />\n <PreviewModal\n :open=\"showPreview\"\n :locale=\"locale\"\n :file=\"previewTarget\"\n :theme=\"config.theme || 'auto'\"\n :preview-url=\"(p) => api.previewUrl(p)\"\n :download-url=\"(p) => api.downloadUrl(p)\"\n :only-office-base=\"effectiveOnlyOfficeBase\"\n :only-office-config-endpoint=\"effectiveOnlyOfficeConfigEndpoint\"\n :save-text-endpoint=\"api.endpoints.saveText || null\"\n :open-mode=\"previewMode\"\n :auth-headers=\"() => buildAuthHeaders({ 'Content-Type': 'application/json' })\"\n :auth-credentials=\"api.credentialsMode()\"\n :drawio-url=\"effectiveDrawioUrl\"\n :pdf-worker-url=\"props.config.pdfWorkerUrl || null\"\n :pdf-save-url=\"props.config.pdfSaveUrl || null\"\n :viewer-base-url=\"props.config.viewerBaseUrl || null\"\n @close=\"showPreview = false\"\n />\n <ConvertModal\n v-if=\"showConvert && convertTarget && effectiveConvertUrl\"\n :convert-url=\"effectiveConvertUrl\"\n :file-name=\"convertTarget?.basename || convertTarget?.path || ''\"\n :fetch-bytes=\"() => api.fetchArrayBuffer(convertTarget?.path ?? '')\"\n :upload=\"(f) => api.uploadMultipart(qualify(currentPath), [f]).then(() => {})\"\n @close=\"showConvert = false\"\n @done=\"onConvertDone\"\n />\n <PermissionsModal\n v-if=\"showPerm && permTarget\"\n :api=\"api\"\n :path=\"permTarget.path\"\n :is-dir=\"permTarget.type === 'dir'\"\n :size=\"typeof permTarget.size === 'number' ? permTarget.size : undefined\"\n :locale=\"locale === 'en' ? 'en' : 'tr'\"\n @close=\"showPerm = false\"\n />\n\n <!-- Recently-opened tray. Anchored to the toolbar trigger via fixed\n position; click the backdrop or any entry to dismiss.\n `.fe` + theme class keeps the dark/light cascade matching the\n host shell — without them the popup floats outside the\n FileExplorer root and falls back to :root light defaults. -->\n <transition name=\"fe-modal\">\n <div\n v-if=\"showRecents\"\n class=\"fe fe-modal__backdrop fe-recents__backdrop\"\n :class=\"{\n 'fe--theme-light': config.theme === 'light',\n 'fe--theme-dark': config.theme === 'dark',\n }\"\n @click=\"showRecents = false\"\n >\n <div class=\"fe-recents__panel\" @click.stop>\n <div class=\"fe-recents__header\">\n <strong>{{ locale === 'en' ? 'Recently opened' : 'Son açılanlar' }}</strong>\n <button class=\"fe-recents__close\" aria-label=\"Close\" @click=\"showRecents = false\">×</button>\n </div>\n <RecentlyOpened\n :api-base=\"props.config.apiBase ?? ''\"\n :auth-headers=\"() => buildAuthHeaders()\"\n :limit=\"20\"\n :refresh-key=\"recentRefreshKey\"\n @open=\"onRecentOpen\"\n @error=\"(msg: string) => emit('error', { message: msg, context: { op: 'recents' } })\"\n />\n </div>\n </div>\n </transition>\n\n <!-- Tag editor — opened from the context menu via Etiketler. -->\n <transition name=\"fe-modal\">\n <div\n v-if=\"showTagPicker && tagPickerNode && typeof tagPickerNode.id === 'number'\"\n class=\"fe-modal__backdrop\"\n @click=\"showTagPicker = false\"\n >\n <div class=\"fe-modal__card fe-modal__card--md\" @click.stop>\n <header class=\"fe-modal__head\">\n <h2 class=\"fe-modal__title\">\n {{ locale === 'en' ? 'Tags' : 'Etiketler' }} — {{ tagPickerNode.basename }}\n </h2>\n <button class=\"fe-modal__close\" aria-label=\"Close\" @click=\"showTagPicker = false\">×</button>\n </header>\n <div class=\"fe-modal__body\">\n <TagPicker\n :node-id=\"tagPickerNode.id\"\n :api-base=\"props.config.apiBase ?? ''\"\n :auth-headers=\"() => buildAuthHeaders()\"\n @error=\"(msg: string) => emit('error', { message: msg, context: { op: 'tags' } })\"\n />\n </div>\n </div>\n </div>\n </transition>\n\n <!-- cila:c wiring — command palette (Ctrl/Cmd+K) + shortcuts help (?) -->\n <CommandPalette\n :open=\"showPalette\"\n :locale=\"locale\"\n :files=\"files\"\n :view-mode=\"viewMode\"\n :can-write=\"canWriteHere && !atVirtualRoot && !trashActive\"\n :can-go-up=\"canGoUp\"\n :global-search=\"paletteGlobalSearch\"\n @close=\"showPalette = false\"\n @open-hit=\"openSearchHit\"\n @open-node=\"openNode\"\n @navigate=\"(p: string) => load(p)\"\n @new-folder=\"showNewFolder = true\"\n @upload=\"triggerUpload\"\n @toggle-view=\"viewMode = viewMode === 'list' ? 'grid' : 'list'\"\n @open-trash=\"loadTrash\"\n @refresh=\"() => load()\"\n @go-up=\"goUp\"\n />\n <ShortcutsHelp\n :open=\"showShortcutsHelp\"\n :locale=\"locale\"\n @close=\"showShortcutsHelp = false\"\n />\n <!-- /cila:c wiring -->\n\n <input\n ref=\"fileInputEl\"\n type=\"file\"\n multiple\n class=\"fe__file-input\"\n @change=\"onFilePicked\"\n />\n\n <transition name=\"fe-toast\">\n <div\n v-if=\"toast\"\n class=\"fe-toast\"\n :class=\"{ 'fe-toast--action': !!toast.actionLabel }\"\n role=\"status\"\n @click=\"dismissToast\"\n >\n <span class=\"fe-toast__msg\">{{ toast.message }}</span>\n <button\n v-if=\"toast.actionLabel && toast.action\"\n type=\"button\"\n class=\"fe-toast__action\"\n @click.stop=\"runToastAction\"\n >{{ toast.actionLabel }}</button>\n </div>\n </transition>\n </div>\n</template>\n\n<style src=\"./styles/variables.css\"></style>\n<style src=\"./styles/base.css\"></style>\n"],"names":["isExternalUsable","s","resolveEndpoints","config","base","derive","path","autoSegment","manager","resolveToken","t","out","normalizeAuth","auth","useFileApi","endpoints","authConf","authHeaders","extra","h","token","creds","authHeadersSync","credentialsMode","statusMessage","status","tr","e","jsonFetch","url","init","headers","res","text","err","permissionsUrl","sub","listPermissions","resolveEmail","email","searchUsers","q","addPermission","body","updatePermission","id","level","deletePermission","invitePermission","shareMail","qs","params","sp","k","v","managerUrl","action","sep","index","search","filter","globalSearch","query","opts","data","subfolders","newFolder","name","rename","item","move","items","target","p","deleteItems","copy","source","moveAsync","sourceDir","deleteAsync","restore","listTrash","storageName","restoreIds","ids","restored","uploadMultipart","files","onProgress","fd","f","resolve","reject","xhr","ev","downloadUrl","previewUrl","fetchBlob","blob","mime","fetchArrayBuffer","limits","capabilities","createShare","payload","listShares","revokeShare","uuid","archiveList","archiveExtract","members","archiveAdd","versionsUrl","listVersions","nodeId","restoreVersion","versionId","snapshotCurrent","snapshotVersion","wsTicket","useUploadChunked","api","DEFAULT_CHUNK","DEFAULT_PARALLEL","uploadFile","chunkSize","parallel","job","cancelled","aborters","a","report","_a","actualChunk","partProgress","completed","cursor","uploadPart","entry","start","end","ctl","prev","delta","etag","blobSize","MAX_RETRIES","uploadPartWithRetry","attempt","leaked","delay","r","worker","workers","i","b","final","asError","_b","useSelection","selected","ref","anchor","click","mod","list","aIdx","n","bIdx","lo","hi","next","clear","selectAll","has","add","remove","size","computed","isEmpty","nodes","SHORTCUTS","useKeyboardShortcuts","rootEl","handlers","onKey","ctrl","onMounted","onBeforeUnmount","en","messages","useLocale","localeRef","lookup","code","key","vars","raw","acc","formatSize","bytes","units","div","val","nodeDisplayName","node","m","POLL_MS","RETAIN_MS","normalizeOp","num","vals","str","rawStatus","sources","opType","usePendingOps","ops","announced","settledAt","firstPollDone","hasActive","o","timer","startPolling","poll","stopPolling","incoming","op","localIds","visibleIncoming","visibleIds","local","merged","now","after","at","register","dismiss","PING_INTERVAL_MS","MAX_BACKOFF_MS","RealtimeClient","__publicField","file","ticket","ws","msg","active","obj","RELOAD_DEBOUNCE_MS","POLL_INTERVAL_MS","useRealtime","presenceUsers","connected","degraded","client","pendingSubscribe","reloadTimer","pollTimer","debouncedReload","onPresence","onFallback","c","subscribe","wire","setFocus","stop","MAX_CACHED","useThumbs","apiBase","urls","order","failed","pending","resolveUrl","src","got","load","evict","monacoPromise","highlightPromise","monacoCached","highlightCached","preloadEditor","ensureMonaco","ensureHighlight","getMonaco","getHighlight","useMonacoLoader","EXPAND_KEY","props","__props","others","u","expanded","toggleExpanded","keyOf","initials","parts","hue","label","_createElementBlock","_normalizeClass","_openBlock","_hoisted_1","_Fragment","_renderList","_createElementVNode","_normalizeStyle","_createTextVNode","_toDisplayString","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_8","_hoisted_9","_hoisted_11","_unref","_hoisted_12","emit","__emit","open","x","y","targetNodes","menuEl","show","nextTick","sheetEl","clampToViewport","el","rect","margin","vw","vh","hide","sheetDragging","sheetDragY","sheetDragStart","onSheetDragStart","t0","onSheetDragMove","onSheetDragEnd","shouldClose","sheetStyle","pick","visibleActions","prefersDark","mq","syncPrefersDark","themeClass","__expose","_createBlock","_Teleport","_createVNode","_Transition","$event","_hoisted_7","DENSITY_LS_KEY","density","toggleDensity","searchEl","localSearch","watch","debounce","onSearchInput","focusSearch","searchOpen","mode","toolbarItems","fire","openSearch","closeSearch","coarse","coarseMq","syncCoarse","moreBtnEl","moreRef","moreActions","writable","openMore","onMoreSelect","_hoisted_22","ContextMenu","_cache","_hoisted_6","_hoisted_10","_hoisted_16","_hoisted_17","_hoisted_19","tags","loading","adding","newTag","palette","colorFor","tag","arr","buildHeaders","persist","previous","_withKeys","limit","fmtTime","diff","_hoisted_2","OVERFLOW_THRESHOLD","confinedRel","floorLabel","rel","crumbs","adapterPrefix","floor","cur","below","part","collapsed","leadCrumbs","middleCrumbs","tailCrumbs","overflowOpen","moreWrapEl","onOverflowPick","crumb","onDocClick","wrap","onDocKeydown","onClick","onContext","onCrumbDragOver","onCrumbDrop","editing","pathDraft","pathInput","startEdit","trimmed","submitPath","clean","slash","adapter","cancelEdit","EXT_FAMILIES","reg","family","exts","iconFamilyFor","ext","FILE_BASE","GLYPHS","SVG_CACHE","iconSvg","svg","fileIconSvg","snippetSegments","snippet","re","last","matchedInContent","matched","toggle","SORT_LS_KEY","isSelected","onRowClick","onRowDbl","onRowCtx","onItemDragStart","onItemDragOver","onItemDrop","pressTimer","pressTarget","onTouchStart","cancelPress","specialEmojiFor","isPinnedSpecial","displayDate","ms","parentDir","stripped","idx","rowSnippet","rowInContent","sortKey","sortDir","defaultDir","toggleSort","ariaSort","modifiedMs","rows","pinned","rest","dir","am","bm","monthFmt","bucketFor","d","dayStart","today","day","DAY","segments","seg","StarButton","_hoisted_14","_hoisted_15","_hoisted_20","_hoisted_21","si","_hoisted_23","_hoisted_24","_hoisted_25","thumbOf","onDbl","onCtx","visible","statusLabel","j","sorted","percent","statusClass","summary","verb","_TransitionGroup","single","isMulti","isFile","multiTotal","thumb","shortHash","formatDate","formatDateStr","copyText","effectivePerm","own","canManagePerms","permLabel","versionsState","versions","confirmVersionId","snapshotFirst","versionBusy","sharesState","shares","refreshSeq","refresh","seq","loadVersions","askRestore","confirmRestore","takeSnapshot","_hoisted_18","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","_hoisted_42","_hoisted_43","_hoisted_44","_hoisted_45","_hoisted_46","_hoisted_47","_hoisted_48","_hoisted_49","_hoisted_50","_hoisted_51","_hoisted_52","_hoisted_53","_hoisted_54","_hoisted_55","_hoisted_56","_hoisted_57","_hoisted_58","EVERYWHERE_MIN_CHARS","EVERYWHERE_LIMIT","EVERYWHERE_DEBOUNCE_MS","SAVED_LS_KEY","SAVED_MAX","inputEl","listEl","matchScore","sc","gotoItems","fileItems","scored","commandItems","everywhere","everywhereLoading","everywhereTimer","everywhereSeq","scheduleEverywhere","fn","hits","hitCrumb","parent","storage","hitItems","savedSearches","readSavedSearches","parsed","writeSavedSearches","saveSearch","removeSavedSearch","flat","savedItems","fileOffset","hitOffset","savedOffset","cmdOffset","choose","it","_withModifiers","_hoisted_29","cardEl","focusable","onBackdrop","_renderSlot","_ctx","$slots","groups","map","Modal","g","combo","submit","isOpen","usePin","expiresAt","maxDownloads","value","toast","shQuote","cliCommand","sh","MAX_TEXT_BYTES","ONLYOFFICE_SCRIPT_ID","IMAGE","VIDEO","AUDIO","CODE_LANGS","TEXT_PLAIN","OFFICE","VIEWER_MAP","kind","wantEdit","viewerCmp","shallowRef","viewerLoadError","pdfFallbackToNative","loadViewerFor","extension","loader","onPdfFallback","viewerProps","stripAdapter","openInNewTab","buildAndOpenStandalone","openEditInNewTab","EDITABLE_EXTS","canEditKind","download","fetchError","rawText","tooLarge","mdDirty","mdSaving","mdReRenderTimer","mdAutosaveTimer","onMdInput","renderMarkdown","saveMarkdown","fetchText","markdownHtml","markdownEl","Md","sanitizeHtml","enrichMarkdown","html","root","blocks","mermaid","katex","block","cls","isMermaid","isMath","_c","codeHtml","highlightCode","language","hljs","result","monacoEl","monacoEditor","codeAutosaveTimer","monacoReady","saving","saveOk","saveError","disposeMonaco","monacoLanguageFor","tryMountMonaco","monaco","editable","dark","saveCode","txt","runOrchestration","officeError","disposeOnlyOfficeEditor","lang","mountOnlyOfficeEditor","codeLanguage","officeEl","officeEditor","documentServerUrl","loadOnlyOfficeScript","mountId","formatOnlyOfficeError","W","existing","script","_hoisted_13","_resolveDynamicComponent","_mergeProps","iframeRef","error","formats","selectedTo","srcExt","fromFmt","ins","toList","seen","uniq","iframeSrc","msgId","send","cmd","transfer","onMessage","loadFormats","tt","doConvert","buf","outName","fb","L","pathParts","segs","tab","canManage","direct","inherited","storageRbac","busy","notice","noAccount","createRole","inviteResult","suggestions","showSuggest","searchTimer","levels","levelLabel","shareBusy","sharePwd","shareExpiry","shareResult","shareErr","copied","shareMailTo","shareMailBusy","shareMailNotice","expiryOptions","dropPwd","dropExpiry","dropShowAdv","dropMaxFiles","dropMaxSizeMB","dropAllowedExt","dropAskName","dropBusy","dropErr","dropResult","dropMailTo","dropMailBusy","dropMailNotice","splitEmails","mailResultNotice","sent","reload","reloadShares","onEmailInput","pickUser","lvl","submitEmail","addr","inviteCreateUser","gotoShareWithMail","changeLevel","newLevel","removeGrant","glabel","ginitial","expiresAtISO","createLink","sendShareMail","detail","dropExpiresAtISO","createDropLink","drop_settings","sendDropMail","revoke","canShare","humanSize","unit","exp","expiryLine","days","shareBody","pin","title","lines","sz","dropBody","folder","maxFiles","maxMB","nativeShare","_hoisted_59","_hoisted_61","_hoisted_62","_hoisted_63","_hoisted_64","_hoisted_65","_hoisted_66","_hoisted_67","_hoisted_68","_hoisted_69","_hoisted_70","_hoisted_71","_hoisted_72","_hoisted_73","_hoisted_74","_hoisted_75","_hoisted_76","_hoisted_77","_hoisted_78","_hoisted_79","_hoisted_80","_hoisted_81","_hoisted_82","_hoisted_83","_hoisted_85","_hoisted_86","_hoisted_87","_hoisted_88","_hoisted_89","_hoisted_90","_hoisted_91","_hoisted_93","_hoisted_94","VIEW_MODE_KEY","INSPECTOR_LS_KEY","PATH_LS_KEY","FE_DND_MIME","locale","realtime","realtimeDegraded","realtimeRoom","vp","qualify","currentPath","thumbs","chunked","opUndo","pendingOps","undo","flashToast","undoToast","rootPathProp","rootFloor","initialFloorPath","dirname","dirPerm","notFoundPath","loadError","loadErrorPath","retryLoad","viewMode","customRef","track","trigger","stored","searchQuery","trashMode","trashOrigin","trashActive","canGoUp","atVirtualRoot","multiStorageRoot","goUp","selection","focusFiles","clipboard","capabilitiesData","starredIds","showRecents","showTagPicker","tagPickerNode","recentRefreshKey","loadStarred","buildAuthHeaders","onStarChange","markRecent","openTagPickerFor","onRecentOpen","openNode","effectiveOnlyOfficeBase","effectiveOnlyOfficeConfigEndpoint","effectiveDrawioUrl","override","effectiveConvertUrl","uploadJobs","fileInputEl","showNewFolder","showRename","showDelete","showShare","showPreview","renameTarget","shareTarget","activeShare","previewTarget","previewMode","showConvert","convertTarget","showPerm","permTarget","showInspector","persistInspector","toggleInspector","openInspector","closeInspector","inspectorDirLabel","onInspectorManage","permCanEdit","selPerm","sel","canWriteHere","emptyCanUpload","ctxRef","toolbarRef","isNarrow","isCoarse","narrowRO","syncCoarsePointer","entries","w","toastTimer","showToast","state","message","dismissToast","runToastAction","act","splitVirtualPath","virtualToWire","wireToVirtual","virtualStorageRows","requested","resp","dirRel","inRoot","isTrashListing","trashEntryEnabled","hydrateTrashRow","leaveNotFound","row","total","newest","ts","loadTrash","wireBasename","wireParent","prefix","wireJoin","registerMoveUndo","opId","targetWire","originWire","movedPaths","persistMode","hashPersistEnabled","safeDecode","readLsPath","readHashPath","readPersistedPath","fromHash","writePersistedPath","encoded","onHashChange","fromPersist","cap","showPalette","showShortcutsHelp","paletteGlobalSearch","openSearchHit","hit","isDir","targetRel","configured","cut","copyToClipboard","paste","OFFICE_EXTS","previewModeForExt","VIEW_DEFAULT_EXTS","restoreSelection","targets","previewNode","openNodeInNewTab","ctxMode","breadcrumbCtxPath","breadcrumbCtxLabel","selectionMode","onToolbarAction","dispatchItemAction","onContextTarget","onContextCanvas","onCrumbContext","contextActions","any","trimmedPath","selectionActionList","tagsLabel","singleHasId","copyIdLabel","accessLabel","toolbarActions","onContextAction","onCopyPath","downloadFile","openConvert","openShare","duplicate","cb","submitNewFolder","submitRename","dirWire","oldPath","oldName","newPath","confirmDelete","nodeIds","restoreUndo","onConvertDone","submitShare","share","closeShare","triggerUpload","onFilePicked","input","uploadFiles","canChunk","chunkedUpload","legacyUpload","patch","registered","dragCounter","dragOver","isExternalFileDrag","dt","hasFile","onDragEnter","onDragLeave","onDragOver","onDropUpload","onWindowDragOver","onWindowDrop","clippedPaths","moveSourcesAsync","targetDir","opLabel","onItemDropInto","onCrumbDropInto","adapterPath","onCancelUpload","onDismissUpload","onNavigate","Toolbar","Breadcrumb","PresenceBar","ListView","GridView","InspectorPanel","UploadProgress","PendingOpsTray","NewFolderModal","RenameModal","DeleteConfirmModal","ShareModal","PreviewModal","ConvertModal","PermissionsModal","RecentlyOpened","TagPicker","CommandPalette","ShortcutsHelp"],"mappings":"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"}
|