@brftech/filex-core 0.1.78 → 0.1.80
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-BmpDoIWA.js → ArchiveViewer-CCGfU9dN.js} +2 -2
- package/dist/{ArchiveViewer-BmpDoIWA.js.map → ArchiveViewer-CCGfU9dN.js.map} +1 -1
- package/dist/{CsvViewer-BAMxNxy4.js → CsvViewer-CAV-Uo4z.js} +2 -2
- package/dist/{CsvViewer-BAMxNxy4.js.map → CsvViewer-CAV-Uo4z.js.map} +1 -1
- package/dist/{DrawioViewer-BIm8G98S.js → DrawioViewer-XhX0JOji.js} +2 -2
- package/dist/{DrawioViewer-BIm8G98S.js.map → DrawioViewer-XhX0JOji.js.map} +1 -1
- package/dist/{EpubViewer-D2OggB7W.js → EpubViewer-CCezeX0N.js} +2 -2
- package/dist/{EpubViewer-D2OggB7W.js.map → EpubViewer-CCezeX0N.js.map} +1 -1
- package/dist/{IpynbViewer-Dcew5gZQ.js → IpynbViewer-BZBb-rs9.js} +2 -2
- package/dist/{IpynbViewer-Dcew5gZQ.js.map → IpynbViewer-BZBb-rs9.js.map} +1 -1
- package/dist/{MermaidViewer-iG7VuHeu.js → MermaidViewer-QEjCQrOM.js} +2 -2
- package/dist/{MermaidViewer-iG7VuHeu.js.map → MermaidViewer-QEjCQrOM.js.map} +1 -1
- package/dist/{PsdViewer-C-92G5j0.js → PsdViewer-BN_HJPVZ.js} +2 -2
- package/dist/{PsdViewer-C-92G5j0.js.map → PsdViewer-BN_HJPVZ.js.map} +1 -1
- package/dist/{TiffViewer-uOJVggkp.js → TiffViewer-DzN9zot1.js} +2 -2
- package/dist/{TiffViewer-uOJVggkp.js.map → TiffViewer-DzN9zot1.js.map} +1 -1
- package/dist/{Viewer3D-RnzhEk_6.js → Viewer3D-BMPN3KRu.js} +2 -2
- package/dist/{Viewer3D-RnzhEk_6.js.map → Viewer3D-BMPN3KRu.js.map} +1 -1
- package/dist/filex-core.js +1 -1
- package/dist/filex-core.umd.cjs +35 -35
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/index-BYO3EF3F.js +5864 -0
- package/dist/index-BYO3EF3F.js.map +1 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/FileExplorer.vue +18 -2
- package/src/components/GridView.vue +12 -2
- package/src/components/PresenceBar.vue +149 -22
- package/src/composables/useThumbs.ts +76 -0
- package/src/lib/realtime.ts +4 -0
- package/dist/index-B6jiFQPw.js +0 -5758
- package/dist/index-B6jiFQPw.js.map +0 -1
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.fx-presence[data-v-1c69ff03]{display:inline-flex;align-items:center;gap:.5rem;max-width:100%}.fx-presence-avatars[data-v-1c69ff03]{display:inline-flex;align-items:center}.fx-presence-avatar[data-v-1c69ff03]{position:relative;display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin-left:-.4rem;border-radius:9999px;border:2px solid var(--fx-presence-ring, #ffffff);color:#fff;font-size:.6rem;font-weight:600;line-height:1;-webkit-user-select:none;user-select:none}.fx-presence-avatar[data-v-1c69ff03]:first-child{margin-left:0}.fx-presence-dot[data-v-1c69ff03]{position:absolute;right:-1px;bottom:-1px;width:.5rem;height:.5rem;border-radius:9999px;background:#22c55e;border:1.5px solid var(--fx-presence-ring, #ffffff)}.fx-presence-more[data-v-1c69ff03]{margin-left:.15rem;font-size:.7rem;color:#71717a}.fx-presence-text[data-v-1c69ff03]{font-size:.75rem;color:#71717a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:14rem}.fx-presence-file[data-v-1c69ff03]{color:#52525b;font-weight:500}.dark{--fx-presence-ring: #18181b}.filex-tag-picker[data-v-7040583c]{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.filex-tag-picker.is-loading[data-v-7040583c]{opacity:.6;pointer-events:none}.filex-tag[data-v-7040583c]{display:inline-flex;align-items:center;gap:4px;border-radius:999px;padding:2px 10px;font-size:12px;font-weight:500;color:#fff;background:var(--filex-tag-color)}.filex-tag-x[data-v-7040583c]{background:transparent;border:none;color:#ffffffd9;cursor:pointer;padding:0 2px;font-size:14px;line-height:1}.filex-tag-x[data-v-7040583c]:hover{color:#fff}.filex-tag-add input[data-v-7040583c]{border:1px solid var(--filex-border, #d1d5db);border-radius:12px;padding:2px 10px;font-size:12px;width:110px}.filex-tag-add-btn[data-v-7040583c]{border:1px dashed var(--filex-border, #d1d5db);background:transparent;border-radius:999px;padding:2px 10px;font-size:12px;color:var(--filex-text-muted, #6b7280);cursor:pointer}.filex-tag-add-btn[data-v-7040583c]:hover{border-color:var(--filex-accent, #6366f1);color:var(--filex-accent, #6366f1)}.filex-recent[data-v-559f2c71]{background:var(--fe-bg-elev, var(--filex-bg-card, #ffffff));border:1px solid var(--fe-border, var(--filex-border, #e5e7eb));border-radius:8px;padding:12px;font-size:13px}.filex-recent header[data-v-559f2c71]{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.filex-recent h3[data-v-559f2c71]{margin:0;font-size:13px;font-weight:600;color:var(--fe-text, var(--filex-text, #111827))}.filex-recent-refresh[data-v-559f2c71]{background:transparent;border:none;color:var(--fe-text-muted, var(--filex-text-muted, #9ca3af));cursor:pointer;font-size:14px;padding:2px 6px}.filex-recent ul[data-v-559f2c71]{list-style:none;margin:0;padding:0}.filex-recent-item[data-v-559f2c71]{display:flex;justify-content:space-between;align-items:center;width:100%;background:transparent;border:none;padding:6px 8px;cursor:pointer;border-radius:4px;text-align:left}.filex-recent-item[data-v-559f2c71]:hover{background:var(--fe-bg-hover, var(--filex-bg-soft, #f3f4f6))}.filex-recent-name[data-v-559f2c71]{color:var(--fe-text, var(--filex-text, #111827));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.filex-recent-meta[data-v-559f2c71]{color:var(--fe-text-muted, var(--filex-text-muted, #9ca3af));font-size:11px;margin-left:8px;flex-shrink:0}.filex-recent-empty[data-v-559f2c71]{color:var(--fe-text-muted, var(--filex-text-muted, #9ca3af));margin:4px 0 0}.filex-star-btn[data-v-12a2f9c5]{display:inline-flex;align-items:center;gap:6px;background:transparent;border:1px solid transparent;border-radius:6px;padding:4px 8px;color:var(--filex-text-muted, #9ca3af);cursor:pointer;transition:color .12s,background .12s}.filex-star-btn[data-v-12a2f9c5]:hover{color:var(--filex-accent-amber, #f59e0b);background:var(--filex-bg-soft, rgba(0, 0, 0, .04))}.filex-star-btn.is-starred[data-v-12a2f9c5]{color:var(--filex-accent-amber, #f59e0b)}.filex-star-btn.is-compact[data-v-12a2f9c5]{padding:4px}.filex-star-label[data-v-12a2f9c5]{font-size:13px}.fe-preview__code-editor.is-hidden{display:none}.fe-preview__viewer{width:100%;height:100%;min-height:70vh;display:flex;flex-direction:column}.fe-preview .fe-preview__viewer{align-self:stretch}.fe-preview__md-mermaid{display:flex;justify-content:center;margin:16px 0}.fe-preview__md-mermaid svg{max-width:100%;height:auto}.fe-preview__md-math{margin:16px 0;text-align:center;overflow-x:auto}.filex-cv__bg[data-v-4363f1ac]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;background:#0000008c;display:flex;align-items:center;justify-content:center}.filex-cv[data-v-4363f1ac]{width:min(560px,92vw);max-height:80vh;overflow:hidden;display:flex;flex-direction:column;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1f29);border:1px solid var(--fe-border, #e2e6ed);border-radius:12px;box-shadow:0 20px 60px #00000059}.filex-cv__head[data-v-4363f1ac]{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--fe-border, #e2e6ed)}.filex-cv__head h3[data-v-4363f1ac]{margin:0;font-size:14px;font-weight:600}.filex-cv__x[data-v-4363f1ac]{border:0;background:none;cursor:pointer;font-size:16px;color:var(--fe-text-muted, #5a6475)}.filex-cv__msg[data-v-4363f1ac]{padding:28px;text-align:center;color:var(--fe-text-muted, #5a6475)}.filex-cv__ok[data-v-4363f1ac]{color:#059669}.filex-cv__src[data-v-4363f1ac]{padding:12px 16px 0;font-size:13px;color:var(--fe-text-muted, #5a6475)}.filex-cv__search[data-v-4363f1ac]{margin:8px 16px;padding:8px 10px;border:1px solid var(--fe-border, #e2e6ed);border-radius:8px;background:var(--fe-bg-elev, #f7f8fa);color:inherit;font-size:13px}.filex-cv__list[data-v-4363f1ac]{flex:1;overflow-y:auto;padding:4px 12px 12px;display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:8px}.filex-cv__fmt[data-v-4363f1ac]{display:flex;flex-direction:column;gap:2px;align-items:flex-start;padding:8px 10px;cursor:pointer;text-align:left;border:1px solid var(--fe-border, #e2e6ed);border-radius:8px;background:var(--fe-bg-elev, #f7f8fa);color:inherit}.filex-cv__fmt small[data-v-4363f1ac]{color:var(--fe-text-muted, #5a6475);font-size:11px}.filex-cv__fmt.is-sel[data-v-4363f1ac]{border-color:#44c878;background:#44c8781f}.filex-cv__empty[data-v-4363f1ac]{grid-column:1 / -1;text-align:center;color:var(--fe-text-muted, #5a6475);padding:16px}.filex-cv__err[data-v-4363f1ac]{padding:0 16px;color:var(--fe-danger, #dc2626);font-size:13px}.filex-cv__foot[data-v-4363f1ac]{padding:12px 16px;border-top:1px solid var(--fe-border, #e2e6ed);text-align:right}.filex-cv__convert[data-v-4363f1ac]{padding:8px 18px;border:0;border-radius:8px;cursor:pointer;background:#44c878;color:#03200f;font-weight:600;font-size:13px}.filex-cv__convert[data-v-4363f1ac]:disabled{opacity:.5;cursor:default}.filex-cv__frame[data-v-4363f1ac]{position:absolute;width:0;height:0;border:0;left:-9999px}.fx-perm-overlay[data-v-23e7820c]{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000;font-family:var(--fe-font)}.fx-perm-modal[data-v-23e7820c]{display:flex;flex-direction:column;background:var(--fe-bg);color:var(--fe-text);width:min(520px,94vw);max-height:86vh;border:1px solid var(--fe-border);border-radius:var(--fe-radius-lg, 14px);box-shadow:var(--fe-shadow);font-size:14px;overflow:hidden}.fx-perm-head[data-v-23e7820c]{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:16px 18px 12px;flex:none}.fx-perm-title[data-v-23e7820c]{display:flex;align-items:center;gap:10px;min-width:0}.fx-perm-ico[data-v-23e7820c]{font-size:22px;line-height:1}.fx-perm-titletext[data-v-23e7820c]{display:flex;flex-direction:column;min-width:0}.fx-perm-title h3[data-v-23e7820c]{margin:0;font-size:15px;font-weight:600;color:var(--fe-text)}.fx-perm-sub[data-v-23e7820c]{font-size:12px;color:var(--fe-text);max-width:340px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fx-perm-subdim[data-v-23e7820c]{color:var(--fe-text-muted)}.fx-perm-x[data-v-23e7820c]{background:none;border:none;font-size:17px;cursor:pointer;color:var(--fe-text-muted);flex:none;line-height:1;padding:2px 4px;border-radius:6px}.fx-perm-x[data-v-23e7820c]:hover{color:var(--fe-text);background:var(--fe-bg-hover)}.fx-perm-tabs[data-v-23e7820c]{display:flex;gap:2px;padding:0 18px;border-bottom:1px solid var(--fe-border);flex:none}.fx-perm-tab[data-v-23e7820c]{background:none;border:none;border-bottom:2px solid transparent;padding:8px 12px;cursor:pointer;color:var(--fe-text-muted);font-size:13px;font-family:inherit;font-weight:500}.fx-perm-tab[data-v-23e7820c]:hover{color:var(--fe-text)}.fx-perm-tab.is-active[data-v-23e7820c]{color:var(--fe-primary);border-bottom-color:var(--fe-primary)}.fx-perm-body[data-v-23e7820c]{flex:1 1 auto;overflow-y:auto;padding:14px 18px 18px}.fx-perm-addcard[data-v-23e7820c]{padding:12px;border-radius:var(--fe-radius-md, 10px);background:var(--fe-bg-elev);border:1px solid var(--fe-border)}.fx-perm-section[data-v-23e7820c]{margin-top:16px}.fx-perm-section h4[data-v-23e7820c]{margin:0 0 8px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--fe-text-muted)}.fx-perm-empty[data-v-23e7820c]{color:var(--fe-text-muted);font-size:13px;padding:8px 2px}.fx-perm-person[data-v-23e7820c]{display:flex;align-items:center;gap:10px;padding:7px 2px}.fx-perm-person+.fx-perm-person[data-v-23e7820c]{border-top:1px solid var(--fe-border)}.fx-perm-inh[data-v-23e7820c]{color:var(--fe-text-muted)}.fx-perm-av[data-v-23e7820c]{width:28px;height:28px;flex:none;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--fe-primary);color:var(--fe-text-on-primary, #fff);font-size:12px;font-weight:600}.fx-perm-av--dim[data-v-23e7820c]{background:var(--fe-bg-hover);color:var(--fe-text-muted)}.fx-perm-user[data-v-23e7820c]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--fe-text);min-width:0}.fx-perm-from[data-v-23e7820c]{font-size:11px;color:var(--fe-text-muted);white-space:nowrap}.fx-perm-badge[data-v-23e7820c]{font-size:11px;padding:2px 9px;border-radius:999px;background:var(--fe-bg-hover);color:var(--fe-text)}.fx-perm-sel[data-v-23e7820c],.fx-perm-input[data-v-23e7820c]{padding:7px 9px;border-radius:var(--fe-radius-sm, 7px);border:1px solid var(--fe-border);background:var(--fe-bg);color:var(--fe-text);font-size:13px;font-family:inherit}.fx-perm-sel--sm[data-v-23e7820c]{padding:5px 7px;font-size:12px}.fx-perm-sel[data-v-23e7820c]:focus,.fx-perm-input[data-v-23e7820c]:focus{outline:none;border-color:var(--fe-primary)}.fx-perm-add[data-v-23e7820c]{display:flex;gap:8px;align-items:stretch}.fx-perm-emailwrap[data-v-23e7820c]{position:relative;flex:1;min-width:120px}.fx-perm-input[data-v-23e7820c]{width:100%;box-sizing:border-box}.fx-perm-suggest[data-v-23e7820c]{position:absolute;top:calc(100% + 3px);left:0;right:0;z-index:5;margin:0;padding:4px;list-style:none;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm, 7px);box-shadow:var(--fe-shadow);max-height:210px;overflow:auto}.fx-perm-suggest li[data-v-23e7820c]{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;cursor:pointer}.fx-perm-suggest li[data-v-23e7820c]:hover{background:var(--fe-bg-hover)}.fx-perm-suggest-av[data-v-23e7820c]{width:24px;height:24px;flex:none;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--fe-bg-hover);color:var(--fe-text);font-size:11px;font-weight:600}.fx-perm-suggest-txt[data-v-23e7820c]{display:flex;flex-direction:column;min-width:0}.fx-perm-suggest-name[data-v-23e7820c]{color:var(--fe-text);font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fx-perm-suggest-meta[data-v-23e7820c]{color:var(--fe-text-muted);font-size:11px}.fx-perm-check[data-v-23e7820c]{display:inline-flex;gap:6px;align-items:center;font-size:13px;color:var(--fe-text);cursor:pointer}.fx-perm-btn[data-v-23e7820c]{padding:7px 13px;border-radius:var(--fe-radius-sm, 7px);border:1px solid var(--fe-border);background:var(--fe-bg);color:var(--fe-text);font-size:13px;font-family:inherit;cursor:pointer;white-space:nowrap}.fx-perm-btn[data-v-23e7820c]:hover:not(:disabled){background:var(--fe-bg-hover)}.fx-perm-btn[data-v-23e7820c]:disabled{opacity:.55;cursor:default}.fx-perm-btn--sm[data-v-23e7820c]{padding:5px 10px;font-size:12px}.fx-perm-btn--primary[data-v-23e7820c]{background:var(--fe-primary);border-color:var(--fe-primary);color:var(--fe-text-on-primary, #fff)}.fx-perm-btn--primary[data-v-23e7820c]:hover:not(:disabled){background:var(--fe-primary-hover, var(--fe-primary));filter:brightness(1.05)}.fx-perm-btn--ghost[data-v-23e7820c]{background:none;border-color:transparent;color:var(--fe-primary);padding-left:2px}.fx-perm-btn--ghost[data-v-23e7820c]:hover:not(:disabled){background:none;text-decoration:underline}.fx-perm-del[data-v-23e7820c]{background:none;border:none;color:var(--fe-danger);cursor:pointer;font-size:14px;flex:none;padding:2px 4px}.fx-perm-del[data-v-23e7820c]:hover:not(:disabled){filter:brightness(1.15)}.fx-perm-invite[data-v-23e7820c]{margin-top:10px;padding-top:10px;border-top:1px dashed var(--fe-border)}.fx-perm-invite-actions[data-v-23e7820c]{display:flex;flex-direction:column;gap:8px;margin-top:6px}.fx-perm-invite-row[data-v-23e7820c]{display:flex;gap:8px;align-items:stretch}.fx-perm-invite-row .fx-perm-btn--primary[data-v-23e7820c]{flex:1}.fx-perm-share-opts[data-v-23e7820c]{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.fx-perm-expiry[data-v-23e7820c]{display:inline-flex;gap:6px;align-items:center;font-size:13px}.fx-perm-share-opts .fx-perm-btn--primary[data-v-23e7820c]{margin-left:auto}.fx-perm-result[data-v-23e7820c]{margin-top:12px;padding-top:12px;border-top:1px solid var(--fe-border)}.fx-perm-linkrow[data-v-23e7820c]{display:flex;gap:8px;align-items:center}.fx-perm-link[data-v-23e7820c]{color:var(--fe-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;text-decoration:none}.fx-perm-link[data-v-23e7820c]:hover{text-decoration:underline}.fx-perm-pin[data-v-23e7820c]{margin:8px 0 0;font-size:13px;color:var(--fe-text);display:flex;align-items:center;gap:8px}.fx-perm-pin code[data-v-23e7820c],.fx-perm-reveal code[data-v-23e7820c]{font-family:var(--fe-font-mono, monospace);background:var(--fe-bg-hover);padding:1px 6px;border-radius:5px}.fx-perm-mailrow[data-v-23e7820c]{display:flex;gap:8px;margin-top:10px}.fx-perm-mailrow .fx-perm-input[data-v-23e7820c]{flex:1}.fx-perm-hint[data-v-23e7820c]{font-size:13px;color:var(--fe-text-muted);margin:10px 0 0}.fx-perm-sharebtn[data-v-23e7820c]{display:flex;width:100%;align-items:center;justify-content:center;gap:6px;margin-top:8px}.fx-perm-dropintro[data-v-23e7820c]{margin:0 0 12px;line-height:1.4}.fx-perm-advtoggle[data-v-23e7820c]{margin-top:10px;padding-left:2px}.fx-perm-adv[data-v-23e7820c]{margin-top:8px;padding-top:10px;border-top:1px dashed var(--fe-border);display:flex;flex-direction:column;gap:8px}.fx-perm-adv-row[data-v-23e7820c]{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:13px}.fx-perm-input--sm[data-v-23e7820c]{width:130px;padding:5px 8px;font-size:12px}.fx-perm-warn[data-v-23e7820c]{background:#f59e0b24;border:1px solid rgba(245,158,11,.4);border-radius:var(--fe-radius-sm, 7px);padding:8px 10px;font-size:13px;margin-bottom:10px;color:var(--fe-text)}.fx-perm-notice[data-v-23e7820c]{margin-top:8px;font-size:13px;color:var(--fe-text-muted)}.fx-perm-reveal[data-v-23e7820c]{margin-top:8px;font-size:13px;word-break:break-all;color:var(--fe-text)}.fx-perm-muted[data-v-23e7820c]{color:var(--fe-text-muted);font-size:13px}:root{--fe-bg: #ffffff;--fe-bg-elev: #f7f8fa;--fe-bg-hover: #edf0f5;--fe-bg-selected: #dfe8ff;--fe-border: #e2e6ed;--fe-border-strong: #c7ced9;--fe-text: #1a1e27;--fe-text-muted: #5a6475;--fe-text-on-primary: #ffffff;--fe-primary: #3b82f6;--fe-primary-hover: #2563eb;--fe-danger: #dc2626;--fe-danger-hover: #b91c1c;--fe-shadow: 0 10px 32px rgba(15, 23, 42, .14);--fe-shadow-sm: 0 2px 6px rgba(15, 23, 42, .08);--fe-radius: 8px;--fe-radius-sm: 4px;--fe-radius-lg: 12px;--fe-font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--fe-font-mono: ui-monospace, "SF Mono", Consolas, Menlo, monospace;--fe-gap: 12px}.fe--theme-dark,:root[data-theme=dark] .fe,.fe.fe--theme-dark,:root.dark,.dark,:root.dark .fe,.dark .fe,.fe-ctx-backdrop--theme-dark,.fe-ctx-backdrop--theme-auto[data-prefers-dark="1"]{--fe-bg: #0f1419;--fe-bg-elev: #161c25;--fe-bg-hover: #1f2733;--fe-bg-selected: #23324a;--fe-border: #2a323e;--fe-border-strong: #3a4453;--fe-text: #e5e9f0;--fe-text-muted: #8b95a7;--fe-primary: #60a5fa;--fe-primary-hover: #3b82f6;--fe-danger: #f87171;--fe-danger-hover: #ef4444;--fe-shadow: 0 12px 32px rgba(0, 0, 0, .45);--fe-shadow-sm: 0 2px 6px rgba(0, 0, 0, .25)}@media (prefers-color-scheme: dark){.fe:not(.fe--theme-light),.fe-ctx-backdrop--theme-auto:not(.fe-ctx-backdrop--theme-light){--fe-bg: #0f1419;--fe-bg-elev: #161c25;--fe-bg-hover: #1f2733;--fe-bg-selected: #23324a;--fe-border: #2a323e;--fe-border-strong: #3a4453;--fe-text: #e5e9f0;--fe-text-muted: #8b95a7;--fe-primary: #60a5fa;--fe-primary-hover: #3b82f6;--fe-danger: #f87171;--fe-danger-hover: #ef4444;--fe-shadow: 0 12px 32px rgba(0, 0, 0, .45);--fe-shadow-sm: 0 2px 6px rgba(0, 0, 0, .25)}}.fe{position:relative;display:flex;flex-direction:column;min-height:420px;height:100%;background:var(--fe-bg);color:var(--fe-text);font-family:var(--fe-font);font-size:14px;border:1px solid var(--fe-border);border-radius:var(--fe-radius);overflow:hidden;outline:none}.fe *{box-sizing:border-box}.fe__body{flex:1 1 auto;overflow:auto;background:var(--fe-bg)}.fe__presence{flex:0 0 auto;padding:.25rem .75rem;border-bottom:1px solid var(--fe-border, rgba(0, 0, 0, .06))}.fe__loading{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;min-height:240px;height:100%;color:var(--fe-text-muted)}.fe__spinner{width:34px;height:34px;border-radius:50%;border:3px solid color-mix(in srgb,var(--fe-text-muted) 30%,transparent);border-top-color:var(--fe-primary);animation:fe-spin .7s linear infinite}.fe__loading-text{margin:0;font-size:13px}@keyframes fe-spin{to{transform:rotate(360deg)}}.fe__notfound{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-height:240px;height:100%;color:var(--fe-text-muted);text-align:center;padding:24px}.fe__notfound-icon{font-size:40px;filter:grayscale(1);opacity:.6}.fe__notfound-title{margin:4px 0 0;font-size:15px;font-weight:600;color:var(--fe-text)}.fe__notfound-path{margin:0;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;word-break:break-all;max-width:480px}.fe__notfound-desc{margin:0 0 10px;font-size:13px}.fe__file-input{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}.fe-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:var(--fe-bg-elev);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);color:var(--fe-text);font:inherit;cursor:pointer;transition:background .12s,border-color .12s;white-space:nowrap}.fe-btn:hover:not(:disabled){background:var(--fe-bg-hover);border-color:var(--fe-border-strong)}.fe-btn:disabled{opacity:.5;cursor:not-allowed}.fe-btn--primary{background:var(--fe-primary);border-color:var(--fe-primary);color:var(--fe-text-on-primary)}.fe-btn--primary:hover:not(:disabled){background:var(--fe-primary-hover);border-color:var(--fe-primary-hover)}.fe-btn--danger{background:var(--fe-danger);border-color:var(--fe-danger);color:var(--fe-text-on-primary)}.fe-btn--danger:hover:not(:disabled){background:var(--fe-danger-hover);border-color:var(--fe-danger-hover)}.fe-btn--icon-only{padding:6px 8px}.fe-btn.is-active{background:var(--fe-bg-selected);border-color:var(--fe-primary)}.fe-btn__label{line-height:1}.fe-icon{font-size:1.05em;line-height:1}.fe-toolbar{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--fe-bg-elev);border-bottom:1px solid var(--fe-border);flex-wrap:wrap}.fe-toolbar__primary{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}.fe-toolbar__spacer{flex:1 1 auto}.fe-toolbar__search-group{display:inline-flex;align-items:center;gap:4px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);padding:2px}.fe-toolbar__search-group .fe-search__input{border:0;background:transparent;padding:4px 8px}.fe-toolbar__search-group .fe-btn{border:0;background:transparent;padding:4px 6px}.fe-toolbar__search-group .fe-btn:hover:not(:disabled){background:var(--fe-bg-hover)}.fe-toolbar__view{display:inline-flex;gap:2px;padding:2px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm)}.fe-toolbar__view .fe-btn{border:0;background:transparent}.fe-toolbar__view .fe-btn.is-active{background:var(--fe-bg-selected)}.fe-search{position:relative}.fe-search__input{background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);padding:6px 10px;font:inherit;color:var(--fe-text);min-width:200px}.fe-search__input:focus-visible{outline:2px solid var(--fe-primary);outline-offset:1px}.fe-breadcrumb{display:flex;align-items:center;gap:4px;flex-wrap:wrap;padding:6px 12px;background:var(--fe-bg);border-bottom:1px solid var(--fe-border);font-size:13px;color:var(--fe-text-muted)}.fe-breadcrumb__crumb{display:inline-flex;align-items:center;gap:4px;background:transparent;border:0;color:inherit;padding:2px 6px;border-radius:var(--fe-radius-sm);cursor:pointer;font:inherit}.fe-breadcrumb__crumb:hover{background:var(--fe-bg-hover);color:var(--fe-text)}.fe-breadcrumb__crumb.is-last{color:var(--fe-text);font-weight:600}.fe-breadcrumb__sep{color:var(--fe-text-muted)}.fe-breadcrumb__edit{margin-left:auto;background:none;border:1px solid transparent;color:var(--fe-text-muted);cursor:pointer;font-size:14px;line-height:1;padding:4px 8px;border-radius:4px}.fe-breadcrumb__edit:hover{background:var(--fe-bg-hover);color:var(--fe-text);border-color:var(--fe-border)}.fe-breadcrumb__input{flex:1;background:var(--fe-bg);color:var(--fe-text);border:1px solid var(--fe-accent, #2563eb);border-radius:4px;padding:4px 8px;font-family:var(--fe-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:13px;outline:none}.fe-list{display:flex;flex-direction:column}.fe-list__head{display:grid;grid-template-columns:32px minmax(0,1fr) 120px 180px;gap:8px;padding:8px 12px;font-weight:600;color:var(--fe-text-muted);font-size:12px;text-transform:uppercase;letter-spacing:.04em;background:var(--fe-bg-elev);border-bottom:1px solid var(--fe-border)}.fe-list__body{display:flex;flex-direction:column}.fe-list__row{display:grid;grid-template-columns:32px minmax(0,1fr) 120px 180px;gap:8px;padding:8px 12px;align-items:center;cursor:pointer;border-bottom:1px solid var(--fe-border);transition:background .08s;-webkit-user-select:none;user-select:none}.fe-list__row:hover{background:var(--fe-bg-hover)}.fe-list__row.is-selected{background:var(--fe-bg-selected)}.fe-list__row.is-trash{opacity:.7}.fe-list__row.is-clipped,.fe-grid__card.is-clipped{opacity:.45;font-style:italic}.fe-list__row:focus-visible{outline:2px solid var(--fe-primary);outline-offset:-2px}.fe-list__col--star{display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .12s}.fe-list__row:hover .fe-list__col--star,.fe-list__row:focus-within .fe-list__col--star,.fe-list__col--star:has(.is-starred){opacity:1}.fe-list__col--star .filex-star-btn.is-starred{color:var(--fe-warning, #f59e0b)}.fe-list__col--name{display:flex;align-items:center;gap:8px;min-width:0}.fe-list__icon{flex-shrink:0;font-size:16px}.fe-list__name-wrap{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}.fe-list__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe-list__parent{font-size:11px;color:var(--fe-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px}.fe-list__col--size,.fe-list__col--mod{color:var(--fe-text-muted);font-size:13px}.fe-list__empty{padding:40px 20px;text-align:center;color:var(--fe-text-muted)}.fe-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:var(--fe-gap);padding:var(--fe-gap)}.fe-grid__card{display:flex;flex-direction:column;align-items:stretch;padding:8px;border:1px solid var(--fe-border);border-radius:var(--fe-radius);background:var(--fe-bg-elev);cursor:pointer;transition:background .08s,border-color .08s;-webkit-user-select:none;user-select:none}.fe-grid__card:hover{background:var(--fe-bg-hover);border-color:var(--fe-border-strong)}.fe-grid__card.is-selected{background:var(--fe-bg-selected);border-color:var(--fe-primary)}.fe-grid__card.is-trash{opacity:.7}.fe-grid__thumb{display:flex;align-items:center;justify-content:center;aspect-ratio:1 / 1;background:var(--fe-bg);border-radius:var(--fe-radius-sm);margin-bottom:8px;overflow:hidden}.fe-grid__thumb img{width:100%;height:100%;object-fit:cover}.fe-grid__icon{font-size:32px}.fe-grid__label{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe-grid__meta{font-size:11px;color:var(--fe-text-muted);margin-top:2px}.fe-grid__parent{font-size:11px;color:var(--fe-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px;font-style:italic}.fe-grid__empty{grid-column:1 / -1;padding:40px 20px;text-align:center;color:var(--fe-text-muted)}.fe__dragover{position:absolute;top:0;right:0;bottom:0;left:0;z-index:30;display:flex;align-items:center;justify-content:center;background:#3b82f61f;border:3px dashed var(--fe-primary);pointer-events:none}.fe__dragover-card{background:var(--fe-bg);border-radius:var(--fe-radius-lg);padding:24px 40px;box-shadow:var(--fe-shadow);text-align:center}.fe__dragover-card .fe-icon{font-size:32px;display:block;margin-bottom:8px}.fe-upload{position:absolute;right:16px;bottom:16px;width:min(360px,calc(100% - 32px));background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);z-index:40;max-height:40vh;display:flex;flex-direction:column;overflow:hidden}.fe-upload__header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:var(--fe-bg-elev);border-bottom:1px solid var(--fe-border);font-size:13px}.fe-upload__count{background:var(--fe-primary);color:var(--fe-text-on-primary);font-size:12px;padding:1px 7px;border-radius:999px}.fe-upload__list{list-style:none;padding:0;margin:0;overflow:auto}.fe-upload__item{padding:10px 14px;border-bottom:1px solid var(--fe-border)}.fe-upload__item:last-child{border-bottom:0}.fe-upload__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;margin-bottom:4px}.fe-upload__bar{background:var(--fe-bg-elev);border-radius:99px;height:6px;overflow:hidden;margin-bottom:4px}.fe-upload__bar-fill{background:var(--fe-primary);height:100%;transition:width .2s}.fe-upload__item.is-error .fe-upload__bar-fill,.fe-upload__item.is-aborted .fe-upload__bar-fill{background:var(--fe-danger)}.fe-upload__item.is-done .fe-upload__bar-fill{background:#16a34a}.fe-upload__meta{display:flex;align-items:center;justify-content:space-between;gap:6px;font-size:11px;color:var(--fe-text-muted)}.fe-upload__cancel{background:transparent;border:0;color:var(--fe-primary);cursor:pointer;font:inherit}.fe-upload-slide-enter-active,.fe-upload-slide-leave-active{transition:transform .2s,opacity .2s}.fe-upload-slide-enter-from,.fe-upload-slide-leave-to{opacity:0;transform:translateY(10px)}.fe-ops{position:absolute;left:16px;bottom:16px;width:min(320px,calc(100% - 32px));display:flex;flex-direction:column;gap:8px;z-index:40}.fe-ops__item{background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);padding:10px 14px;font-size:13px}.fe-ops__item.is-done{border-color:#16a34a}.fe-ops__item.is-error{border-color:var(--fe-danger)}.fe-ops__row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}.fe-ops__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto}.fe-ops__dismiss{background:transparent;border:0;color:var(--fe-text-muted);cursor:pointer;font-size:18px;line-height:1;padding:0 4px}.fe-ops__bar{background:var(--fe-bg-elev);border-radius:99px;height:6px;overflow:hidden}.fe-ops__bar-fill{background:var(--fe-primary);height:100%;transition:width .25s}.fe-ops__item.is-done .fe-ops__bar-fill{background:#16a34a}.fe-ops__item.is-error .fe-ops__bar-fill{background:var(--fe-danger)}.fe-ops__error{margin-top:6px;font-size:11px;color:var(--fe-danger)}.fe-ops-slide-enter-active,.fe-ops-slide-leave-active{transition:transform .2s,opacity .2s}.fe-ops-slide-enter-from,.fe-ops-slide-leave-to{opacity:0;transform:translateY(10px)}.fe-ctx-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:80;color:var(--fe-text);font-family:var(--fe-font);font-size:14px}.fe-ctx{position:absolute;min-width:180px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);padding:4px;z-index:90;color:var(--fe-text)}.fe-ctx__item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:var(--fe-radius-sm);border:0;background:transparent;color:var(--fe-text);font:inherit;width:100%;text-align:left;cursor:pointer}.fe-ctx__item:hover:not(.is-disabled){background:var(--fe-bg-hover)}.fe-ctx__item.is-danger{color:var(--fe-danger)}.fe-ctx__item.is-disabled{opacity:.45;cursor:not-allowed}.fe-ctx__icon{width:1.2em;text-align:center}.fe-ctx__sep{height:1px;background:var(--fe-border);margin:4px 0}.fe-ctx-enter-active,.fe-ctx-leave-active{transition:opacity .1s}.fe-ctx-enter-from,.fe-ctx-leave-to{opacity:0}.fe-modal__backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:70;display:flex;align-items:center;justify-content:center;background:#0d131b7a;padding:16px}.fe-modal__card{background:var(--fe-bg);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);width:100%;max-height:calc(100vh - 32px);display:flex;flex-direction:column;overflow:hidden}.fe-modal__card--sm{max-width:420px}.fe-modal__card--md{max-width:560px}.fe-modal__card--lg{max-width:800px}.fe-modal__card--xl{max-width:1080px;height:calc(100vh - 64px)}.fe-recents__backdrop{align-items:flex-start!important;padding-top:60px}.fe-recents__panel{background:var(--fe-bg, #fff);border-radius:var(--fe-radius, 8px);box-shadow:var(--fe-shadow, 0 6px 24px rgba(0, 0, 0, .18));width:min(480px,calc(100vw - 32px));max-height:calc(100vh - 96px);display:flex;flex-direction:column;overflow:hidden}.fe-recents__header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid var(--fe-border, #e2e6ed)}.fe-recents__close{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;font-size:22px;line-height:1;cursor:pointer;color:var(--fe-text-muted, #6b7280);padding:0 4px}.fe-recents__close:hover{color:var(--fe-text, #111)}.fe-preview__md-split{display:flex;flex-direction:column;height:100%;width:100%;min-height:0}.fe-preview__md-split-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 14px;background:var(--fe-bg-elev, #f6f7f9);border-bottom:1px solid var(--fe-border, #e2e6ed);flex:0 0 auto}.fe-preview__md-split-label{font-family:var(--fe-font-mono, ui-monospace, monospace);font-size:11px;letter-spacing:.06em;color:var(--fe-text-muted, #6b7280)}.fe-preview__md-split-error{flex:1 1 auto;font-size:12px;color:var(--fe-danger, #dc2626);text-align:center}.fe-preview__md-split-body{flex:1 1 auto;display:grid;grid-template-columns:1fr 1fr;min-height:0}.fe-preview__md-split-input{resize:none;border:0;outline:0;padding:16px 20px;font-family:var(--fe-font-mono, ui-monospace, monospace);font-size:13px;line-height:1.6;background:var(--fe-bg, #fff);color:var(--fe-text, #111);border-right:1px solid var(--fe-border, #e2e6ed);overflow:auto;-moz-tab-size:2;tab-size:2}.fe-preview__md-split-output{overflow:auto;padding:16px 24px;background:var(--fe-bg, #fff)}.fe-preview__md-split-output.fe-preview__md{max-height:none;min-height:0;height:100%}@media (max-width: 900px){.fe-preview__md-split-body{grid-template-columns:1fr;grid-template-rows:1fr 1fr}.fe-preview__md-split-input{border-right:0;border-bottom:1px solid var(--fe-border, #e2e6ed)}}.fe-modal__backdrop--chromeless{background:transparent;padding:0}.fe-modal__card--chromeless{max-width:none;width:100vw;height:100vh;max-height:100vh;border-radius:0;box-shadow:none}.fe-modal__card--chromeless .fe-modal__body{flex:1 1 auto;min-height:0;padding:0}.fe-modal__card--chromeless .fe-preview{align-items:stretch;justify-content:stretch;min-height:0;flex:1 1 auto}.fe-modal__card--chromeless .fe-preview>*{width:100%;height:100%}.fe-modal__head{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--fe-border)}.fe-modal__title{font-size:16px;font-weight:600;margin:0}.fe-modal__close{background:transparent;border:0;color:var(--fe-text-muted);font-size:22px;cursor:pointer;padding:0 4px;line-height:1}.fe-modal__body{padding:16px;overflow:auto;flex:1 1 auto}.fe-modal__actions{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--fe-border);background:var(--fe-bg-elev)}.fe-modal-enter-active,.fe-modal-leave-active{transition:opacity .15s}.fe-modal-enter-from,.fe-modal-leave-to{opacity:0}.fe-input{width:100%;padding:8px 10px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);font:inherit;color:var(--fe-text)}.fe-input:focus-visible{outline:2px solid var(--fe-primary);outline-offset:1px}.fe-input--mono{font-family:var(--fe-font-mono);letter-spacing:.1em}.fe-form{display:flex;flex-direction:column;gap:12px}.fe-form__row{display:flex;align-items:center;gap:8px}.fe-form__row--stack{flex-direction:column;align-items:stretch}.fe-form__error{color:var(--fe-danger);font-size:12px;margin:6px 0 0}.fe-share-result{display:flex;flex-direction:column;gap:12px}.fe-share-result__row label{display:block;font-size:12px;font-weight:600;color:var(--fe-text-muted);margin-bottom:4px}.fe-share-result__copy{display:flex;gap:6px}.fe-preview{display:flex;align-items:center;justify-content:center;width:100%;height:100%;min-height:50vh;background:var(--fe-bg-elev)}.fe-preview__image{max-width:100%;max-height:70vh;object-fit:contain}.fe-preview__video,.fe-preview__audio{max-width:100%;max-height:70vh}.fe-preview__iframe{width:100%;height:70vh;border:0;background:#fff}.fe-preview__office{width:100%;height:78vh;background:var(--fe-bg)}.fe-preview__code-wrap{display:flex;flex-direction:column;width:100%;height:78vh}.fe-preview__code-toolbar{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--fe-bg-hover, #f3f4f6);border-bottom:1px solid var(--fe-border, #e5e7eb);font-size:12px}.fe-preview__code-lang{font-family:var(--fe-font-mono, ui-monospace, monospace);color:var(--fe-text-muted);text-transform:uppercase;letter-spacing:.04em}.fe-preview__code-toolbar>.fe-btn{margin-left:auto}.fe-preview__code-status{font-size:12px;font-weight:500}.fe-preview__code-status--ok{color:#059669}.fe-preview__code-status--err{color:#dc2626;cursor:help}.fe-preview__code-editor{flex:1;min-height:0;overflow:hidden}.fe-preview__code-editor .cm-editor{height:100%;font-size:13px}.fe-preview__code-editor .cm-scroller{font-family:var(--fe-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)}.fe-preview__fallback{text-align:center;color:var(--fe-text-muted);padding:40px 20px}.fe-preview__fallback-icon{font-size:48px;display:block;margin-bottom:12px}.fe-preview__pre{margin:0;padding:16px;width:100%;max-height:70vh;overflow:auto;background:var(--fe-bg);color:var(--fe-text);font-family:var(--fe-font-mono);font-size:13px;line-height:1.5;white-space:pre-wrap;word-wrap:break-word}.fe-preview__code{white-space:pre;word-wrap:normal}.hljs{background:var(--fe-bg);color:var(--fe-text)}.hljs-comment,.hljs-quote{color:var(--fe-text-muted);font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-built_in,.hljs-section,.hljs-meta{color:#c678dd}.hljs-string,.hljs-attr,.hljs-symbol,.hljs-bullet,.hljs-addition,.hljs-link{color:#98c379}.hljs-number,.hljs-literal,.hljs-deletion{color:#d19a66}.hljs-title,.hljs-name,.hljs-selector-id,.hljs-selector-class,.hljs-template-tag,.hljs-template-variable{color:#61aeee}.hljs-type,.hljs-tag{color:#e06c75}.hljs-variable,.hljs-attribute{color:#d19a66}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.fe-preview__md{width:100%;max-height:70vh;overflow:auto;padding:24px 32px;background:var(--fe-bg);color:var(--fe-text);line-height:1.6;font-size:15px}.fe-preview__md h1,.fe-preview__md h2,.fe-preview__md h3,.fe-preview__md h4{margin:1.2em 0 .6em;font-weight:600}.fe-preview__md h1{font-size:1.8em;border-bottom:1px solid var(--fe-border);padding-bottom:.3em}.fe-preview__md h2{font-size:1.4em;border-bottom:1px solid var(--fe-border);padding-bottom:.3em}.fe-preview__md h3{font-size:1.2em}.fe-preview__md p{margin:.8em 0}.fe-preview__md a{color:var(--fe-primary);text-decoration:underline}.fe-preview__md code{font-family:var(--fe-font-mono);background:var(--fe-bg-elev);padding:1px 5px;border-radius:3px;font-size:.92em}.fe-preview__md pre{background:var(--fe-bg-elev);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);padding:12px 16px;overflow:auto;font-size:.9em}.fe-preview__md pre code{background:transparent;padding:0}.fe-preview__md ul,.fe-preview__md ol{padding-left:2em;margin:.8em 0}.fe-preview__md li{margin:.3em 0}.fe-preview__md blockquote{border-left:3px solid var(--fe-border-strong);padding:0 1em;color:var(--fe-text-muted);margin:.8em 0}.fe-preview__md table{border-collapse:collapse;margin:1em 0;width:100%}.fe-preview__md th,.fe-preview__md td{border:1px solid var(--fe-border);padding:6px 10px;text-align:left}.fe-preview__md th{background:var(--fe-bg-elev)}.fe-preview__md img{max-width:100%}.fe-toast{position:absolute;bottom:24px;left:50%;transform:translate(-50%);background:var(--fe-text);color:var(--fe-bg);padding:8px 14px;border-radius:var(--fe-radius);font-size:13px;box-shadow:var(--fe-shadow-sm);z-index:95}.fe-toast-enter-active,.fe-toast-leave-active{transition:opacity .2s,transform .2s}.fe-toast-enter-from,.fe-toast-leave-to{opacity:0;transform:translate(-50%,10px)}@media (max-width: 640px){.fe-list__head,.fe-list__row{grid-template-columns:28px minmax(0,1fr) 90px}.fe-list__col--mod{display:none}.fe-toolbar{padding:8px}.fe-search__input{min-width:120px}}.filex-viewer-3d[data-v-f9492fd4]{width:100%;height:100%;min-height:480px;background:#1a1a1a;display:flex;align-items:center;justify-content:center}.filex-viewer-3d[data-v-f9492fd4] model-viewer{width:100%;height:100%;min-height:480px;background:#1a1a1a;display:block}.filex-viewer-fallback[data-v-f9492fd4]{text-align:center;color:#c8cdd6;padding:32px;max-width:480px}.filex-viewer-fallback__icon[data-v-f9492fd4]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-epub__nav[data-v-12eb7133]{position:absolute;bottom:12px;left:50%;transform:translate(-50%);display:flex;gap:8px;padding:4px 8px;background:var(--fe-bg-elev, rgba(255, 255, 255, .9));border:1px solid var(--fe-border, #e2e6ed);border-radius:6px;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.filex-viewer-epub[data-v-12eb7133]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);position:relative}.filex-viewer-epub__bar[data-v-12eb7133]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-spacer[data-v-12eb7133]{flex:1}.filex-viewer-epub__fs[data-v-12eb7133]{display:inline-block;min-width:40px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-epub__main[data-v-12eb7133]{flex:1;min-height:0;display:flex}.filex-viewer-epub__rendition[data-v-12eb7133]{flex:1;min-height:0}.filex-viewer-epub__toc[data-v-12eb7133]{width:260px;border-right:1px solid var(--fe-border, #e2e6ed);overflow-y:auto;padding:12px 0;background:var(--fe-bg-elev, #f7f8fa)}.filex-viewer-epub__toc ul[data-v-12eb7133]{list-style:none;margin:0;padding:0}.filex-viewer-epub__toc-link[data-v-12eb7133]{display:block;width:100%;text-align:left;background:transparent;border:0;padding:6px 14px;font:inherit;color:inherit;cursor:pointer}.filex-viewer-epub__toc-link[data-v-12eb7133]:hover{background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-epub__toc-link.is-child[data-v-12eb7133]{padding-left:28px;color:var(--fe-text-muted, #5a6475);font-size:12px}.filex-viewer-epub__loading[data-v-12eb7133]{position:absolute;inset:auto 0 0 0;text-align:center;padding:6px;background:#0000000d;font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback[data-v-12eb7133]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-12eb7133]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-12eb7133]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-12eb7133]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn[data-v-12eb7133]:disabled{opacity:.5;cursor:not-allowed}.filex-viewer-mermaid[data-v-939eea2b]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-mermaid__bar[data-v-939eea2b]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-mermaid__zoom[data-v-939eea2b]{min-width:50px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-mermaid__pane[data-v-939eea2b]{flex:1;overflow:hidden;position:relative;cursor:grab;background:var(--fe-bg-elev, #f7f8fa);touch-action:none}.filex-viewer-mermaid__pane[data-v-939eea2b]:active{cursor:grabbing}.filex-viewer-mermaid__surface[data-v-939eea2b]{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;transform-origin:center center;transition:transform .05s linear;-webkit-user-select:none;user-select:none}.filex-viewer-mermaid__surface[data-v-939eea2b] svg{max-width:90%;max-height:90%}.filex-viewer-fallback[data-v-939eea2b]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475);width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.filex-viewer-fallback__icon[data-v-939eea2b]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-939eea2b]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-939eea2b]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-drawio[data-v-2e4b5f3b]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff)}.filex-viewer-drawio__bar[data-v-2e4b5f3b]{display:flex;align-items:center;gap:12px;padding:6px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-drawio__status[data-state=error][data-v-2e4b5f3b]{color:var(--fe-danger, #dc2626)}.filex-viewer-drawio__status[data-state=saved][data-v-2e4b5f3b]{color:#059669}.filex-viewer-drawio__readonly[data-v-2e4b5f3b]{font-style:italic;margin-left:auto}.filex-viewer-drawio__frame[data-v-2e4b5f3b]{flex:1;width:100%;border:0;background:#fafafa;min-height:0}.filex-viewer-fallback[data-v-2e4b5f3b]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-2e4b5f3b]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-tiff__pager[data-v-c6b84f5d]{position:absolute;bottom:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:8px;padding:4px 8px;background:var(--fe-bg-elev, rgba(255, 255, 255, .9));border:1px solid var(--fe-border, #e2e6ed);border-radius:6px;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.filex-viewer-tiff__pages[data-v-c6b84f5d]{font-size:12px;font-variant-numeric:tabular-nums}.filex-viewer-tiff[data-v-c6b84f5d]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff)}.filex-viewer-tiff__bar[data-v-c6b84f5d]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-tiff__pages[data-v-c6b84f5d]{min-width:110px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-tiff__zoom[data-v-c6b84f5d]{min-width:50px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-spacer[data-v-c6b84f5d]{flex:1}.filex-viewer-tiff__pane[data-v-c6b84f5d]{flex:1;overflow:auto;padding:16px;background:#2a2d33;display:flex;align-items:flex-start;justify-content:flex-start}.filex-viewer-tiff__pane canvas[data-v-c6b84f5d]{background:#fff;box-shadow:0 4px 16px #0000004d}.filex-viewer-fallback[data-v-c6b84f5d]{text-align:center;padding:32px;color:#c8cdd6;margin:auto}.filex-viewer-fallback__icon[data-v-c6b84f5d]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-c6b84f5d]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-c6b84f5d]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn[data-v-c6b84f5d]:disabled{opacity:.4;cursor:not-allowed}.filex-viewer-psd[data-v-001123c3]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff)}.filex-viewer-psd__bar[data-v-001123c3]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-spacer[data-v-001123c3]{flex:1}.filex-viewer-psd__dim[data-v-001123c3]{font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-psd__zoom[data-v-001123c3]{min-width:50px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-psd__main[data-v-001123c3]{flex:1;display:flex;min-height:0}.filex-viewer-psd__layers[data-v-001123c3]{width:240px;border-right:1px solid var(--fe-border, #e2e6ed);overflow-y:auto;padding:8px 0;background:var(--fe-bg-elev, #f7f8fa)}.filex-viewer-psd__layers ul[data-v-001123c3]{list-style:none;margin:0;padding:0}.filex-viewer-psd__layers li[data-v-001123c3]{display:flex;align-items:center;gap:6px;padding:4px 12px;font-size:12px}.filex-viewer-psd__layer-vis[data-v-001123c3]{width:14px;text-align:center;color:var(--fe-text-muted, #5a6475)}.filex-viewer-psd__layer-vis[data-hidden="1"][data-v-001123c3]{color:var(--fe-border-strong, #c7ced9)}.filex-viewer-psd__layer-name[data-v-001123c3]{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.filex-viewer-psd__pane[data-v-001123c3]{flex:1;overflow:auto;padding:16px;background:#2a2d33;display:flex;align-items:flex-start;justify-content:flex-start}.filex-viewer-psd__pane canvas[data-v-001123c3]{background:#fff repeating-conic-gradient(#e0e0e0 0% 25%,transparent 0% 50%) 50% / 16px 16px;box-shadow:0 4px 16px #0000004d}.filex-viewer-fallback[data-v-001123c3]{text-align:center;padding:32px;color:#c8cdd6;margin:auto}.filex-viewer-fallback__icon[data-v-001123c3]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-001123c3]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-001123c3]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn.is-active[data-v-001123c3]{background:var(--fe-bg-selected, #dfe8ff);border-color:var(--fe-primary, #3b82f6)}.filex-viewer-ipynb[data-v-eece712d]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-ipynb__bar[data-v-eece712d]{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-ipynb__lang[data-v-eece712d]{font-family:var(--fe-font-mono, monospace);text-transform:uppercase;letter-spacing:.04em}.filex-viewer-ipynb__pane[data-v-eece712d]{flex:1;overflow:auto;padding:16px 24px}.filex-viewer-ipynb__cell[data-v-eece712d]{border:1px solid var(--fe-border, #e2e6ed);border-radius:6px;margin-bottom:16px;overflow:hidden}.filex-viewer-ipynb__cell[data-type=code][data-v-eece712d]{background:var(--fe-bg-elev, #f7f8fa)}.filex-viewer-ipynb__exec[data-v-eece712d]{padding:4px 12px;font-family:var(--fe-font-mono, monospace);font-size:11px;color:var(--fe-text-muted, #5a6475);background:#0000000a}.filex-viewer-ipynb__src[data-v-eece712d]{margin:0;padding:12px;font-family:var(--fe-font-mono, monospace);font-size:12px;line-height:1.5;white-space:pre;overflow-x:auto}.filex-viewer-ipynb__outputs[data-v-eece712d]{border-top:1px dashed var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);padding:8px 12px}.filex-viewer-ipynb__out[data-v-eece712d]{margin:0;padding:4px 0;font-family:var(--fe-font-mono, monospace);font-size:12px;white-space:pre-wrap;word-wrap:break-word}.filex-viewer-ipynb__out[data-type=error][data-v-eece712d]{color:var(--fe-danger, #dc2626)}.filex-viewer-ipynb__img[data-v-eece712d]{display:block;max-width:100%;height:auto;margin:8px 0}.filex-viewer-ipynb__html[data-v-eece712d]{font-size:13px}.filex-viewer-ipynb__md[data-v-eece712d]{padding:12px 16px;font-size:14px;line-height:1.6}.filex-viewer-ipynb__md-raw[data-v-eece712d]{padding:12px;margin:0;font-family:var(--fe-font-mono, monospace);font-size:12px;white-space:pre-wrap}.filex-viewer-fallback[data-v-eece712d]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-eece712d]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-csv[data-v-db55a104]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-csv__bar[data-v-db55a104]{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:12px}.filex-viewer-csv__check[data-v-db55a104]{display:flex;align-items:center;gap:4px;font-size:12px}.filex-viewer-csv__select[data-v-db55a104],.filex-viewer-csv__filter[data-v-db55a104]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:inherit;padding:4px 8px;border-radius:4px;font:inherit;font-size:12px}.filex-viewer-csv__filter[data-v-db55a104]{flex:0 1 240px}.filex-viewer-spacer[data-v-db55a104]{flex:1}.filex-viewer-csv__count[data-v-db55a104]{font-size:11px;color:var(--fe-text-muted, #5a6475);font-variant-numeric:tabular-nums}.filex-viewer-csv__pane[data-v-db55a104]{flex:1;overflow:auto}.filex-viewer-csv__table[data-v-db55a104]{border-collapse:collapse;width:max-content;min-width:100%;font-size:12px;font-family:var(--fe-font-mono, monospace)}.filex-viewer-csv__table th[data-v-db55a104],.filex-viewer-csv__table td[data-v-db55a104]{padding:4px 10px;border:1px solid var(--fe-border, #e2e6ed);white-space:nowrap;max-width:320px;overflow:hidden;text-overflow:ellipsis}.filex-viewer-csv__table th[data-v-db55a104]{background:var(--fe-bg-elev, #f7f8fa);position:sticky;top:0;font-weight:600;text-align:left}.filex-viewer-csv__table tbody tr[data-v-db55a104]:nth-child(2n){background:var(--fe-bg-hover, rgba(0, 0, 0, .02))}.filex-viewer-csv__rownum[data-v-db55a104]{color:var(--fe-text-muted, #5a6475);text-align:right;background:var(--fe-bg-elev, #f7f8fa);font-variant-numeric:tabular-nums;position:sticky;left:0}.filex-viewer-csv__pager[data-v-db55a104]{display:flex;justify-content:center;align-items:center;gap:8px;padding:6px;background:var(--fe-bg-elev, #f7f8fa);border-top:1px solid var(--fe-border, #e2e6ed);font-size:12px}.filex-viewer-csv__pageno[data-v-db55a104]{font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-fallback[data-v-db55a104]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-db55a104]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-db55a104]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-db55a104]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn[data-v-db55a104]:disabled{opacity:.4;cursor:not-allowed}.filex-viewer-archive[data-v-93df7b13]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-archive__pane[data-v-93df7b13]{flex:1;overflow:auto;padding:16px 20px}.filex-viewer-archive__summary[data-v-93df7b13]{font-size:12px;color:var(--fe-text-muted, #5a6475);margin-bottom:12px;font-variant-numeric:tabular-nums}.filex-viewer-archive__table[data-v-93df7b13]{width:100%;border-collapse:collapse;font-size:13px;font-family:var(--fe-font-mono, monospace)}.filex-viewer-archive__table th[data-v-93df7b13],.filex-viewer-archive__table td[data-v-93df7b13]{padding:6px 12px;border-bottom:1px solid var(--fe-border, #e2e6ed);text-align:left}.filex-viewer-archive__table th[data-v-93df7b13]{background:var(--fe-bg-elev, #f7f8fa);font-weight:600;position:sticky;top:0}.filex-viewer-archive__size[data-v-93df7b13]{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--fe-text-muted, #5a6475)}.filex-viewer-archive__icon[data-v-93df7b13]{margin-right:6px}.filex-viewer-archive__table tr[data-dir="1"][data-v-93df7b13]{color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback[data-v-93df7b13]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-93df7b13]{font-size:48px;display:block;margin-bottom:12px}
|
|
1
|
+
.fx-presence[data-v-16daca94]{display:inline-flex;align-items:center;gap:.5rem;max-width:100%}.fx-presence-avatars[data-v-16daca94]{display:inline-flex;align-items:center}.fx-presence-avatar[data-v-16daca94]{position:relative;display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin-left:-.4rem;border-radius:9999px;border:2px solid var(--fx-presence-ring, #ffffff);color:#fff;font-size:.6rem;font-weight:600;line-height:1;-webkit-user-select:none;user-select:none}.fx-presence-avatar[data-v-16daca94]:first-child{margin-left:0}.fx-presence-dot[data-v-16daca94]{position:absolute;right:-1px;bottom:-1px;width:.5rem;height:.5rem;border-radius:9999px;background:#22c55e;border:1.5px solid var(--fx-presence-ring, #ffffff)}.fx-presence-more[data-v-16daca94]{margin-left:.15rem;font-size:.7rem;color:#71717a}.fx-presence--wide[data-v-16daca94]{flex:1 1 auto;min-width:0}.fx-presence-chips[data-v-16daca94]{display:flex;align-items:center;gap:.4rem;overflow-x:auto;min-width:0;padding-bottom:2px;scrollbar-width:thin}.fx-presence-chip[data-v-16daca94]{display:inline-flex;align-items:center;gap:.35rem;flex:0 0 auto;padding:.15rem .5rem .15rem .2rem;border-radius:9999px;background:#f4f4f5;font-size:.75rem;color:#3f3f46;white-space:nowrap}.fx-presence-chip .fx-presence-avatar[data-v-16daca94]{margin-left:0}.fx-presence-chip-name[data-v-16daca94]{font-weight:500}.fx-presence-chip-file[data-v-16daca94]{color:#71717a;max-width:12rem;overflow:hidden;text-overflow:ellipsis}.fx-presence-toggle[data-v-16daca94]{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:none;border-radius:9999px;background:transparent;color:#71717a;font-size:.9rem;line-height:1;cursor:pointer}.fx-presence-toggle[data-v-16daca94]:hover{background:#e4e4e7;color:#3f3f46}.dark{background:#27272a;color:#d4d4d8}.fx-presence-text[data-v-16daca94]{font-size:.75rem;color:#71717a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:14rem}.fx-presence-file[data-v-16daca94]{color:#52525b;font-weight:500}.dark{--fx-presence-ring: #18181b}.filex-tag-picker[data-v-7040583c]{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.filex-tag-picker.is-loading[data-v-7040583c]{opacity:.6;pointer-events:none}.filex-tag[data-v-7040583c]{display:inline-flex;align-items:center;gap:4px;border-radius:999px;padding:2px 10px;font-size:12px;font-weight:500;color:#fff;background:var(--filex-tag-color)}.filex-tag-x[data-v-7040583c]{background:transparent;border:none;color:#ffffffd9;cursor:pointer;padding:0 2px;font-size:14px;line-height:1}.filex-tag-x[data-v-7040583c]:hover{color:#fff}.filex-tag-add input[data-v-7040583c]{border:1px solid var(--filex-border, #d1d5db);border-radius:12px;padding:2px 10px;font-size:12px;width:110px}.filex-tag-add-btn[data-v-7040583c]{border:1px dashed var(--filex-border, #d1d5db);background:transparent;border-radius:999px;padding:2px 10px;font-size:12px;color:var(--filex-text-muted, #6b7280);cursor:pointer}.filex-tag-add-btn[data-v-7040583c]:hover{border-color:var(--filex-accent, #6366f1);color:var(--filex-accent, #6366f1)}.filex-recent[data-v-559f2c71]{background:var(--fe-bg-elev, var(--filex-bg-card, #ffffff));border:1px solid var(--fe-border, var(--filex-border, #e5e7eb));border-radius:8px;padding:12px;font-size:13px}.filex-recent header[data-v-559f2c71]{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.filex-recent h3[data-v-559f2c71]{margin:0;font-size:13px;font-weight:600;color:var(--fe-text, var(--filex-text, #111827))}.filex-recent-refresh[data-v-559f2c71]{background:transparent;border:none;color:var(--fe-text-muted, var(--filex-text-muted, #9ca3af));cursor:pointer;font-size:14px;padding:2px 6px}.filex-recent ul[data-v-559f2c71]{list-style:none;margin:0;padding:0}.filex-recent-item[data-v-559f2c71]{display:flex;justify-content:space-between;align-items:center;width:100%;background:transparent;border:none;padding:6px 8px;cursor:pointer;border-radius:4px;text-align:left}.filex-recent-item[data-v-559f2c71]:hover{background:var(--fe-bg-hover, var(--filex-bg-soft, #f3f4f6))}.filex-recent-name[data-v-559f2c71]{color:var(--fe-text, var(--filex-text, #111827));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.filex-recent-meta[data-v-559f2c71]{color:var(--fe-text-muted, var(--filex-text-muted, #9ca3af));font-size:11px;margin-left:8px;flex-shrink:0}.filex-recent-empty[data-v-559f2c71]{color:var(--fe-text-muted, var(--filex-text-muted, #9ca3af));margin:4px 0 0}.filex-star-btn[data-v-12a2f9c5]{display:inline-flex;align-items:center;gap:6px;background:transparent;border:1px solid transparent;border-radius:6px;padding:4px 8px;color:var(--filex-text-muted, #9ca3af);cursor:pointer;transition:color .12s,background .12s}.filex-star-btn[data-v-12a2f9c5]:hover{color:var(--filex-accent-amber, #f59e0b);background:var(--filex-bg-soft, rgba(0, 0, 0, .04))}.filex-star-btn.is-starred[data-v-12a2f9c5]{color:var(--filex-accent-amber, #f59e0b)}.filex-star-btn.is-compact[data-v-12a2f9c5]{padding:4px}.filex-star-label[data-v-12a2f9c5]{font-size:13px}.fe-preview__code-editor.is-hidden{display:none}.fe-preview__viewer{width:100%;height:100%;min-height:70vh;display:flex;flex-direction:column}.fe-preview .fe-preview__viewer{align-self:stretch}.fe-preview__md-mermaid{display:flex;justify-content:center;margin:16px 0}.fe-preview__md-mermaid svg{max-width:100%;height:auto}.fe-preview__md-math{margin:16px 0;text-align:center;overflow-x:auto}.filex-cv__bg[data-v-4363f1ac]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;background:#0000008c;display:flex;align-items:center;justify-content:center}.filex-cv[data-v-4363f1ac]{width:min(560px,92vw);max-height:80vh;overflow:hidden;display:flex;flex-direction:column;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1f29);border:1px solid var(--fe-border, #e2e6ed);border-radius:12px;box-shadow:0 20px 60px #00000059}.filex-cv__head[data-v-4363f1ac]{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--fe-border, #e2e6ed)}.filex-cv__head h3[data-v-4363f1ac]{margin:0;font-size:14px;font-weight:600}.filex-cv__x[data-v-4363f1ac]{border:0;background:none;cursor:pointer;font-size:16px;color:var(--fe-text-muted, #5a6475)}.filex-cv__msg[data-v-4363f1ac]{padding:28px;text-align:center;color:var(--fe-text-muted, #5a6475)}.filex-cv__ok[data-v-4363f1ac]{color:#059669}.filex-cv__src[data-v-4363f1ac]{padding:12px 16px 0;font-size:13px;color:var(--fe-text-muted, #5a6475)}.filex-cv__search[data-v-4363f1ac]{margin:8px 16px;padding:8px 10px;border:1px solid var(--fe-border, #e2e6ed);border-radius:8px;background:var(--fe-bg-elev, #f7f8fa);color:inherit;font-size:13px}.filex-cv__list[data-v-4363f1ac]{flex:1;overflow-y:auto;padding:4px 12px 12px;display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:8px}.filex-cv__fmt[data-v-4363f1ac]{display:flex;flex-direction:column;gap:2px;align-items:flex-start;padding:8px 10px;cursor:pointer;text-align:left;border:1px solid var(--fe-border, #e2e6ed);border-radius:8px;background:var(--fe-bg-elev, #f7f8fa);color:inherit}.filex-cv__fmt small[data-v-4363f1ac]{color:var(--fe-text-muted, #5a6475);font-size:11px}.filex-cv__fmt.is-sel[data-v-4363f1ac]{border-color:#44c878;background:#44c8781f}.filex-cv__empty[data-v-4363f1ac]{grid-column:1 / -1;text-align:center;color:var(--fe-text-muted, #5a6475);padding:16px}.filex-cv__err[data-v-4363f1ac]{padding:0 16px;color:var(--fe-danger, #dc2626);font-size:13px}.filex-cv__foot[data-v-4363f1ac]{padding:12px 16px;border-top:1px solid var(--fe-border, #e2e6ed);text-align:right}.filex-cv__convert[data-v-4363f1ac]{padding:8px 18px;border:0;border-radius:8px;cursor:pointer;background:#44c878;color:#03200f;font-weight:600;font-size:13px}.filex-cv__convert[data-v-4363f1ac]:disabled{opacity:.5;cursor:default}.filex-cv__frame[data-v-4363f1ac]{position:absolute;width:0;height:0;border:0;left:-9999px}.fx-perm-overlay[data-v-23e7820c]{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000;font-family:var(--fe-font)}.fx-perm-modal[data-v-23e7820c]{display:flex;flex-direction:column;background:var(--fe-bg);color:var(--fe-text);width:min(520px,94vw);max-height:86vh;border:1px solid var(--fe-border);border-radius:var(--fe-radius-lg, 14px);box-shadow:var(--fe-shadow);font-size:14px;overflow:hidden}.fx-perm-head[data-v-23e7820c]{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:16px 18px 12px;flex:none}.fx-perm-title[data-v-23e7820c]{display:flex;align-items:center;gap:10px;min-width:0}.fx-perm-ico[data-v-23e7820c]{font-size:22px;line-height:1}.fx-perm-titletext[data-v-23e7820c]{display:flex;flex-direction:column;min-width:0}.fx-perm-title h3[data-v-23e7820c]{margin:0;font-size:15px;font-weight:600;color:var(--fe-text)}.fx-perm-sub[data-v-23e7820c]{font-size:12px;color:var(--fe-text);max-width:340px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fx-perm-subdim[data-v-23e7820c]{color:var(--fe-text-muted)}.fx-perm-x[data-v-23e7820c]{background:none;border:none;font-size:17px;cursor:pointer;color:var(--fe-text-muted);flex:none;line-height:1;padding:2px 4px;border-radius:6px}.fx-perm-x[data-v-23e7820c]:hover{color:var(--fe-text);background:var(--fe-bg-hover)}.fx-perm-tabs[data-v-23e7820c]{display:flex;gap:2px;padding:0 18px;border-bottom:1px solid var(--fe-border);flex:none}.fx-perm-tab[data-v-23e7820c]{background:none;border:none;border-bottom:2px solid transparent;padding:8px 12px;cursor:pointer;color:var(--fe-text-muted);font-size:13px;font-family:inherit;font-weight:500}.fx-perm-tab[data-v-23e7820c]:hover{color:var(--fe-text)}.fx-perm-tab.is-active[data-v-23e7820c]{color:var(--fe-primary);border-bottom-color:var(--fe-primary)}.fx-perm-body[data-v-23e7820c]{flex:1 1 auto;overflow-y:auto;padding:14px 18px 18px}.fx-perm-addcard[data-v-23e7820c]{padding:12px;border-radius:var(--fe-radius-md, 10px);background:var(--fe-bg-elev);border:1px solid var(--fe-border)}.fx-perm-section[data-v-23e7820c]{margin-top:16px}.fx-perm-section h4[data-v-23e7820c]{margin:0 0 8px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--fe-text-muted)}.fx-perm-empty[data-v-23e7820c]{color:var(--fe-text-muted);font-size:13px;padding:8px 2px}.fx-perm-person[data-v-23e7820c]{display:flex;align-items:center;gap:10px;padding:7px 2px}.fx-perm-person+.fx-perm-person[data-v-23e7820c]{border-top:1px solid var(--fe-border)}.fx-perm-inh[data-v-23e7820c]{color:var(--fe-text-muted)}.fx-perm-av[data-v-23e7820c]{width:28px;height:28px;flex:none;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--fe-primary);color:var(--fe-text-on-primary, #fff);font-size:12px;font-weight:600}.fx-perm-av--dim[data-v-23e7820c]{background:var(--fe-bg-hover);color:var(--fe-text-muted)}.fx-perm-user[data-v-23e7820c]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--fe-text);min-width:0}.fx-perm-from[data-v-23e7820c]{font-size:11px;color:var(--fe-text-muted);white-space:nowrap}.fx-perm-badge[data-v-23e7820c]{font-size:11px;padding:2px 9px;border-radius:999px;background:var(--fe-bg-hover);color:var(--fe-text)}.fx-perm-sel[data-v-23e7820c],.fx-perm-input[data-v-23e7820c]{padding:7px 9px;border-radius:var(--fe-radius-sm, 7px);border:1px solid var(--fe-border);background:var(--fe-bg);color:var(--fe-text);font-size:13px;font-family:inherit}.fx-perm-sel--sm[data-v-23e7820c]{padding:5px 7px;font-size:12px}.fx-perm-sel[data-v-23e7820c]:focus,.fx-perm-input[data-v-23e7820c]:focus{outline:none;border-color:var(--fe-primary)}.fx-perm-add[data-v-23e7820c]{display:flex;gap:8px;align-items:stretch}.fx-perm-emailwrap[data-v-23e7820c]{position:relative;flex:1;min-width:120px}.fx-perm-input[data-v-23e7820c]{width:100%;box-sizing:border-box}.fx-perm-suggest[data-v-23e7820c]{position:absolute;top:calc(100% + 3px);left:0;right:0;z-index:5;margin:0;padding:4px;list-style:none;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm, 7px);box-shadow:var(--fe-shadow);max-height:210px;overflow:auto}.fx-perm-suggest li[data-v-23e7820c]{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;cursor:pointer}.fx-perm-suggest li[data-v-23e7820c]:hover{background:var(--fe-bg-hover)}.fx-perm-suggest-av[data-v-23e7820c]{width:24px;height:24px;flex:none;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--fe-bg-hover);color:var(--fe-text);font-size:11px;font-weight:600}.fx-perm-suggest-txt[data-v-23e7820c]{display:flex;flex-direction:column;min-width:0}.fx-perm-suggest-name[data-v-23e7820c]{color:var(--fe-text);font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fx-perm-suggest-meta[data-v-23e7820c]{color:var(--fe-text-muted);font-size:11px}.fx-perm-check[data-v-23e7820c]{display:inline-flex;gap:6px;align-items:center;font-size:13px;color:var(--fe-text);cursor:pointer}.fx-perm-btn[data-v-23e7820c]{padding:7px 13px;border-radius:var(--fe-radius-sm, 7px);border:1px solid var(--fe-border);background:var(--fe-bg);color:var(--fe-text);font-size:13px;font-family:inherit;cursor:pointer;white-space:nowrap}.fx-perm-btn[data-v-23e7820c]:hover:not(:disabled){background:var(--fe-bg-hover)}.fx-perm-btn[data-v-23e7820c]:disabled{opacity:.55;cursor:default}.fx-perm-btn--sm[data-v-23e7820c]{padding:5px 10px;font-size:12px}.fx-perm-btn--primary[data-v-23e7820c]{background:var(--fe-primary);border-color:var(--fe-primary);color:var(--fe-text-on-primary, #fff)}.fx-perm-btn--primary[data-v-23e7820c]:hover:not(:disabled){background:var(--fe-primary-hover, var(--fe-primary));filter:brightness(1.05)}.fx-perm-btn--ghost[data-v-23e7820c]{background:none;border-color:transparent;color:var(--fe-primary);padding-left:2px}.fx-perm-btn--ghost[data-v-23e7820c]:hover:not(:disabled){background:none;text-decoration:underline}.fx-perm-del[data-v-23e7820c]{background:none;border:none;color:var(--fe-danger);cursor:pointer;font-size:14px;flex:none;padding:2px 4px}.fx-perm-del[data-v-23e7820c]:hover:not(:disabled){filter:brightness(1.15)}.fx-perm-invite[data-v-23e7820c]{margin-top:10px;padding-top:10px;border-top:1px dashed var(--fe-border)}.fx-perm-invite-actions[data-v-23e7820c]{display:flex;flex-direction:column;gap:8px;margin-top:6px}.fx-perm-invite-row[data-v-23e7820c]{display:flex;gap:8px;align-items:stretch}.fx-perm-invite-row .fx-perm-btn--primary[data-v-23e7820c]{flex:1}.fx-perm-share-opts[data-v-23e7820c]{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.fx-perm-expiry[data-v-23e7820c]{display:inline-flex;gap:6px;align-items:center;font-size:13px}.fx-perm-share-opts .fx-perm-btn--primary[data-v-23e7820c]{margin-left:auto}.fx-perm-result[data-v-23e7820c]{margin-top:12px;padding-top:12px;border-top:1px solid var(--fe-border)}.fx-perm-linkrow[data-v-23e7820c]{display:flex;gap:8px;align-items:center}.fx-perm-link[data-v-23e7820c]{color:var(--fe-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;text-decoration:none}.fx-perm-link[data-v-23e7820c]:hover{text-decoration:underline}.fx-perm-pin[data-v-23e7820c]{margin:8px 0 0;font-size:13px;color:var(--fe-text);display:flex;align-items:center;gap:8px}.fx-perm-pin code[data-v-23e7820c],.fx-perm-reveal code[data-v-23e7820c]{font-family:var(--fe-font-mono, monospace);background:var(--fe-bg-hover);padding:1px 6px;border-radius:5px}.fx-perm-mailrow[data-v-23e7820c]{display:flex;gap:8px;margin-top:10px}.fx-perm-mailrow .fx-perm-input[data-v-23e7820c]{flex:1}.fx-perm-hint[data-v-23e7820c]{font-size:13px;color:var(--fe-text-muted);margin:10px 0 0}.fx-perm-sharebtn[data-v-23e7820c]{display:flex;width:100%;align-items:center;justify-content:center;gap:6px;margin-top:8px}.fx-perm-dropintro[data-v-23e7820c]{margin:0 0 12px;line-height:1.4}.fx-perm-advtoggle[data-v-23e7820c]{margin-top:10px;padding-left:2px}.fx-perm-adv[data-v-23e7820c]{margin-top:8px;padding-top:10px;border-top:1px dashed var(--fe-border);display:flex;flex-direction:column;gap:8px}.fx-perm-adv-row[data-v-23e7820c]{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:13px}.fx-perm-input--sm[data-v-23e7820c]{width:130px;padding:5px 8px;font-size:12px}.fx-perm-warn[data-v-23e7820c]{background:#f59e0b24;border:1px solid rgba(245,158,11,.4);border-radius:var(--fe-radius-sm, 7px);padding:8px 10px;font-size:13px;margin-bottom:10px;color:var(--fe-text)}.fx-perm-notice[data-v-23e7820c]{margin-top:8px;font-size:13px;color:var(--fe-text-muted)}.fx-perm-reveal[data-v-23e7820c]{margin-top:8px;font-size:13px;word-break:break-all;color:var(--fe-text)}.fx-perm-muted[data-v-23e7820c]{color:var(--fe-text-muted);font-size:13px}:root{--fe-bg: #ffffff;--fe-bg-elev: #f7f8fa;--fe-bg-hover: #edf0f5;--fe-bg-selected: #dfe8ff;--fe-border: #e2e6ed;--fe-border-strong: #c7ced9;--fe-text: #1a1e27;--fe-text-muted: #5a6475;--fe-text-on-primary: #ffffff;--fe-primary: #3b82f6;--fe-primary-hover: #2563eb;--fe-danger: #dc2626;--fe-danger-hover: #b91c1c;--fe-shadow: 0 10px 32px rgba(15, 23, 42, .14);--fe-shadow-sm: 0 2px 6px rgba(15, 23, 42, .08);--fe-radius: 8px;--fe-radius-sm: 4px;--fe-radius-lg: 12px;--fe-font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--fe-font-mono: ui-monospace, "SF Mono", Consolas, Menlo, monospace;--fe-gap: 12px}.fe--theme-dark,:root[data-theme=dark] .fe,.fe.fe--theme-dark,:root.dark,.dark,:root.dark .fe,.dark .fe,.fe-ctx-backdrop--theme-dark,.fe-ctx-backdrop--theme-auto[data-prefers-dark="1"]{--fe-bg: #0f1419;--fe-bg-elev: #161c25;--fe-bg-hover: #1f2733;--fe-bg-selected: #23324a;--fe-border: #2a323e;--fe-border-strong: #3a4453;--fe-text: #e5e9f0;--fe-text-muted: #8b95a7;--fe-primary: #60a5fa;--fe-primary-hover: #3b82f6;--fe-danger: #f87171;--fe-danger-hover: #ef4444;--fe-shadow: 0 12px 32px rgba(0, 0, 0, .45);--fe-shadow-sm: 0 2px 6px rgba(0, 0, 0, .25)}@media (prefers-color-scheme: dark){.fe:not(.fe--theme-light),.fe-ctx-backdrop--theme-auto:not(.fe-ctx-backdrop--theme-light){--fe-bg: #0f1419;--fe-bg-elev: #161c25;--fe-bg-hover: #1f2733;--fe-bg-selected: #23324a;--fe-border: #2a323e;--fe-border-strong: #3a4453;--fe-text: #e5e9f0;--fe-text-muted: #8b95a7;--fe-primary: #60a5fa;--fe-primary-hover: #3b82f6;--fe-danger: #f87171;--fe-danger-hover: #ef4444;--fe-shadow: 0 12px 32px rgba(0, 0, 0, .45);--fe-shadow-sm: 0 2px 6px rgba(0, 0, 0, .25)}}.fe{position:relative;display:flex;flex-direction:column;min-height:420px;height:100%;background:var(--fe-bg);color:var(--fe-text);font-family:var(--fe-font);font-size:14px;border:1px solid var(--fe-border);border-radius:var(--fe-radius);overflow:hidden;outline:none}.fe *{box-sizing:border-box}.fe__body{flex:1 1 auto;overflow:auto;background:var(--fe-bg)}.fe__presence{flex:0 0 auto;padding:.25rem .75rem;border-bottom:1px solid var(--fe-border, rgba(0, 0, 0, .06))}.fe__loading{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;min-height:240px;height:100%;color:var(--fe-text-muted)}.fe__spinner{width:34px;height:34px;border-radius:50%;border:3px solid color-mix(in srgb,var(--fe-text-muted) 30%,transparent);border-top-color:var(--fe-primary);animation:fe-spin .7s linear infinite}.fe__loading-text{margin:0;font-size:13px}@keyframes fe-spin{to{transform:rotate(360deg)}}.fe__notfound{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-height:240px;height:100%;color:var(--fe-text-muted);text-align:center;padding:24px}.fe__notfound-icon{font-size:40px;filter:grayscale(1);opacity:.6}.fe__notfound-title{margin:4px 0 0;font-size:15px;font-weight:600;color:var(--fe-text)}.fe__notfound-path{margin:0;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;word-break:break-all;max-width:480px}.fe__notfound-desc{margin:0 0 10px;font-size:13px}.fe__file-input{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}.fe-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:var(--fe-bg-elev);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);color:var(--fe-text);font:inherit;cursor:pointer;transition:background .12s,border-color .12s;white-space:nowrap}.fe-btn:hover:not(:disabled){background:var(--fe-bg-hover);border-color:var(--fe-border-strong)}.fe-btn:disabled{opacity:.5;cursor:not-allowed}.fe-btn--primary{background:var(--fe-primary);border-color:var(--fe-primary);color:var(--fe-text-on-primary)}.fe-btn--primary:hover:not(:disabled){background:var(--fe-primary-hover);border-color:var(--fe-primary-hover)}.fe-btn--danger{background:var(--fe-danger);border-color:var(--fe-danger);color:var(--fe-text-on-primary)}.fe-btn--danger:hover:not(:disabled){background:var(--fe-danger-hover);border-color:var(--fe-danger-hover)}.fe-btn--icon-only{padding:6px 8px}.fe-btn.is-active{background:var(--fe-bg-selected);border-color:var(--fe-primary)}.fe-btn__label{line-height:1}.fe-icon{font-size:1.05em;line-height:1}.fe-toolbar{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--fe-bg-elev);border-bottom:1px solid var(--fe-border);flex-wrap:wrap}.fe-toolbar__primary{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}.fe-toolbar__spacer{flex:1 1 auto}.fe-toolbar__search-group{display:inline-flex;align-items:center;gap:4px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);padding:2px}.fe-toolbar__search-group .fe-search__input{border:0;background:transparent;padding:4px 8px}.fe-toolbar__search-group .fe-btn{border:0;background:transparent;padding:4px 6px}.fe-toolbar__search-group .fe-btn:hover:not(:disabled){background:var(--fe-bg-hover)}.fe-toolbar__view{display:inline-flex;gap:2px;padding:2px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm)}.fe-toolbar__view .fe-btn{border:0;background:transparent}.fe-toolbar__view .fe-btn.is-active{background:var(--fe-bg-selected)}.fe-search{position:relative}.fe-search__input{background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);padding:6px 10px;font:inherit;color:var(--fe-text);min-width:200px}.fe-search__input:focus-visible{outline:2px solid var(--fe-primary);outline-offset:1px}.fe-breadcrumb{display:flex;align-items:center;gap:4px;flex-wrap:wrap;padding:6px 12px;background:var(--fe-bg);border-bottom:1px solid var(--fe-border);font-size:13px;color:var(--fe-text-muted)}.fe-breadcrumb__crumb{display:inline-flex;align-items:center;gap:4px;background:transparent;border:0;color:inherit;padding:2px 6px;border-radius:var(--fe-radius-sm);cursor:pointer;font:inherit}.fe-breadcrumb__crumb:hover{background:var(--fe-bg-hover);color:var(--fe-text)}.fe-breadcrumb__crumb.is-last{color:var(--fe-text);font-weight:600}.fe-breadcrumb__sep{color:var(--fe-text-muted)}.fe-breadcrumb__edit{margin-left:auto;background:none;border:1px solid transparent;color:var(--fe-text-muted);cursor:pointer;font-size:14px;line-height:1;padding:4px 8px;border-radius:4px}.fe-breadcrumb__edit:hover{background:var(--fe-bg-hover);color:var(--fe-text);border-color:var(--fe-border)}.fe-breadcrumb__input{flex:1;background:var(--fe-bg);color:var(--fe-text);border:1px solid var(--fe-accent, #2563eb);border-radius:4px;padding:4px 8px;font-family:var(--fe-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:13px;outline:none}.fe-list{display:flex;flex-direction:column}.fe-list__head{display:grid;grid-template-columns:32px minmax(0,1fr) 120px 180px;gap:8px;padding:8px 12px;font-weight:600;color:var(--fe-text-muted);font-size:12px;text-transform:uppercase;letter-spacing:.04em;background:var(--fe-bg-elev);border-bottom:1px solid var(--fe-border)}.fe-list__body{display:flex;flex-direction:column}.fe-list__row{display:grid;grid-template-columns:32px minmax(0,1fr) 120px 180px;gap:8px;padding:8px 12px;align-items:center;cursor:pointer;border-bottom:1px solid var(--fe-border);transition:background .08s;-webkit-user-select:none;user-select:none}.fe-list__row:hover{background:var(--fe-bg-hover)}.fe-list__row.is-selected{background:var(--fe-bg-selected)}.fe-list__row.is-trash{opacity:.7}.fe-list__row.is-clipped,.fe-grid__card.is-clipped{opacity:.45;font-style:italic}.fe-list__row:focus-visible{outline:2px solid var(--fe-primary);outline-offset:-2px}.fe-list__col--star{display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .12s}.fe-list__row:hover .fe-list__col--star,.fe-list__row:focus-within .fe-list__col--star,.fe-list__col--star:has(.is-starred){opacity:1}.fe-list__col--star .filex-star-btn.is-starred{color:var(--fe-warning, #f59e0b)}.fe-list__col--name{display:flex;align-items:center;gap:8px;min-width:0}.fe-list__icon{flex-shrink:0;font-size:16px}.fe-list__name-wrap{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}.fe-list__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe-list__parent{font-size:11px;color:var(--fe-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px}.fe-list__col--size,.fe-list__col--mod{color:var(--fe-text-muted);font-size:13px}.fe-list__empty{padding:40px 20px;text-align:center;color:var(--fe-text-muted)}.fe-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:var(--fe-gap);padding:var(--fe-gap)}.fe-grid__card{display:flex;flex-direction:column;align-items:stretch;padding:8px;border:1px solid var(--fe-border);border-radius:var(--fe-radius);background:var(--fe-bg-elev);cursor:pointer;transition:background .08s,border-color .08s;-webkit-user-select:none;user-select:none}.fe-grid__card:hover{background:var(--fe-bg-hover);border-color:var(--fe-border-strong)}.fe-grid__card.is-selected{background:var(--fe-bg-selected);border-color:var(--fe-primary)}.fe-grid__card.is-trash{opacity:.7}.fe-grid__thumb{display:flex;align-items:center;justify-content:center;aspect-ratio:1 / 1;background:var(--fe-bg);border-radius:var(--fe-radius-sm);margin-bottom:8px;overflow:hidden}.fe-grid__thumb img{width:100%;height:100%;object-fit:cover}.fe-grid__icon{font-size:32px}.fe-grid__label{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fe-grid__meta{font-size:11px;color:var(--fe-text-muted);margin-top:2px}.fe-grid__parent{font-size:11px;color:var(--fe-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px;font-style:italic}.fe-grid__empty{grid-column:1 / -1;padding:40px 20px;text-align:center;color:var(--fe-text-muted)}.fe__dragover{position:absolute;top:0;right:0;bottom:0;left:0;z-index:30;display:flex;align-items:center;justify-content:center;background:#3b82f61f;border:3px dashed var(--fe-primary);pointer-events:none}.fe__dragover-card{background:var(--fe-bg);border-radius:var(--fe-radius-lg);padding:24px 40px;box-shadow:var(--fe-shadow);text-align:center}.fe__dragover-card .fe-icon{font-size:32px;display:block;margin-bottom:8px}.fe-upload{position:absolute;right:16px;bottom:16px;width:min(360px,calc(100% - 32px));background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);z-index:40;max-height:40vh;display:flex;flex-direction:column;overflow:hidden}.fe-upload__header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:var(--fe-bg-elev);border-bottom:1px solid var(--fe-border);font-size:13px}.fe-upload__count{background:var(--fe-primary);color:var(--fe-text-on-primary);font-size:12px;padding:1px 7px;border-radius:999px}.fe-upload__list{list-style:none;padding:0;margin:0;overflow:auto}.fe-upload__item{padding:10px 14px;border-bottom:1px solid var(--fe-border)}.fe-upload__item:last-child{border-bottom:0}.fe-upload__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;margin-bottom:4px}.fe-upload__bar{background:var(--fe-bg-elev);border-radius:99px;height:6px;overflow:hidden;margin-bottom:4px}.fe-upload__bar-fill{background:var(--fe-primary);height:100%;transition:width .2s}.fe-upload__item.is-error .fe-upload__bar-fill,.fe-upload__item.is-aborted .fe-upload__bar-fill{background:var(--fe-danger)}.fe-upload__item.is-done .fe-upload__bar-fill{background:#16a34a}.fe-upload__meta{display:flex;align-items:center;justify-content:space-between;gap:6px;font-size:11px;color:var(--fe-text-muted)}.fe-upload__cancel{background:transparent;border:0;color:var(--fe-primary);cursor:pointer;font:inherit}.fe-upload-slide-enter-active,.fe-upload-slide-leave-active{transition:transform .2s,opacity .2s}.fe-upload-slide-enter-from,.fe-upload-slide-leave-to{opacity:0;transform:translateY(10px)}.fe-ops{position:absolute;left:16px;bottom:16px;width:min(320px,calc(100% - 32px));display:flex;flex-direction:column;gap:8px;z-index:40}.fe-ops__item{background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);padding:10px 14px;font-size:13px}.fe-ops__item.is-done{border-color:#16a34a}.fe-ops__item.is-error{border-color:var(--fe-danger)}.fe-ops__row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}.fe-ops__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto}.fe-ops__dismiss{background:transparent;border:0;color:var(--fe-text-muted);cursor:pointer;font-size:18px;line-height:1;padding:0 4px}.fe-ops__bar{background:var(--fe-bg-elev);border-radius:99px;height:6px;overflow:hidden}.fe-ops__bar-fill{background:var(--fe-primary);height:100%;transition:width .25s}.fe-ops__item.is-done .fe-ops__bar-fill{background:#16a34a}.fe-ops__item.is-error .fe-ops__bar-fill{background:var(--fe-danger)}.fe-ops__error{margin-top:6px;font-size:11px;color:var(--fe-danger)}.fe-ops-slide-enter-active,.fe-ops-slide-leave-active{transition:transform .2s,opacity .2s}.fe-ops-slide-enter-from,.fe-ops-slide-leave-to{opacity:0;transform:translateY(10px)}.fe-ctx-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:80;color:var(--fe-text);font-family:var(--fe-font);font-size:14px}.fe-ctx{position:absolute;min-width:180px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);padding:4px;z-index:90;color:var(--fe-text)}.fe-ctx__item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:var(--fe-radius-sm);border:0;background:transparent;color:var(--fe-text);font:inherit;width:100%;text-align:left;cursor:pointer}.fe-ctx__item:hover:not(.is-disabled){background:var(--fe-bg-hover)}.fe-ctx__item.is-danger{color:var(--fe-danger)}.fe-ctx__item.is-disabled{opacity:.45;cursor:not-allowed}.fe-ctx__icon{width:1.2em;text-align:center}.fe-ctx__sep{height:1px;background:var(--fe-border);margin:4px 0}.fe-ctx-enter-active,.fe-ctx-leave-active{transition:opacity .1s}.fe-ctx-enter-from,.fe-ctx-leave-to{opacity:0}.fe-modal__backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:70;display:flex;align-items:center;justify-content:center;background:#0d131b7a;padding:16px}.fe-modal__card{background:var(--fe-bg);border-radius:var(--fe-radius);box-shadow:var(--fe-shadow);width:100%;max-height:calc(100vh - 32px);display:flex;flex-direction:column;overflow:hidden}.fe-modal__card--sm{max-width:420px}.fe-modal__card--md{max-width:560px}.fe-modal__card--lg{max-width:800px}.fe-modal__card--xl{max-width:1080px;height:calc(100vh - 64px)}.fe-recents__backdrop{align-items:flex-start!important;padding-top:60px}.fe-recents__panel{background:var(--fe-bg, #fff);border-radius:var(--fe-radius, 8px);box-shadow:var(--fe-shadow, 0 6px 24px rgba(0, 0, 0, .18));width:min(480px,calc(100vw - 32px));max-height:calc(100vh - 96px);display:flex;flex-direction:column;overflow:hidden}.fe-recents__header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid var(--fe-border, #e2e6ed)}.fe-recents__close{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;font-size:22px;line-height:1;cursor:pointer;color:var(--fe-text-muted, #6b7280);padding:0 4px}.fe-recents__close:hover{color:var(--fe-text, #111)}.fe-preview__md-split{display:flex;flex-direction:column;height:100%;width:100%;min-height:0}.fe-preview__md-split-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 14px;background:var(--fe-bg-elev, #f6f7f9);border-bottom:1px solid var(--fe-border, #e2e6ed);flex:0 0 auto}.fe-preview__md-split-label{font-family:var(--fe-font-mono, ui-monospace, monospace);font-size:11px;letter-spacing:.06em;color:var(--fe-text-muted, #6b7280)}.fe-preview__md-split-error{flex:1 1 auto;font-size:12px;color:var(--fe-danger, #dc2626);text-align:center}.fe-preview__md-split-body{flex:1 1 auto;display:grid;grid-template-columns:1fr 1fr;min-height:0}.fe-preview__md-split-input{resize:none;border:0;outline:0;padding:16px 20px;font-family:var(--fe-font-mono, ui-monospace, monospace);font-size:13px;line-height:1.6;background:var(--fe-bg, #fff);color:var(--fe-text, #111);border-right:1px solid var(--fe-border, #e2e6ed);overflow:auto;-moz-tab-size:2;tab-size:2}.fe-preview__md-split-output{overflow:auto;padding:16px 24px;background:var(--fe-bg, #fff)}.fe-preview__md-split-output.fe-preview__md{max-height:none;min-height:0;height:100%}@media (max-width: 900px){.fe-preview__md-split-body{grid-template-columns:1fr;grid-template-rows:1fr 1fr}.fe-preview__md-split-input{border-right:0;border-bottom:1px solid var(--fe-border, #e2e6ed)}}.fe-modal__backdrop--chromeless{background:transparent;padding:0}.fe-modal__card--chromeless{max-width:none;width:100vw;height:100vh;max-height:100vh;border-radius:0;box-shadow:none}.fe-modal__card--chromeless .fe-modal__body{flex:1 1 auto;min-height:0;padding:0}.fe-modal__card--chromeless .fe-preview{align-items:stretch;justify-content:stretch;min-height:0;flex:1 1 auto}.fe-modal__card--chromeless .fe-preview>*{width:100%;height:100%}.fe-modal__head{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--fe-border)}.fe-modal__title{font-size:16px;font-weight:600;margin:0}.fe-modal__close{background:transparent;border:0;color:var(--fe-text-muted);font-size:22px;cursor:pointer;padding:0 4px;line-height:1}.fe-modal__body{padding:16px;overflow:auto;flex:1 1 auto}.fe-modal__actions{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--fe-border);background:var(--fe-bg-elev)}.fe-modal-enter-active,.fe-modal-leave-active{transition:opacity .15s}.fe-modal-enter-from,.fe-modal-leave-to{opacity:0}.fe-input{width:100%;padding:8px 10px;background:var(--fe-bg);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);font:inherit;color:var(--fe-text)}.fe-input:focus-visible{outline:2px solid var(--fe-primary);outline-offset:1px}.fe-input--mono{font-family:var(--fe-font-mono);letter-spacing:.1em}.fe-form{display:flex;flex-direction:column;gap:12px}.fe-form__row{display:flex;align-items:center;gap:8px}.fe-form__row--stack{flex-direction:column;align-items:stretch}.fe-form__error{color:var(--fe-danger);font-size:12px;margin:6px 0 0}.fe-share-result{display:flex;flex-direction:column;gap:12px}.fe-share-result__row label{display:block;font-size:12px;font-weight:600;color:var(--fe-text-muted);margin-bottom:4px}.fe-share-result__copy{display:flex;gap:6px}.fe-preview{display:flex;align-items:center;justify-content:center;width:100%;height:100%;min-height:50vh;background:var(--fe-bg-elev)}.fe-preview__image{max-width:100%;max-height:70vh;object-fit:contain}.fe-preview__video,.fe-preview__audio{max-width:100%;max-height:70vh}.fe-preview__iframe{width:100%;height:70vh;border:0;background:#fff}.fe-preview__office{width:100%;height:78vh;background:var(--fe-bg)}.fe-preview__code-wrap{display:flex;flex-direction:column;width:100%;height:78vh}.fe-preview__code-toolbar{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--fe-bg-hover, #f3f4f6);border-bottom:1px solid var(--fe-border, #e5e7eb);font-size:12px}.fe-preview__code-lang{font-family:var(--fe-font-mono, ui-monospace, monospace);color:var(--fe-text-muted);text-transform:uppercase;letter-spacing:.04em}.fe-preview__code-toolbar>.fe-btn{margin-left:auto}.fe-preview__code-status{font-size:12px;font-weight:500}.fe-preview__code-status--ok{color:#059669}.fe-preview__code-status--err{color:#dc2626;cursor:help}.fe-preview__code-editor{flex:1;min-height:0;overflow:hidden}.fe-preview__code-editor .cm-editor{height:100%;font-size:13px}.fe-preview__code-editor .cm-scroller{font-family:var(--fe-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)}.fe-preview__fallback{text-align:center;color:var(--fe-text-muted);padding:40px 20px}.fe-preview__fallback-icon{font-size:48px;display:block;margin-bottom:12px}.fe-preview__pre{margin:0;padding:16px;width:100%;max-height:70vh;overflow:auto;background:var(--fe-bg);color:var(--fe-text);font-family:var(--fe-font-mono);font-size:13px;line-height:1.5;white-space:pre-wrap;word-wrap:break-word}.fe-preview__code{white-space:pre;word-wrap:normal}.hljs{background:var(--fe-bg);color:var(--fe-text)}.hljs-comment,.hljs-quote{color:var(--fe-text-muted);font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-built_in,.hljs-section,.hljs-meta{color:#c678dd}.hljs-string,.hljs-attr,.hljs-symbol,.hljs-bullet,.hljs-addition,.hljs-link{color:#98c379}.hljs-number,.hljs-literal,.hljs-deletion{color:#d19a66}.hljs-title,.hljs-name,.hljs-selector-id,.hljs-selector-class,.hljs-template-tag,.hljs-template-variable{color:#61aeee}.hljs-type,.hljs-tag{color:#e06c75}.hljs-variable,.hljs-attribute{color:#d19a66}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.fe-preview__md{width:100%;max-height:70vh;overflow:auto;padding:24px 32px;background:var(--fe-bg);color:var(--fe-text);line-height:1.6;font-size:15px}.fe-preview__md h1,.fe-preview__md h2,.fe-preview__md h3,.fe-preview__md h4{margin:1.2em 0 .6em;font-weight:600}.fe-preview__md h1{font-size:1.8em;border-bottom:1px solid var(--fe-border);padding-bottom:.3em}.fe-preview__md h2{font-size:1.4em;border-bottom:1px solid var(--fe-border);padding-bottom:.3em}.fe-preview__md h3{font-size:1.2em}.fe-preview__md p{margin:.8em 0}.fe-preview__md a{color:var(--fe-primary);text-decoration:underline}.fe-preview__md code{font-family:var(--fe-font-mono);background:var(--fe-bg-elev);padding:1px 5px;border-radius:3px;font-size:.92em}.fe-preview__md pre{background:var(--fe-bg-elev);border:1px solid var(--fe-border);border-radius:var(--fe-radius-sm);padding:12px 16px;overflow:auto;font-size:.9em}.fe-preview__md pre code{background:transparent;padding:0}.fe-preview__md ul,.fe-preview__md ol{padding-left:2em;margin:.8em 0}.fe-preview__md li{margin:.3em 0}.fe-preview__md blockquote{border-left:3px solid var(--fe-border-strong);padding:0 1em;color:var(--fe-text-muted);margin:.8em 0}.fe-preview__md table{border-collapse:collapse;margin:1em 0;width:100%}.fe-preview__md th,.fe-preview__md td{border:1px solid var(--fe-border);padding:6px 10px;text-align:left}.fe-preview__md th{background:var(--fe-bg-elev)}.fe-preview__md img{max-width:100%}.fe-toast{position:absolute;bottom:24px;left:50%;transform:translate(-50%);background:var(--fe-text);color:var(--fe-bg);padding:8px 14px;border-radius:var(--fe-radius);font-size:13px;box-shadow:var(--fe-shadow-sm);z-index:95}.fe-toast-enter-active,.fe-toast-leave-active{transition:opacity .2s,transform .2s}.fe-toast-enter-from,.fe-toast-leave-to{opacity:0;transform:translate(-50%,10px)}@media (max-width: 640px){.fe-list__head,.fe-list__row{grid-template-columns:28px minmax(0,1fr) 90px}.fe-list__col--mod{display:none}.fe-toolbar{padding:8px}.fe-search__input{min-width:120px}}.filex-viewer-3d[data-v-f9492fd4]{width:100%;height:100%;min-height:480px;background:#1a1a1a;display:flex;align-items:center;justify-content:center}.filex-viewer-3d[data-v-f9492fd4] model-viewer{width:100%;height:100%;min-height:480px;background:#1a1a1a;display:block}.filex-viewer-fallback[data-v-f9492fd4]{text-align:center;color:#c8cdd6;padding:32px;max-width:480px}.filex-viewer-fallback__icon[data-v-f9492fd4]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-epub__nav[data-v-12eb7133]{position:absolute;bottom:12px;left:50%;transform:translate(-50%);display:flex;gap:8px;padding:4px 8px;background:var(--fe-bg-elev, rgba(255, 255, 255, .9));border:1px solid var(--fe-border, #e2e6ed);border-radius:6px;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.filex-viewer-epub[data-v-12eb7133]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);position:relative}.filex-viewer-epub__bar[data-v-12eb7133]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-spacer[data-v-12eb7133]{flex:1}.filex-viewer-epub__fs[data-v-12eb7133]{display:inline-block;min-width:40px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-epub__main[data-v-12eb7133]{flex:1;min-height:0;display:flex}.filex-viewer-epub__rendition[data-v-12eb7133]{flex:1;min-height:0}.filex-viewer-epub__toc[data-v-12eb7133]{width:260px;border-right:1px solid var(--fe-border, #e2e6ed);overflow-y:auto;padding:12px 0;background:var(--fe-bg-elev, #f7f8fa)}.filex-viewer-epub__toc ul[data-v-12eb7133]{list-style:none;margin:0;padding:0}.filex-viewer-epub__toc-link[data-v-12eb7133]{display:block;width:100%;text-align:left;background:transparent;border:0;padding:6px 14px;font:inherit;color:inherit;cursor:pointer}.filex-viewer-epub__toc-link[data-v-12eb7133]:hover{background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-epub__toc-link.is-child[data-v-12eb7133]{padding-left:28px;color:var(--fe-text-muted, #5a6475);font-size:12px}.filex-viewer-epub__loading[data-v-12eb7133]{position:absolute;inset:auto 0 0 0;text-align:center;padding:6px;background:#0000000d;font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback[data-v-12eb7133]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-12eb7133]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-12eb7133]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-12eb7133]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn[data-v-12eb7133]:disabled{opacity:.5;cursor:not-allowed}.filex-viewer-mermaid[data-v-939eea2b]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-mermaid__bar[data-v-939eea2b]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-mermaid__zoom[data-v-939eea2b]{min-width:50px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-mermaid__pane[data-v-939eea2b]{flex:1;overflow:hidden;position:relative;cursor:grab;background:var(--fe-bg-elev, #f7f8fa);touch-action:none}.filex-viewer-mermaid__pane[data-v-939eea2b]:active{cursor:grabbing}.filex-viewer-mermaid__surface[data-v-939eea2b]{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;transform-origin:center center;transition:transform .05s linear;-webkit-user-select:none;user-select:none}.filex-viewer-mermaid__surface[data-v-939eea2b] svg{max-width:90%;max-height:90%}.filex-viewer-fallback[data-v-939eea2b]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475);width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.filex-viewer-fallback__icon[data-v-939eea2b]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-939eea2b]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-939eea2b]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-drawio[data-v-2e4b5f3b]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff)}.filex-viewer-drawio__bar[data-v-2e4b5f3b]{display:flex;align-items:center;gap:12px;padding:6px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-drawio__status[data-state=error][data-v-2e4b5f3b]{color:var(--fe-danger, #dc2626)}.filex-viewer-drawio__status[data-state=saved][data-v-2e4b5f3b]{color:#059669}.filex-viewer-drawio__readonly[data-v-2e4b5f3b]{font-style:italic;margin-left:auto}.filex-viewer-drawio__frame[data-v-2e4b5f3b]{flex:1;width:100%;border:0;background:#fafafa;min-height:0}.filex-viewer-fallback[data-v-2e4b5f3b]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-2e4b5f3b]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-tiff__pager[data-v-c6b84f5d]{position:absolute;bottom:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:8px;padding:4px 8px;background:var(--fe-bg-elev, rgba(255, 255, 255, .9));border:1px solid var(--fe-border, #e2e6ed);border-radius:6px;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.filex-viewer-tiff__pages[data-v-c6b84f5d]{font-size:12px;font-variant-numeric:tabular-nums}.filex-viewer-tiff[data-v-c6b84f5d]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff)}.filex-viewer-tiff__bar[data-v-c6b84f5d]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-tiff__pages[data-v-c6b84f5d]{min-width:110px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-tiff__zoom[data-v-c6b84f5d]{min-width:50px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-spacer[data-v-c6b84f5d]{flex:1}.filex-viewer-tiff__pane[data-v-c6b84f5d]{flex:1;overflow:auto;padding:16px;background:#2a2d33;display:flex;align-items:flex-start;justify-content:flex-start}.filex-viewer-tiff__pane canvas[data-v-c6b84f5d]{background:#fff;box-shadow:0 4px 16px #0000004d}.filex-viewer-fallback[data-v-c6b84f5d]{text-align:center;padding:32px;color:#c8cdd6;margin:auto}.filex-viewer-fallback__icon[data-v-c6b84f5d]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-c6b84f5d]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-c6b84f5d]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn[data-v-c6b84f5d]:disabled{opacity:.4;cursor:not-allowed}.filex-viewer-psd[data-v-001123c3]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff)}.filex-viewer-psd__bar[data-v-001123c3]{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:13px}.filex-viewer-spacer[data-v-001123c3]{flex:1}.filex-viewer-psd__dim[data-v-001123c3]{font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-psd__zoom[data-v-001123c3]{min-width:50px;text-align:center;font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-psd__main[data-v-001123c3]{flex:1;display:flex;min-height:0}.filex-viewer-psd__layers[data-v-001123c3]{width:240px;border-right:1px solid var(--fe-border, #e2e6ed);overflow-y:auto;padding:8px 0;background:var(--fe-bg-elev, #f7f8fa)}.filex-viewer-psd__layers ul[data-v-001123c3]{list-style:none;margin:0;padding:0}.filex-viewer-psd__layers li[data-v-001123c3]{display:flex;align-items:center;gap:6px;padding:4px 12px;font-size:12px}.filex-viewer-psd__layer-vis[data-v-001123c3]{width:14px;text-align:center;color:var(--fe-text-muted, #5a6475)}.filex-viewer-psd__layer-vis[data-hidden="1"][data-v-001123c3]{color:var(--fe-border-strong, #c7ced9)}.filex-viewer-psd__layer-name[data-v-001123c3]{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.filex-viewer-psd__pane[data-v-001123c3]{flex:1;overflow:auto;padding:16px;background:#2a2d33;display:flex;align-items:flex-start;justify-content:flex-start}.filex-viewer-psd__pane canvas[data-v-001123c3]{background:#fff repeating-conic-gradient(#e0e0e0 0% 25%,transparent 0% 50%) 50% / 16px 16px;box-shadow:0 4px 16px #0000004d}.filex-viewer-fallback[data-v-001123c3]{text-align:center;padding:32px;color:#c8cdd6;margin:auto}.filex-viewer-fallback__icon[data-v-001123c3]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-001123c3]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-001123c3]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn.is-active[data-v-001123c3]{background:var(--fe-bg-selected, #dfe8ff);border-color:var(--fe-primary, #3b82f6)}.filex-viewer-ipynb[data-v-eece712d]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-ipynb__bar[data-v-eece712d]{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:12px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-ipynb__lang[data-v-eece712d]{font-family:var(--fe-font-mono, monospace);text-transform:uppercase;letter-spacing:.04em}.filex-viewer-ipynb__pane[data-v-eece712d]{flex:1;overflow:auto;padding:16px 24px}.filex-viewer-ipynb__cell[data-v-eece712d]{border:1px solid var(--fe-border, #e2e6ed);border-radius:6px;margin-bottom:16px;overflow:hidden}.filex-viewer-ipynb__cell[data-type=code][data-v-eece712d]{background:var(--fe-bg-elev, #f7f8fa)}.filex-viewer-ipynb__exec[data-v-eece712d]{padding:4px 12px;font-family:var(--fe-font-mono, monospace);font-size:11px;color:var(--fe-text-muted, #5a6475);background:#0000000a}.filex-viewer-ipynb__src[data-v-eece712d]{margin:0;padding:12px;font-family:var(--fe-font-mono, monospace);font-size:12px;line-height:1.5;white-space:pre;overflow-x:auto}.filex-viewer-ipynb__outputs[data-v-eece712d]{border-top:1px dashed var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);padding:8px 12px}.filex-viewer-ipynb__out[data-v-eece712d]{margin:0;padding:4px 0;font-family:var(--fe-font-mono, monospace);font-size:12px;white-space:pre-wrap;word-wrap:break-word}.filex-viewer-ipynb__out[data-type=error][data-v-eece712d]{color:var(--fe-danger, #dc2626)}.filex-viewer-ipynb__img[data-v-eece712d]{display:block;max-width:100%;height:auto;margin:8px 0}.filex-viewer-ipynb__html[data-v-eece712d]{font-size:13px}.filex-viewer-ipynb__md[data-v-eece712d]{padding:12px 16px;font-size:14px;line-height:1.6}.filex-viewer-ipynb__md-raw[data-v-eece712d]{padding:12px;margin:0;font-family:var(--fe-font-mono, monospace);font-size:12px;white-space:pre-wrap}.filex-viewer-fallback[data-v-eece712d]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-eece712d]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-csv[data-v-db55a104]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-csv__bar[data-v-db55a104]{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--fe-bg-elev, #f7f8fa);border-bottom:1px solid var(--fe-border, #e2e6ed);font-size:12px}.filex-viewer-csv__check[data-v-db55a104]{display:flex;align-items:center;gap:4px;font-size:12px}.filex-viewer-csv__select[data-v-db55a104],.filex-viewer-csv__filter[data-v-db55a104]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:inherit;padding:4px 8px;border-radius:4px;font:inherit;font-size:12px}.filex-viewer-csv__filter[data-v-db55a104]{flex:0 1 240px}.filex-viewer-spacer[data-v-db55a104]{flex:1}.filex-viewer-csv__count[data-v-db55a104]{font-size:11px;color:var(--fe-text-muted, #5a6475);font-variant-numeric:tabular-nums}.filex-viewer-csv__pane[data-v-db55a104]{flex:1;overflow:auto}.filex-viewer-csv__table[data-v-db55a104]{border-collapse:collapse;width:max-content;min-width:100%;font-size:12px;font-family:var(--fe-font-mono, monospace)}.filex-viewer-csv__table th[data-v-db55a104],.filex-viewer-csv__table td[data-v-db55a104]{padding:4px 10px;border:1px solid var(--fe-border, #e2e6ed);white-space:nowrap;max-width:320px;overflow:hidden;text-overflow:ellipsis}.filex-viewer-csv__table th[data-v-db55a104]{background:var(--fe-bg-elev, #f7f8fa);position:sticky;top:0;font-weight:600;text-align:left}.filex-viewer-csv__table tbody tr[data-v-db55a104]:nth-child(2n){background:var(--fe-bg-hover, rgba(0, 0, 0, .02))}.filex-viewer-csv__rownum[data-v-db55a104]{color:var(--fe-text-muted, #5a6475);text-align:right;background:var(--fe-bg-elev, #f7f8fa);font-variant-numeric:tabular-nums;position:sticky;left:0}.filex-viewer-csv__pager[data-v-db55a104]{display:flex;justify-content:center;align-items:center;gap:8px;padding:6px;background:var(--fe-bg-elev, #f7f8fa);border-top:1px solid var(--fe-border, #e2e6ed);font-size:12px}.filex-viewer-csv__pageno[data-v-db55a104]{font-variant-numeric:tabular-nums;font-size:12px}.filex-viewer-fallback[data-v-db55a104]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-db55a104]{font-size:48px;display:block;margin-bottom:12px}.filex-viewer-btn[data-v-db55a104]{border:1px solid var(--fe-border, #e2e6ed);background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27);padding:4px 10px;border-radius:4px;cursor:pointer;font:inherit;font-size:12px}.filex-viewer-btn[data-v-db55a104]:hover:not(:disabled){background:var(--fe-bg-hover, #edf0f5)}.filex-viewer-btn[data-v-db55a104]:disabled{opacity:.4;cursor:not-allowed}.filex-viewer-archive[data-v-93df7b13]{display:flex;flex-direction:column;width:100%;height:100%;min-height:70vh;background:var(--fe-bg, #fff);color:var(--fe-text, #1a1e27)}.filex-viewer-archive__pane[data-v-93df7b13]{flex:1;overflow:auto;padding:16px 20px}.filex-viewer-archive__summary[data-v-93df7b13]{font-size:12px;color:var(--fe-text-muted, #5a6475);margin-bottom:12px;font-variant-numeric:tabular-nums}.filex-viewer-archive__table[data-v-93df7b13]{width:100%;border-collapse:collapse;font-size:13px;font-family:var(--fe-font-mono, monospace)}.filex-viewer-archive__table th[data-v-93df7b13],.filex-viewer-archive__table td[data-v-93df7b13]{padding:6px 12px;border-bottom:1px solid var(--fe-border, #e2e6ed);text-align:left}.filex-viewer-archive__table th[data-v-93df7b13]{background:var(--fe-bg-elev, #f7f8fa);font-weight:600;position:sticky;top:0}.filex-viewer-archive__size[data-v-93df7b13]{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--fe-text-muted, #5a6475)}.filex-viewer-archive__icon[data-v-93df7b13]{margin-right:6px}.filex-viewer-archive__table tr[data-dir="1"][data-v-93df7b13]{color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback[data-v-93df7b13]{text-align:center;padding:32px;color:var(--fe-text-muted, #5a6475)}.filex-viewer-fallback__icon[data-v-93df7b13]{font-size:48px;display:block;margin-bottom:12px}
|
package/package.json
CHANGED
package/src/FileExplorer.vue
CHANGED
|
@@ -31,6 +31,7 @@ import { useKeyboardShortcuts } from './composables/useKeyboardShortcuts';
|
|
|
31
31
|
import { useLocale } from './composables/useLocale';
|
|
32
32
|
import { usePendingOps, type PendingOp } from './composables/usePendingOps';
|
|
33
33
|
import { useRealtime } from './composables/useRealtime';
|
|
34
|
+
import { useThumbs } from './composables/useThumbs';
|
|
34
35
|
import { preloadEditor } from './composables/useMonacoLoader';
|
|
35
36
|
import PresenceBar from './components/PresenceBar.vue';
|
|
36
37
|
|
|
@@ -87,8 +88,17 @@ const realtime = useRealtime(api, { reload: () => load() });
|
|
|
87
88
|
const presenceUsers = realtime.presenceUsers;
|
|
88
89
|
function realtimeRoom(vp: string): string | null {
|
|
89
90
|
const p = (vp || '').replace(/^\/+|\/+$/g, '');
|
|
90
|
-
if (
|
|
91
|
-
|
|
91
|
+
if (p === '.trash' || p.startsWith('.trash/')) return null;
|
|
92
|
+
// The wire form must go through the mode-aware qualify(), exactly like every
|
|
93
|
+
// API call: in single-storage mode currentPath is a BARE relative path
|
|
94
|
+
// ("projeler/5") — virtualToWire would mistake its first segment for an
|
|
95
|
+
// adapter ("projeler://5") and subscribe a nonexistent room, so presence and
|
|
96
|
+
// live changes silently missed the real folder. An empty p is the storage
|
|
97
|
+
// root — a real room ("main://") — not "no room"; only the multi-storage
|
|
98
|
+
// drives list (no adapter yet) has none.
|
|
99
|
+
const wire = qualify(p);
|
|
100
|
+
if (!wire || !wire.includes('://') || wire.startsWith('://')) return null;
|
|
101
|
+
return wire;
|
|
92
102
|
}
|
|
93
103
|
onMounted(() => {
|
|
94
104
|
realtime.start();
|
|
@@ -96,6 +106,11 @@ onMounted(() => {
|
|
|
96
106
|
});
|
|
97
107
|
onBeforeUnmount(() => realtime.stop());
|
|
98
108
|
|
|
109
|
+
// Authenticated thumbnails — raw thumb_url is root-relative + header-less,
|
|
110
|
+
// which only ever worked for the native same-origin SPA (embedded hosts got
|
|
111
|
+
// empty/broken <img>s). See useThumbs.
|
|
112
|
+
const thumbs = useThumbs(props.config.apiBase, api);
|
|
113
|
+
|
|
99
114
|
const chunked = useUploadChunked(props.config, api);
|
|
100
115
|
const pendingOps = usePendingOps(props.config, api, {
|
|
101
116
|
onSettled: (op: PendingOp) => {
|
|
@@ -1819,6 +1834,7 @@ function buildAuthHeaders(extra: Record<string, string> = {}) {
|
|
|
1819
1834
|
:show-parent-path="!!searchQuery"
|
|
1820
1835
|
:locale="locale"
|
|
1821
1836
|
:loading="loading"
|
|
1837
|
+
:thumb-src="thumbs.src"
|
|
1822
1838
|
@click-card="(n, m) => selection.click(n.path, m)"
|
|
1823
1839
|
@dbl-card="openNode"
|
|
1824
1840
|
@context-card="onContextTarget"
|
|
@@ -13,6 +13,10 @@ const props = defineProps<{
|
|
|
13
13
|
showParentPath?: boolean;
|
|
14
14
|
locale: LocaleCode;
|
|
15
15
|
loading?: boolean;
|
|
16
|
+
/** Authenticated thumb resolver (useThumbs.src). Raw `thumb_url` is
|
|
17
|
+
* root-relative and unauthenticated — a bare <img src> only works for the
|
|
18
|
+
* native same-origin SPA, so embedded hosts NEED this. null = icon. */
|
|
19
|
+
thumbSrc?: (n: FileNode) => string | null;
|
|
16
20
|
}>();
|
|
17
21
|
|
|
18
22
|
const emit = defineEmits<{
|
|
@@ -25,6 +29,12 @@ const emit = defineEmits<{
|
|
|
25
29
|
|
|
26
30
|
const { t, formatSize, nodeDisplayName } = useLocale(() => props.locale);
|
|
27
31
|
|
|
32
|
+
// Prefer the authenticated resolver when the host wired one; otherwise fall
|
|
33
|
+
// back to the raw URL (legacy same-origin behavior).
|
|
34
|
+
function thumbOf(n: FileNode): string | null {
|
|
35
|
+
return props.thumbSrc ? props.thumbSrc(n) : (n.thumb_url ?? null);
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
function isSelected(n: FileNode): boolean {
|
|
29
39
|
return props.selected.has(n.path);
|
|
30
40
|
}
|
|
@@ -140,8 +150,8 @@ function iconFor(n: FileNode): string {
|
|
|
140
150
|
Parent card stays draggable=true so internal move works.
|
|
141
151
|
-->
|
|
142
152
|
<img
|
|
143
|
-
v-if="n
|
|
144
|
-
:src="n
|
|
153
|
+
v-if="thumbOf(n)"
|
|
154
|
+
:src="thumbOf(n)!"
|
|
145
155
|
:alt="n.basename"
|
|
146
156
|
loading="lazy"
|
|
147
157
|
draggable="false"
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
// PresenceBar — compact avatar strip showing who else is viewing the current
|
|
3
|
-
// folder, and (as a small badge) which file each person is focused on.
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// folder, and (as a small badge) which file each person is focused on. The
|
|
4
|
+
// server already excludes the recipient from the roster (presence answers
|
|
5
|
+
// "who ELSE is here"); the optional selfId filter remains as a belt-and-braces
|
|
6
|
+
// for older backends. Purely presentational; the live data comes from the
|
|
7
|
+
// realtime presence stream.
|
|
6
8
|
|
|
7
|
-
import { computed } from 'vue';
|
|
9
|
+
import { computed, ref } from 'vue';
|
|
8
10
|
import type { PresenceUser } from '../lib/realtime';
|
|
9
11
|
|
|
10
12
|
const props = defineProps<{
|
|
@@ -16,6 +18,32 @@ const others = computed(() =>
|
|
|
16
18
|
(props.users ?? []).filter((u) => props.selfId == null || u.id !== props.selfId),
|
|
17
19
|
);
|
|
18
20
|
|
|
21
|
+
// Compact (avatar strip) ⇄ expanded (scrollable name chips). With many users
|
|
22
|
+
// the strip collapses to "+N", so the expanded mode is how you actually READ
|
|
23
|
+
// who is here; the choice sticks for the session via localStorage.
|
|
24
|
+
const EXPAND_KEY = 'filex.presence.expanded';
|
|
25
|
+
const expanded = ref<boolean>((() => {
|
|
26
|
+
try {
|
|
27
|
+
return localStorage.getItem(EXPAND_KEY) === '1';
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
})());
|
|
32
|
+
function toggleExpanded(): void {
|
|
33
|
+
expanded.value = !expanded.value;
|
|
34
|
+
try {
|
|
35
|
+
localStorage.setItem(EXPAND_KEY, expanded.value ? '1' : '0');
|
|
36
|
+
} catch {
|
|
37
|
+
/* private mode — session-only */
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Stable key per identity: end users behind one shared proxy token have the
|
|
42
|
+
// same numeric id but distinct server-issued uids.
|
|
43
|
+
function keyOf(u: PresenceUser): string {
|
|
44
|
+
return u.uid ?? String(u.id);
|
|
45
|
+
}
|
|
46
|
+
|
|
19
47
|
function initials(name: string): string {
|
|
20
48
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
21
49
|
if (parts.length === 0) return '?';
|
|
@@ -23,9 +51,12 @@ function initials(name: string): string {
|
|
|
23
51
|
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
24
52
|
}
|
|
25
53
|
|
|
26
|
-
// Deterministic hue per
|
|
27
|
-
function hue(
|
|
28
|
-
|
|
54
|
+
// Deterministic hue per identity so the same person keeps the same colour.
|
|
55
|
+
function hue(u: PresenceUser): number {
|
|
56
|
+
const s = keyOf(u);
|
|
57
|
+
let h = 0;
|
|
58
|
+
for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) >>> 0;
|
|
59
|
+
return h % 360;
|
|
29
60
|
}
|
|
30
61
|
|
|
31
62
|
function label(u: PresenceUser): string {
|
|
@@ -34,26 +65,58 @@ function label(u: PresenceUser): string {
|
|
|
34
65
|
</script>
|
|
35
66
|
|
|
36
67
|
<template>
|
|
37
|
-
<div v-if="others.length" class="fx-presence" :
|
|
38
|
-
|
|
68
|
+
<div v-if="others.length" class="fx-presence" :class="{ 'fx-presence--wide': expanded }">
|
|
69
|
+
<!-- Expanded: every user as an avatar+name chip in a horizontally
|
|
70
|
+
scrollable row — names stay fully readable however many join. -->
|
|
71
|
+
<div v-if="expanded" class="fx-presence-chips">
|
|
39
72
|
<span
|
|
40
|
-
v-for="u in others
|
|
41
|
-
:key="u
|
|
42
|
-
class="fx-presence-
|
|
43
|
-
:style="{ backgroundColor: `hsl(${hue(u.id)} 60% 45%)` }"
|
|
73
|
+
v-for="u in others"
|
|
74
|
+
:key="keyOf(u)"
|
|
75
|
+
class="fx-presence-chip"
|
|
44
76
|
:title="label(u)"
|
|
45
77
|
>
|
|
46
|
-
|
|
47
|
-
|
|
78
|
+
<span
|
|
79
|
+
class="fx-presence-avatar"
|
|
80
|
+
:style="{ backgroundColor: `hsl(${hue(u)} 60% 45%)` }"
|
|
81
|
+
>
|
|
82
|
+
{{ initials(u.name) }}
|
|
83
|
+
<span v-if="u.file" class="fx-presence-dot" aria-hidden="true"></span>
|
|
84
|
+
</span>
|
|
85
|
+
<span class="fx-presence-chip-name">{{ u.name }}</span>
|
|
86
|
+
<span v-if="u.file" class="fx-presence-chip-file">· {{ u.file }}</span>
|
|
48
87
|
</span>
|
|
49
|
-
<span v-if="others.length > 5" class="fx-presence-more">+{{ others.length - 5 }}</span>
|
|
50
88
|
</div>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
89
|
+
|
|
90
|
+
<!-- Compact: the classic overlapping avatar strip. -->
|
|
91
|
+
<template v-else>
|
|
92
|
+
<div class="fx-presence-avatars" :title="others.map(label).join(', ')">
|
|
93
|
+
<span
|
|
94
|
+
v-for="u in others.slice(0, 5)"
|
|
95
|
+
:key="keyOf(u)"
|
|
96
|
+
class="fx-presence-avatar"
|
|
97
|
+
:style="{ backgroundColor: `hsl(${hue(u)} 60% 45%)` }"
|
|
98
|
+
:title="label(u)"
|
|
99
|
+
>
|
|
100
|
+
{{ initials(u.name) }}
|
|
101
|
+
<span v-if="u.file" class="fx-presence-dot" aria-hidden="true"></span>
|
|
102
|
+
</span>
|
|
103
|
+
<span v-if="others.length > 5" class="fx-presence-more">+{{ others.length - 5 }}</span>
|
|
104
|
+
</div>
|
|
105
|
+
<span class="fx-presence-text" :title="others.map(label).join(', ')">
|
|
106
|
+
{{ others.length === 1 ? others[0].name : `${others.length} kişi` }}
|
|
107
|
+
<template v-if="others.length === 1 && others[0].file">
|
|
108
|
+
· <span class="fx-presence-file">{{ others[0].file }}</span>
|
|
109
|
+
</template>
|
|
110
|
+
</span>
|
|
111
|
+
</template>
|
|
112
|
+
|
|
113
|
+
<button
|
|
114
|
+
type="button"
|
|
115
|
+
class="fx-presence-toggle"
|
|
116
|
+
:title="expanded ? 'Küçült' : 'İsimleri göster'"
|
|
117
|
+
:aria-expanded="expanded"
|
|
118
|
+
@click="toggleExpanded"
|
|
119
|
+
>{{ expanded ? '‹' : '›' }}</button>
|
|
57
120
|
</div>
|
|
58
121
|
</template>
|
|
59
122
|
|
|
@@ -102,6 +165,70 @@ function label(u: PresenceUser): string {
|
|
|
102
165
|
font-size: 0.7rem;
|
|
103
166
|
color: rgb(113 113 122); /* zinc-500 */
|
|
104
167
|
}
|
|
168
|
+
.fx-presence--wide {
|
|
169
|
+
flex: 1 1 auto;
|
|
170
|
+
min-width: 0;
|
|
171
|
+
}
|
|
172
|
+
.fx-presence-chips {
|
|
173
|
+
display: flex;
|
|
174
|
+
align-items: center;
|
|
175
|
+
gap: 0.4rem;
|
|
176
|
+
overflow-x: auto;
|
|
177
|
+
min-width: 0;
|
|
178
|
+
padding-bottom: 2px; /* keep the scrollbar off the chips */
|
|
179
|
+
scrollbar-width: thin;
|
|
180
|
+
}
|
|
181
|
+
.fx-presence-chip {
|
|
182
|
+
display: inline-flex;
|
|
183
|
+
align-items: center;
|
|
184
|
+
gap: 0.35rem;
|
|
185
|
+
flex: 0 0 auto;
|
|
186
|
+
padding: 0.15rem 0.5rem 0.15rem 0.2rem;
|
|
187
|
+
border-radius: 9999px;
|
|
188
|
+
background: rgb(244 244 245); /* zinc-100 */
|
|
189
|
+
font-size: 0.75rem;
|
|
190
|
+
color: rgb(63 63 70); /* zinc-700 */
|
|
191
|
+
white-space: nowrap;
|
|
192
|
+
}
|
|
193
|
+
.fx-presence-chip .fx-presence-avatar {
|
|
194
|
+
margin-left: 0;
|
|
195
|
+
}
|
|
196
|
+
.fx-presence-chip-name {
|
|
197
|
+
font-weight: 500;
|
|
198
|
+
}
|
|
199
|
+
.fx-presence-chip-file {
|
|
200
|
+
color: rgb(113 113 122); /* zinc-500 */
|
|
201
|
+
max-width: 12rem;
|
|
202
|
+
overflow: hidden;
|
|
203
|
+
text-overflow: ellipsis;
|
|
204
|
+
}
|
|
205
|
+
.fx-presence-toggle {
|
|
206
|
+
flex: 0 0 auto;
|
|
207
|
+
display: inline-flex;
|
|
208
|
+
align-items: center;
|
|
209
|
+
justify-content: center;
|
|
210
|
+
width: 1.25rem;
|
|
211
|
+
height: 1.25rem;
|
|
212
|
+
border: none;
|
|
213
|
+
border-radius: 9999px;
|
|
214
|
+
background: transparent;
|
|
215
|
+
color: rgb(113 113 122); /* zinc-500 */
|
|
216
|
+
font-size: 0.9rem;
|
|
217
|
+
line-height: 1;
|
|
218
|
+
cursor: pointer;
|
|
219
|
+
}
|
|
220
|
+
.fx-presence-toggle:hover {
|
|
221
|
+
background: rgb(228 228 231); /* zinc-200 */
|
|
222
|
+
color: rgb(63 63 70);
|
|
223
|
+
}
|
|
224
|
+
:global(.dark) .fx-presence-chip {
|
|
225
|
+
background: rgb(39 39 42); /* zinc-800 */
|
|
226
|
+
color: rgb(212 212 216); /* zinc-300 */
|
|
227
|
+
}
|
|
228
|
+
:global(.dark) .fx-presence-toggle:hover {
|
|
229
|
+
background: rgb(39 39 42);
|
|
230
|
+
color: rgb(212 212 216);
|
|
231
|
+
}
|
|
105
232
|
.fx-presence-text {
|
|
106
233
|
font-size: 0.75rem;
|
|
107
234
|
color: rgb(113 113 122); /* zinc-500 */
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// useThumbs — authenticated thumbnail loader for the grid view.
|
|
2
|
+
//
|
|
3
|
+
// The backend emits `thumb_url` as a ROOT-RELATIVE path ("/api/files/thumb/{id}").
|
|
4
|
+
// A plain `<img src>` only works for the native same-origin SPA: an embedded
|
|
5
|
+
// webcomponent resolves it against the HOST page's origin (work.brf.sh → 404)
|
|
6
|
+
// and, even with the URL fixed, `<img>` cannot carry the bearer header a
|
|
7
|
+
// proxied host (fishapp PWA) requires. So thumbs are fetched through the same
|
|
8
|
+
// auth machinery as every API call (headers + credentials), cached as object
|
|
9
|
+
// URLs, and handed to the grid; a failed fetch falls back to the file icon.
|
|
10
|
+
|
|
11
|
+
import { ref } from 'vue';
|
|
12
|
+
import type { FileNode } from '../types/FileNode';
|
|
13
|
+
|
|
14
|
+
interface ThumbApiSlice {
|
|
15
|
+
authHeaders: (extra?: Record<string, string>) => Promise<Record<string, string>>;
|
|
16
|
+
credentialsMode: () => RequestCredentials;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Cap the object-URL cache; beyond it oldest entries are revoked. Thumbs are
|
|
20
|
+
* small (~KBs) so this is generous while still bounding a long session. */
|
|
21
|
+
const MAX_CACHED = 500;
|
|
22
|
+
|
|
23
|
+
export function useThumbs(apiBase: string | undefined, api: ThumbApiSlice) {
|
|
24
|
+
const urls = ref<Record<string, string>>({});
|
|
25
|
+
const order: string[] = [];
|
|
26
|
+
const failed = new Set<string>();
|
|
27
|
+
const pending = new Set<string>();
|
|
28
|
+
|
|
29
|
+
function resolveUrl(raw: string): string {
|
|
30
|
+
if (/^https?:\/\//i.test(raw)) return raw;
|
|
31
|
+
const base = (apiBase || '').replace(/\/+$/, '');
|
|
32
|
+
return base && raw.startsWith('/') ? base + raw : raw;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Reactive: returns the loaded object URL for the node's thumb, kicking off
|
|
36
|
+
* the fetch on first sight. null = not (yet) available → show the icon. */
|
|
37
|
+
function src(n: FileNode): string | null {
|
|
38
|
+
const raw = n.thumb_url;
|
|
39
|
+
if (!raw) return null;
|
|
40
|
+
const got = urls.value[raw];
|
|
41
|
+
if (got) return got;
|
|
42
|
+
if (!failed.has(raw) && !pending.has(raw)) void load(raw);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function load(raw: string): Promise<void> {
|
|
47
|
+
pending.add(raw);
|
|
48
|
+
try {
|
|
49
|
+
const res = await fetch(resolveUrl(raw), {
|
|
50
|
+
headers: await api.authHeaders({ Accept: '*/*' }),
|
|
51
|
+
credentials: api.credentialsMode(),
|
|
52
|
+
});
|
|
53
|
+
if (!res.ok) throw new Error(String(res.status));
|
|
54
|
+
const blob = await res.blob();
|
|
55
|
+
if (order.length >= MAX_CACHED) {
|
|
56
|
+
const evict = order.shift();
|
|
57
|
+
if (evict && urls.value[evict]) {
|
|
58
|
+
URL.revokeObjectURL(urls.value[evict]);
|
|
59
|
+
const next = { ...urls.value };
|
|
60
|
+
delete next[evict];
|
|
61
|
+
urls.value = next;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
order.push(raw);
|
|
65
|
+
urls.value = { ...urls.value, [raw]: URL.createObjectURL(blob) };
|
|
66
|
+
} catch {
|
|
67
|
+
// 404 (thumb evicted server-side) or auth hiccup — icon fallback, and we
|
|
68
|
+
// don't retry within this session to avoid hammering.
|
|
69
|
+
failed.add(raw);
|
|
70
|
+
} finally {
|
|
71
|
+
pending.delete(raw);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { src };
|
|
76
|
+
}
|