(() => {
  const IMAGE_EXTS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".ico", ".bmp"]);
  const MD_EXTS = /* @__PURE__ */ new Set([".md", ".markdown", ".mdown"]);
  const DOWNLOAD_EXTS = /* @__PURE__ */ new Set([
    ".docx",
    ".doc",
    ".xlsx",
    ".xls",
    ".pptx",
    ".ppt",
    ".odt",
    ".ods",
    ".odp",
    ".pdf",
    ".zip",
    ".tar",
    ".gz",
    ".bz2",
    ".7z",
    ".rar",
    ".mp3",
    ".mp4",
    ".wav",
    ".m4a",
    ".ogg",
    ".flac",
    ".mov",
    ".avi",
    ".mkv",
    ".webm",
    ".exe",
    ".dmg",
    ".pkg",
    ".deb",
    ".rpm",
    ".woff",
    ".woff2",
    ".ttf",
    ".otf",
    ".eot",
    ".bin",
    ".dat",
    ".db",
    ".sqlite",
    ".pyc",
    ".class",
    ".so",
    ".dylib",
    ".dll"
  ]);
  window.IMAGE_EXTS = IMAGE_EXTS;
  window.MD_EXTS = MD_EXTS;
  window.DOWNLOAD_EXTS = DOWNLOAD_EXTS;
  function fileExt(p) {
    const i = p.lastIndexOf(".");
    return i >= 0 ? p.slice(i).toLowerCase() : "";
  }
  window.fileExt = fileExt;
  async function api(path, opts = {}) {
    const rel = path.startsWith("/") ? path.slice(1) : path;
    const url = new URL(rel, location.href);
    const res = await fetch(url.href, { credentials: "include", headers: { "Content-Type": "application/json" }, ...opts });
    if (!res.ok) {
      const text = await res.text();
      try {
        const j = JSON.parse(text);
        throw new Error(j.error || j.message || text);
      } catch (e) {
        if (e instanceof SyntaxError) throw new Error(text);
        throw e;
      }
    }
    const ct = res.headers.get("content-type") || "";
    return ct.includes("application/json") ? res.json() : res.text();
  }
  window.api = api;
  function _wsExpandKey() {
    const ws = S.session && S.session.workspace;
    return ws ? "hermes-webui-expanded:" + ws : null;
  }
  function _saveExpandedDirs() {
    const key = _wsExpandKey();
    if (!key) return;
    try {
      localStorage.setItem(key, JSON.stringify([...S._expandedDirs || /* @__PURE__ */ new Set()]));
    } catch (e) {
    }
  }
  function _restoreExpandedDirs() {
    const key = _wsExpandKey();
    if (!key) {
      S._expandedDirs = /* @__PURE__ */ new Set();
      return;
    }
    try {
      const raw = localStorage.getItem(key);
      S._expandedDirs = raw ? new Set(JSON.parse(raw)) : /* @__PURE__ */ new Set();
    } catch (e) {
      S._expandedDirs = /* @__PURE__ */ new Set();
    }
  }
  async function loadDir(path) {
    if (!S.session) return;
    try {
      if (!path || path === ".") {
        S._dirCache = {};
        _restoreExpandedDirs();
      }
      S.currentDir = path || ".";
      const data = await api(`/api/list?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(path)}`);
      S.entries = data.entries || [];
      renderBreadcrumb();
      renderFileTree();
      if (!path || path === ".") {
        for (const dirPath of S._expandedDirs || []) {
          if (!S._dirCache[dirPath]) {
            try {
              const dc = await api(`/api/list?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(dirPath)}`);
              S._dirCache[dirPath] = dc.entries || [];
            } catch (e2) {
              S._dirCache[dirPath] = [];
            }
          }
        }
        if (S._expandedDirs && S._expandedDirs.size > 0) renderFileTree();
      }
      if (typeof clearPreview === "function") {
        if (typeof _previewDirty !== "undefined" && _previewDirty) {
          showConfirmDialog({ title: t("unsaved_confirm"), message: "", confirmLabel: "Discard", danger: true, focusCancel: true }).then((ok) => {
            if (ok) clearPreview();
          });
        } else {
          clearPreview();
        }
      }
      if (!path || path === ".") _refreshGitBadge();
    } catch (e) {
      console.warn("loadDir", e);
    }
  }
  async function _refreshGitBadge() {
    const badge = $("gitBadge");
    if (!badge || !S.session) return;
    try {
      const data = await api(`/api/git-info?session_id=${encodeURIComponent(S.session.session_id)}`);
      if (data.git && data.git.is_git) {
        const g = data.git;
        let text = g.branch || "git";
        if ((g.dirty ?? 0) > 0) text += ` \xB7 ${g.dirty}\u2206`;
        if ((g.behind ?? 0) > 0) text += ` \u2193${g.behind}`;
        if ((g.ahead ?? 0) > 0) text += ` \u2191${g.ahead}`;
        badge.textContent = text;
        badge.className = "git-badge" + ((g.dirty ?? 0) > 0 ? " dirty" : "");
        badge.style.display = "";
      } else {
        badge.style.display = "none";
        badge.textContent = "";
      }
    } catch (e) {
      if (badge) badge.style.display = "none";
    }
  }
  function navigateUp() {
    if (!S.session || S.currentDir === ".") return;
    const parts = S.currentDir.split("/");
    parts.pop();
    loadDir(parts.length ? parts.join("/") : ".");
  }
  let _previewCurrentPath = "";
  let _previewCurrentMode = "";
  let _previewDirty = false;
  let _previewRawContent = "";
  function showPreview(mode) {
    const codeEl = $("previewCode");
    const imgWrap = $("previewImgWrap");
    const mdEl = $("previewMd");
    const editEl = $("previewEditArea");
    const badge = $("previewBadge");
    if (codeEl) codeEl.style.display = mode === "code" ? "" : "none";
    if (imgWrap) imgWrap.style.display = mode === "image" ? "" : "none";
    if (mdEl) mdEl.style.display = mode === "md" ? "" : "none";
    if (editEl) editEl.style.display = "none";
    if (badge) {
      badge.className = "preview-badge " + mode;
      const pathText = $("previewPathText");
      badge.textContent = mode === "image" ? "image" : mode === "md" ? "md" : fileExt(pathText?.textContent || "");
    }
    _previewCurrentMode = mode;
    _previewDirty = false;
    updateEditBtn();
  }
  function updateEditBtn() {
    const btn = $("btnEditFile");
    if (!btn) return;
    const editable = _previewCurrentMode === "code" || _previewCurrentMode === "md";
    btn.style.display = editable ? "" : "none";
    const editing = $("previewEditArea")?.style.display !== "none";
    btn.innerHTML = editing ? `&#128190; ${t("save")}` : `&#9998; ${t("edit")}`;
    btn.title = editing ? t("save_title") : t("edit_title");
    btn.style.color = editing ? "var(--blue)" : "";
    if (_previewDirty) btn.innerHTML = "&#128190; Save*";
  }
  async function toggleEditMode() {
    const editEl = $("previewEditArea");
    const editing = editEl && editEl.style.display !== "none";
    if (editing) {
      if (!S.session || !_previewCurrentPath) return;
      const content = editEl.value;
      try {
        await api("/api/file/save", { method: "POST", body: JSON.stringify({ session_id: S.session.session_id, path: _previewCurrentPath, content }) });
        _previewDirty = false;
        const codeEl = $("previewCode");
        const mdEl = $("previewMd");
        if (_previewCurrentMode === "code" && codeEl) codeEl.textContent = content;
        else if (mdEl) {
          mdEl.innerHTML = renderMd(content);
          requestAnimationFrame(() => {
            if (typeof renderKatexBlocks === "function") renderKatexBlocks();
          });
        }
        if (editEl) editEl.style.display = "none";
        if (codeEl && _previewCurrentMode === "code") codeEl.style.display = "";
        else if (mdEl) mdEl.style.display = "";
        showToast(t("saved"));
      } catch (e) {
        setStatus(t("save_failed") + (e instanceof Error ? e.message : String(e)));
      }
    } else {
      const currentText = _previewCurrentMode === "code" ? $("previewCode")?.textContent || "" : _previewRawContent || "";
      if (editEl) {
        editEl.value = currentText;
        editEl.style.display = "";
      }
      const codeEl = $("previewCode");
      const mdEl = $("previewMd");
      if (codeEl && _previewCurrentMode === "code") codeEl.style.display = "none";
      else if (mdEl) mdEl.style.display = "none";
      editEl.onkeydown = (e) => {
        if (e.key === "Escape") {
          e.preventDefault();
          cancelEditMode();
        }
      };
    }
    updateEditBtn();
  }
  function cancelEditMode() {
    const editEl = $("previewEditArea");
    if (editEl) {
      editEl.style.display = "none";
      editEl.onkeydown = null;
    }
    const codeEl = $("previewCode");
    const mdEl = $("previewMd");
    if (codeEl && _previewCurrentMode === "code") codeEl.style.display = "";
    else if (mdEl) mdEl.style.display = "";
    _previewDirty = false;
    updateEditBtn();
  }
  async function openFile(path) {
    if (!S.session) return;
    const ext = fileExt(path);
    if (DOWNLOAD_EXTS.has(ext)) {
      downloadFile(path);
      return;
    }
    const previewPathText = $("previewPathText");
    const previewArea = $("previewArea");
    const fileTree = $("fileTree");
    const wsSearch = $("wsSearchWrap");
    if (previewPathText) previewPathText.textContent = path;
    previewArea?.classList.add("visible");
    if (fileTree) fileTree.style.display = "none";
    if (wsSearch) wsSearch.style.display = "none";
    _previewCurrentPath = path;
    renderFileBreadcrumb(path);
    if (IMAGE_EXTS.has(ext)) {
      showPreview("image");
      const url = `api/file/raw?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(path)}`;
      const previewImg = $("previewImg");
      if (previewImg) {
        previewImg.alt = path;
        previewImg.src = url;
        previewImg.onerror = () => setStatus(t("image_load_failed"));
      }
    } else if (MD_EXTS.has(ext)) {
      try {
        const data = await api(`/api/file?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(path)}`);
        showPreview("md");
        _previewRawContent = data.content || "";
        const mdEl = $("previewMd");
        if (mdEl) mdEl.innerHTML = renderMd(data.content || "");
        requestAnimationFrame(() => {
          if (typeof renderKatexBlocks === "function") renderKatexBlocks();
        });
      } catch (e) {
        setStatus(t("file_open_failed"));
      }
    } else {
      try {
        const data = await api(`/api/file?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(path)}`);
        if (data.binary) {
          downloadFile(path);
          return;
        }
        showPreview("code");
        const content = data.content || "";
        const codeEl = $("previewCode");
        if (["yml", "yaml"].includes(ext)) {
          if (codeEl) {
            codeEl.className = "preview-code hl-yaml";
            codeEl.innerHTML = typeof highlightYAML === "function" ? highlightYAML(content) : _highlightWithLineNumbers(content);
          }
        } else if (ext === "json") {
          if (codeEl) {
            codeEl.className = "preview-code hl-json";
            codeEl.innerHTML = _highlightJSON(content);
          }
        } else if (["py", "js", "ts", "sh", "bash", "zsh", "rb", "go", "rs", "java", "c", "cpp", "h", "css", "scss", "html", "xml", "sql", "r", "lua", "pl", "php", "swift", "kt", "dart"].includes(ext)) {
          if (codeEl) {
            codeEl.className = "preview-code";
            codeEl.textContent = content;
            requestAnimationFrame(() => {
              if (typeof highlightCode === "function") highlightCode();
            });
          }
        } else {
          if (codeEl) {
            codeEl.className = "preview-code hl-text";
            codeEl.innerHTML = _highlightWithLineNumbers(content);
          }
        }
      } catch (e) {
        downloadFile(path);
      }
    }
  }
  function downloadFile(path) {
    if (!S.session) return;
    const url = `api/file/raw?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(path)}&download=1`;
    const filename = path.split("/").pop() || path;
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    setTimeout(() => document.body.removeChild(a), 100);
    showToast(t("downloading", filename), 2e3);
  }
  function renderFileBreadcrumb(filePath) {
    const bar = $("breadcrumbBar");
    if (!bar) return;
    bar.style.display = "flex";
    const upBtn = $("btnUpDir");
    if (upBtn) upBtn.style.display = "";
    bar.innerHTML = "";
    const root = document.createElement("span");
    root.className = "breadcrumb-seg breadcrumb-link";
    root.textContent = "~";
    root.onclick = () => {
      clearPreview();
      loadDir(".");
    };
    bar.appendChild(root);
    const parts = filePath.split("/");
    let accumulated = "";
    for (let i = 0; i < parts.length; i++) {
      const sep = document.createElement("span");
      sep.className = "breadcrumb-sep";
      sep.textContent = "/";
      bar.appendChild(sep);
      accumulated += (accumulated ? "/" : "") + parts[i];
      const seg = document.createElement("span");
      seg.textContent = parts[i];
      if (i < parts.length - 1) {
        seg.className = "breadcrumb-seg breadcrumb-link";
        const target = accumulated;
        seg.onclick = () => {
          clearPreview();
          loadDir(target);
        };
      } else {
        seg.className = "breadcrumb-seg breadcrumb-current";
      }
      bar.appendChild(seg);
    }
  }
  function _escHtml(s) {
    return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
  }
  function _highlightWithLineNumbers(text) {
    return text.split("\n").map((line) => '<span class="code-line">' + _escHtml(line) + "</span>").join("\n");
  }
  function _highlightJSON(text) {
    try {
      const pretty = JSON.stringify(JSON.parse(text), null, 2);
      return pretty.split("\n").map((raw) => {
        let line = _escHtml(raw);
        line = line.replace(/^(\s*)(&quot;)([\w\s.\/\-_@:]+)(&quot;)(\s*:)/, '$1<span class="hl-key">$2$3$4</span><span class="hl-value">$5</span>');
        line = line.replace(/(:\s*)(&quot;[^&]*?&quot;)/g, '$1<span class="hl-string">$2</span>');
        line = line.replace(/:\s*(\d+\.?\d*)/g, ': <span class="hl-number">$1</span>');
        line = line.replace(/:\s*(true|false|null)/g, ': <span class="hl-bool">$1</span>');
        return '<span class="code-line">' + line + "</span>";
      }).join("\n");
    } catch {
      return _highlightWithLineNumbers(text);
    }
  }
  let _wsSearchTimer = null;
  function filterWsFiles() {
    clearTimeout(_wsSearchTimer ?? void 0);
    _wsSearchTimer = setTimeout(_doWsSearch, 300);
  }
  async function _doWsSearch() {
    const input = $("wsSearchInput");
    const clearBtn = $("wsSearchClear");
    const tree = $("fileTree");
    if (!input || !tree) return;
    const query = input.value.trim().toLowerCase();
    if (clearBtn) clearBtn.classList.toggle("visible", query.length > 0);
    const oldNoRes = tree.querySelector(".ws-no-results");
    if (oldNoRes) oldNoRes.remove();
    if (!query) {
      if (typeof renderFileTree === "function") renderFileTree();
      return;
    }
    if (!S.session || !S.session.workspace) return;
    tree.innerHTML = '<div class="ws-no-results" style="opacity:.5">Suche...</div>';
    try {
      const data = await api(`/api/list?session_id=${encodeURIComponent(S.session.session_id)}&path=.&search=${encodeURIComponent(query)}`);
      const results = data.entries || [];
      if (!results.length) {
        tree.innerHTML = '<div class="ws-no-results">Keine Dateien gefunden</div>';
        return;
      }
      tree.innerHTML = "";
      for (const item of results) {
        const el = document.createElement("div");
        el.className = "file-item";
        el.style.paddingLeft = "10px";
        const iconEl = document.createElement("span");
        iconEl.className = "file-icon";
        iconEl.innerHTML = fileIcon(item.name, item.type);
        el.appendChild(iconEl);
        const nameEl = document.createElement("span");
        nameEl.className = "file-name";
        nameEl.textContent = item.name;
        el.appendChild(nameEl);
        if (item.path) {
          const pathEl = document.createElement("span");
          pathEl.className = "file-size";
          pathEl.style.opacity = ".4";
          const dir = item.path.substring(0, item.path.lastIndexOf("/"));
          pathEl.textContent = dir || ".";
          el.appendChild(pathEl);
        }
        if (item.type === "dir") el.onclick = () => {
          clearWsSearch();
          loadDir(item.path);
        };
        else el.onclick = () => openFile(item.path);
        tree.appendChild(el);
      }
    } catch {
      tree.innerHTML = "";
      const allItems = S.entries || [];
      const matches = allItems.filter((it) => it.name.toLowerCase().includes(query));
      if (!matches.length) tree.innerHTML = '<div class="ws-no-results">Keine Dateien gefunden</div>';
      else {
        for (const item of matches) {
          const el = document.createElement("div");
          el.className = "file-item";
          el.style.paddingLeft = "10px";
          el.innerHTML = '<span class="file-icon">' + fileIcon(item.name, item.type) + '</span><span class="file-name">' + item.name + "</span>";
          el.onclick = item.type === "dir" ? () => {
            clearWsSearch();
            loadDir(item.path);
          } : () => openFile(item.path);
          tree.appendChild(el);
        }
      }
    }
  }
  function toggleWsSearch() {
    const wrap = $("wsSearchWrap");
    if (!wrap) return;
    wrap.style.display = wrap.style.display === "none" ? "flex" : "none";
    setTimeout(() => {
      if (wrap.style.display !== "none") {
        const inp = $("wsSearchInput");
        if (inp) inp.focus();
      }
    }, 50);
  }
  function clearWsSearch() {
    const input = $("wsSearchInput");
    if (input) input.value = "";
    const clearBtn = $("wsSearchClear");
    if (clearBtn) clearBtn.classList.remove("visible");
    if (typeof renderFileTree === "function") renderFileTree();
  }
  function refreshWorkspace() {
    loadDir(".");
  }
  // ── Export to window for cross-module access ──
  window.loadDir = loadDir;
  window.renderFileTree = renderFileTree;
  window.toggleWsSearch = toggleWsSearch;
  window.clearWsSearch = clearWsSearch;
  window.openFile = openFile;
  window.showPreview = showPreview;
  window.refreshWorkspace = refreshWorkspace;
})();
//# sourceMappingURL=workspace.js.map
