/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/

var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/main.ts
var main_exports = {};
__export(main_exports, {
  default: () => UITweakerPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian19 = require("obsidian");

// src/settings.ts
var DEFAULT_SETTINGS = {
  // Auto-hide elements
  titleBar: "show",
  fileExplorerNavHeader: "show",
  otherNavHeaders: "show",
  leftTabHeaders: "show",
  rightTabHeaders: "show",
  ribbonRevealOnHover: false,
  vaultSwitcher: "show",
  helpButton: "show",
  settingsButton: "show",
  // Simple toggles
  tabBar: false,
  tabBarHideWhenSingle: false,
  enableWindowDragging: false,
  newNoteButton: false,
  newFolderButton: false,
  sortOrderButton: false,
  autoRevealButton: false,
  collapseAllButton: false,
  readingModeButton: false,
  bookmarkedButton: false,
  searchSettingsButton: false,
  tabListIcon: "show",
  newTabIcon: "show",
  tabCloseButton: "show",
  statusBar: false,
  scrollBars: "show",
  leftSidebarToggleButton: "show",
  rightSidebarToggleButton: "show",
  tooltips: false,
  searchSuggestions: false,
  searchTermCounts: false,
  propertiesInReadingView: false,
  propertiesInHeading: false,
  addPropertyButton: false,
  deemphasizeProperties: false,
  instructions: false,
  // Mobile-specific
  mobileChevronsIcon: false,
  navigateBackButton: false,
  navigateForwardButton: false,
  quickSwitcherButton: false,
  mobileNewTabButton: false,
  openTabButton: false,
  ribbonMenuButton: false,
  swapMobileNewTabIcon: false,
  hideMobileTitle: false,
  hideMobileSyncIcon: false,
  hideStatusBarMobile: false,
  // Mobile navigation menu positions
  navigateButtonPosition: "1",
  navigationButtonPosition: "2",
  quickSwitcherPosition: "3",
  newTabPosition: "4",
  openTabsPosition: "5",
  ribbonMenuPosition: "6",
  // Advanced
  vaultSwitcherBackgroundTransparency: 0.98,
  helpButtonReplacement: {
    enabled: false,
    commandId: "",
    iconId: "wrench"
  },
  syncButtonReplacement: {
    enabled: false,
    commandId: "",
    iconId: "wrench"
  },
  // Tab Bar
  tabBarCommands: [],
  // Status Bar
  statusBarItems: [],
  // Explorer
  explorerCommands: [],
  explorerButtonItems: [],
  // Native explorer button colors
  nativeExplorerButtonColors: {
    newNote: void 0,
    newFolder: void 0,
    sortOrder: void 0,
    autoReveal: void 0,
    collapseAll: void 0
  },
  // Native explorer button icon overrides
  nativeExplorerButtonIcons: {
    newNote: void 0,
    newFolder: void 0,
    sortOrder: void 0,
    autoReveal: void 0,
    collapseAll: void 0
  },
  // Property icon settings
  propertyIconItems: [],
  minimalPropertyIcons: false,
  showPropertyMenuActions: true
};

// src/uiManager.ts
var import_obsidian = require("obsidian");

// src/utils/cssUtils.ts
function getVaultSwitcherMask(transparency) {
  if (transparency >= 1) {
    return "none";
  }
  return "linear-gradient(to top, hsl(0, 0%, 0%) 0%, hsla(0, 0%, 0%, 0.99) 18.4%, hsla(0, 0%, 0%, 0.963) 33.7%, hsla(0, 0%, 0%, 0.92) 46.4%, hsla(0, 0%, 0%, 0.864) 56.7%, hsla(0, 0%, 0%, 0.796) 64.8%, hsla(0, 0%, 0%, 0.72) 71.2%, hsla(0, 0%, 0%, 0.637) 76.1%, hsla(0, 0%, 0%, 0.55) 79.9%, hsla(0, 0%, 0%, 0.46) 82.8%, hsla(0, 0%, 0%, 0.37) 85.2%, hsla(0, 0%, 0%, 0.283) 87.3%, hsla(0, 0%, 0%, 0.2) 89.6%, hsla(0, 0%, 0%, 0.124) 92.3%, hsla(0, 0%, 0%, 0.056) 95.6%, hsla(0, 0%, 0%, 0) 100%)";
}
function setCssProps(el, props) {
  Object.entries(props).forEach(([key, value]) => {
    el.style.setProperty(key, String(value));
  });
}

// src/uiManager.ts
var UIManager = class {
  constructor(plugin, settings) {
    this.revealListeners = /* @__PURE__ */ new Map();
    this.tabObserver = null;
    this.sidebarObserver = null;
    this.plugin = plugin;
    this.settings = settings;
  }
  updateSettings(settings) {
    this.settings = settings;
    this.applyStyles();
  }
  detectOS() {
    if (import_obsidian.Platform.isMacOS) {
      return "macos";
    }
    if (import_obsidian.Platform.isWin) {
      return "windows";
    }
    return "neutral";
  }
  applyStyles() {
    var _a;
    const body = document.body;
    this.applyVisibilityState(body, "auto-hide-title-bar", this.settings.titleBar, true);
    this.applyVisibilityState(body, "auto-hide-file-explorer-nav-header", this.settings.fileExplorerNavHeader);
    this.applyVisibilityState(body, "auto-hide-other-nav-headers", this.settings.otherNavHeaders);
    this.applyVisibilityState(body, "auto-hide-left-tab-headers", this.settings.leftTabHeaders);
    this.applyVisibilityState(body, "auto-hide-right-tab-headers", this.settings.rightTabHeaders);
    this.applyVisibilityState(body, "auto-hide-vault-switcher", this.settings.vaultSwitcher);
    this.applyVisibilityState(body, "hider-help-button", this.settings.helpButton);
    this.applyVisibilityState(body, "auto-hide-settings-button", this.settings.settingsButton);
    body.classList.toggle("auto-collapse-ribbon", this.settings.ribbonRevealOnHover);
    body.classList.toggle("ui-tweaker-sync-replacement-enabled", (_a = this.settings.syncButtonReplacement) == null ? void 0 : _a.enabled);
    body.classList.toggle("hider-tabs", this.settings.tabBar);
    if (this.settings.tabBar) {
      const os = this.detectOS();
      body.classList.remove("hider-tabs-windows", "hider-tabs-macos", "hider-tabs-neutral");
      body.classList.add(`hider-tabs-${os}`);
    } else {
      body.classList.remove("hider-tabs-windows", "hider-tabs-macos", "hider-tabs-neutral");
    }
    body.classList.toggle("auto-hide-tab-bar-when-single-tab", this.settings.tabBarHideWhenSingle);
    if (this.settings.tabBarHideWhenSingle) {
      const os = this.detectOS();
      body.classList.remove("auto-hide-tab-bar-windows", "auto-hide-tab-bar-macos", "auto-hide-tab-bar-neutral");
      body.classList.add(`auto-hide-tab-bar-${os}`);
      this.setupTabObserver();
    } else {
      this.cleanupTabObserver();
    }
    if (this.settings.tabBar && this.settings.enableWindowDragging) {
      const os = this.detectOS();
      body.classList.remove("enable-window-dragging-windows", "enable-window-dragging-macos", "enable-window-dragging-neutral");
      body.classList.add(`enable-window-dragging-${os}`);
    } else {
      body.classList.remove("enable-window-dragging-windows", "enable-window-dragging-macos", "enable-window-dragging-neutral");
    }
    body.classList.toggle("hide-button-new-note", this.settings.newNoteButton);
    body.classList.toggle("hide-button-new-folder", this.settings.newFolderButton);
    body.classList.toggle("hide-button-sort-order", this.settings.sortOrderButton);
    body.classList.toggle("hide-button-auto-reveal", this.settings.autoRevealButton);
    body.classList.toggle("hide-button-collapse-all", this.settings.collapseAllButton);
    body.classList.toggle("hide-button-reading-mode", this.settings.readingModeButton);
    body.classList.toggle("hide-button-bookmarked", this.settings.bookmarkedButton);
    body.classList.toggle("hide-button-search-settings", this.settings.searchSettingsButton);
    this.applyVisibilityState(body, "hide-tab-list-icon", this.settings.tabListIcon);
    this.applyVisibilityState(body, "hide-new-tab-icon", this.settings.newTabIcon);
    this.applyVisibilityState(body, "hide-tab-close-button", this.settings.tabCloseButton);
    body.classList.toggle("hider-status", this.settings.statusBar);
    this.applyVisibilityState(body, "hider-scroll", this.settings.scrollBars);
    if (this.settings.scrollBars === "reveal") {
      this.setupScrollbarRevealListeners();
    } else {
      this.removeScrollbarRevealListeners();
    }
    this.applyVisibilityState(body, "hider-left-sidebar-button", this.settings.leftSidebarToggleButton);
    this.applyVisibilityState(body, "hider-right-sidebar-button", this.settings.rightSidebarToggleButton);
    body.classList.toggle("hider-tooltips", this.settings.tooltips);
    body.classList.toggle("hider-search-suggestions", this.settings.searchSuggestions);
    body.classList.toggle("hider-search-counts", this.settings.searchTermCounts);
    body.classList.toggle("hider-meta", this.settings.propertiesInReadingView);
    body.classList.toggle("ui-tweaker-deemphasize-properties", this.settings.deemphasizeProperties);
    body.classList.toggle("metadata-heading-off", this.settings.propertiesInHeading);
    body.classList.toggle("metadata-add-property-off", this.settings.addPropertyButton);
    body.classList.toggle("hider-instructions", this.settings.instructions);
    body.classList.toggle("hide-icon-mobile-chevrons", this.settings.mobileChevronsIcon);
    body.classList.toggle("hide-button-mobile-navbar-action-back", this.settings.navigateBackButton);
    body.classList.toggle("hide-button-mobile-navbar-action-forward", this.settings.navigateForwardButton);
    body.classList.toggle("hide-button-mobile-navbar-action-quick-switcher", this.settings.quickSwitcherButton);
    body.classList.toggle("hide-button-mobile-navbar-action-new-tab", this.settings.mobileNewTabButton);
    body.classList.toggle("hide-button-mobile-navbar-action-tabs", this.settings.openTabButton);
    body.classList.toggle("hide-button-mobile-navbar-action-menu", this.settings.ribbonMenuButton);
    body.classList.toggle("swap-mobile-new-tab-icon", this.settings.swapMobileNewTabIcon);
    body.classList.toggle("hide-mobile-title", this.settings.hideMobileTitle);
    body.classList.toggle("hide-mobile-sync-icon", this.settings.hideMobileSyncIcon);
    body.classList.toggle("hider-status-mobile", this.settings.hideStatusBarMobile);
    const orderClasses = Array.from(body.classList).filter(
      (cls) => cls.startsWith("order-navbar-button-nth-child-")
    );
    orderClasses.forEach((cls) => body.classList.remove(cls));
    body.classList.add(`order-navbar-button-nth-child-1-${this.settings.navigateButtonPosition}`);
    body.classList.add(`order-navbar-button-nth-child-2-${this.settings.navigationButtonPosition}`);
    body.classList.add(`order-navbar-button-nth-child-3-${this.settings.quickSwitcherPosition}`);
    body.classList.add(`order-navbar-button-nth-child-4-${this.settings.newTabPosition}`);
    body.classList.add(`order-navbar-button-nth-child-5-${this.settings.openTabsPosition}`);
    body.classList.add(`order-navbar-button-nth-child-6-${this.settings.ribbonMenuPosition}`);
    const maskValue = getVaultSwitcherMask(this.settings.vaultSwitcherBackgroundTransparency);
    setCssProps(body, {
      "--auto-hide-vault-switcher-bg-transparency": String(this.settings.vaultSwitcherBackgroundTransparency),
      "--auto-hide-vault-switcher-mask": maskValue
    });
  }
  applyVisibilityState(body, className, state, useAlwaysShow = false) {
    if (useAlwaysShow) {
      body.classList.remove("always-show-title-bar", `${className}-hide`, `${className}-reveal`);
    } else {
      body.classList.remove(`${className}-show`, `${className}-hide`, `${className}-reveal`);
    }
    if (state === "show") {
      if (useAlwaysShow) {
        body.classList.add("always-show-title-bar");
      }
    } else if (state === "hide") {
      body.classList.add(`${className}-hide`);
    } else if (state === "reveal") {
      body.classList.add(`${className}-reveal`);
    }
  }
  setupScrollbarRevealListeners() {
    this.removeScrollbarRevealListeners();
    const isScrollable = (element) => {
      const style = window.getComputedStyle(element);
      const overflow = style.overflow + style.overflowY + style.overflowX;
      if (!overflow.includes("scroll") && !overflow.includes("auto")) {
        return false;
      }
      return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
    };
    const hoveredElements = /* @__PURE__ */ new Set();
    const handleMouseMove = (e) => {
      const target = e.target;
      if (!target) return;
      hoveredElements.forEach((el) => {
        el.classList.remove("ui-tweaker-scrollbar-hover");
      });
      hoveredElements.clear();
      let element = target;
      while (element && element !== document.body && element !== document.documentElement) {
        if (isScrollable(element)) {
          const rect = element.getBoundingClientRect();
          const scrollbarArea = 25;
          const isInVerticalScrollbarArea = e.clientX >= rect.right - scrollbarArea && e.clientX <= rect.right;
          const isInHorizontalScrollbarArea = e.clientY >= rect.bottom - scrollbarArea && e.clientY <= rect.bottom;
          if (isInVerticalScrollbarArea || isInHorizontalScrollbarArea) {
            element.classList.add("ui-tweaker-scrollbar-hover");
            hoveredElements.add(element);
          }
        }
        element = element.parentElement;
      }
    };
    const handleMouseLeave = () => {
      hoveredElements.forEach((el) => {
        el.classList.remove("ui-tweaker-scrollbar-hover");
      });
      hoveredElements.clear();
    };
    document.addEventListener("mousemove", handleMouseMove, true);
    document.addEventListener("mouseleave", handleMouseLeave, true);
    this.revealListeners.set("scrollbar-reveal", () => {
      document.removeEventListener("mousemove", handleMouseMove, true);
      document.removeEventListener("mouseleave", handleMouseLeave, true);
      hoveredElements.forEach((el) => {
        el.classList.remove("ui-tweaker-scrollbar-hover");
      });
      hoveredElements.clear();
    });
  }
  removeScrollbarRevealListeners() {
    const cleanup = this.revealListeners.get("scrollbar-reveal");
    if (cleanup) {
      cleanup();
      this.revealListeners.delete("scrollbar-reveal");
    }
  }
  /**
   * Set up MutationObserver to detect single tab state and sidebar state
   * Ported from obsidian-oxygen-settings
   */
  setupTabObserver() {
    if (this.tabObserver) {
      return;
    }
    const checkSidebars = () => {
      var _a, _b;
      const workspace2 = this.plugin.app.workspace;
      const rightSidebarCollapsed = ((_a = workspace2.rightSplit) == null ? void 0 : _a.collapsed) !== false;
      const leftSidebarCollapsed = ((_b = workspace2.leftSplit) == null ? void 0 : _b.collapsed) !== false;
      document.body.classList.toggle("is-right-sidebar-collapsed", rightSidebarCollapsed);
      document.body.classList.toggle("is-left-sidebar-collapsed", leftSidebarCollapsed);
    };
    let checkTimeout = null;
    const debouncedCheck = () => {
      if (checkTimeout) {
        clearTimeout(checkTimeout);
      }
      checkTimeout = window.setTimeout(() => {
        checkSidebars();
        checkTimeout = null;
      }, 150);
    };
    setTimeout(checkSidebars, 100);
    this.tabObserver = new MutationObserver(() => {
      debouncedCheck();
    });
    const workspace = document.querySelector(".workspace");
    if (workspace) {
      this.tabObserver.observe(workspace, {
        childList: true,
        subtree: true
      });
    }
    this.plugin.registerEvent(
      this.plugin.app.workspace.on("layout-change", () => {
        debouncedCheck();
      })
    );
    this.plugin.registerEvent(
      this.plugin.app.workspace.on("resize", () => {
        debouncedCheck();
      })
    );
    const workspaceEl = document.querySelector(".workspace");
    if (workspaceEl) {
      this.sidebarObserver = new MutationObserver((mutations) => {
        let shouldCheck = false;
        mutations.forEach((mutation) => {
          if (mutation.type === "attributes" && mutation.attributeName === "class") {
            shouldCheck = true;
          }
        });
        if (shouldCheck) {
          checkSidebars();
          debouncedCheck();
        }
      });
      this.sidebarObserver.observe(workspaceEl, {
        attributes: true,
        attributeFilter: ["class"]
      });
    }
  }
  /**
   * Cleanup tab observer
   */
  cleanupTabObserver() {
    if (this.tabObserver) {
      this.tabObserver.disconnect();
      this.tabObserver = null;
    }
    if (this.sidebarObserver) {
      this.sidebarObserver.disconnect();
      this.sidebarObserver = null;
    }
    document.body.classList.remove("is-right-sidebar-collapsed", "is-left-sidebar-collapsed");
    document.body.classList.remove("auto-hide-tab-bar-windows", "auto-hide-tab-bar-macos", "auto-hide-tab-bar-neutral");
  }
  cleanup() {
    this.cleanupTabObserver();
    this.revealListeners.forEach((cleanup) => cleanup());
    this.revealListeners.clear();
    const body = document.body;
    const classesToRemove = [];
    body.classList.forEach((className) => {
      if (className.startsWith("ui-tweaker-") || className.startsWith("auto-hide-") || className.startsWith("hider-") || className.startsWith("hide-") || className.startsWith("metadata-") || className.startsWith("order-navbar-button-") || className.startsWith("enable-window-dragging-") || className === "auto-collapse-ribbon" || className === "swap-mobile-new-tab-icon" || className === "always-show-title-bar") {
        classesToRemove.push(className);
      }
    });
    classesToRemove.forEach((className) => body.classList.remove(className));
    body.style.removeProperty("--auto-hide-vault-switcher-bg-transparency");
    body.style.removeProperty("--auto-hide-vault-switcher-mask");
    body.style.removeProperty("--native-button-color-new-note");
    body.style.removeProperty("--native-button-color-new-folder");
    body.style.removeProperty("--native-button-color-sort-order");
    body.style.removeProperty("--native-button-color-auto-reveal");
    body.style.removeProperty("--native-button-color-collapse-all");
  }
};

// src/commands.ts
function registerCommands(context) {
  const { plugin, settings, saveSettings, refresh } = context;
  registerToggleCommand(plugin, "toggle-title-bar", "Toggle title bar", async () => {
    settings.titleBar = toggleVisibilityState(settings.titleBar);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-file-explorer-nav-header", "Toggle file explorer navigation header", async () => {
    settings.fileExplorerNavHeader = toggleVisibilityState(settings.fileExplorerNavHeader);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-other-nav-headers", "Toggle other navigation headers", async () => {
    settings.otherNavHeaders = toggleVisibilityState(settings.otherNavHeaders);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-left-tab-headers", "Toggle left tab headers", async () => {
    settings.leftTabHeaders = toggleVisibilityState(settings.leftTabHeaders);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-right-tab-headers", "Toggle right tab headers", async () => {
    settings.rightTabHeaders = toggleVisibilityState(settings.rightTabHeaders);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-vault-switcher", "Toggle vault switcher", async () => {
    settings.vaultSwitcher = toggleVisibilityState(settings.vaultSwitcher);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-help-button", "Toggle help button", async () => {
    settings.helpButton = toggleVisibilityState(settings.helpButton);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-settings-button", "Toggle settings button", async () => {
    settings.settingsButton = toggleVisibilityState(settings.settingsButton);
    await saveSettings();
    refresh();
  });
  plugin.addCommand({
    id: "open-settings",
    name: "Open settings",
    callback: () => {
      var _a, _b;
      const app = plugin.app;
      const settingApi = app.setting;
      if (settingApi) {
        (_a = settingApi.open) == null ? void 0 : _a.call(settingApi);
        const pluginInstance = plugin;
        if (((_b = pluginInstance.settingTab) == null ? void 0 : _b.id) && settingApi.openTabById) {
          settingApi.openTabById(pluginInstance.settingTab.id);
        }
      }
    }
  });
  registerToggleCommand(plugin, "toggle-tab-bar", "Toggle tab bar", async () => {
    settings.tabBar = !settings.tabBar;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-tab-bar-single", "Toggle hide tab bar when only one tab", async () => {
    settings.tabBarHideWhenSingle = !settings.tabBarHideWhenSingle;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-new-note-button", "Toggle new note button", async () => {
    settings.newNoteButton = !settings.newNoteButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-new-folder-button", "Toggle new folder button", async () => {
    settings.newFolderButton = !settings.newFolderButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-sort-order-button", "Toggle sort order button", async () => {
    settings.sortOrderButton = !settings.sortOrderButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-auto-reveal-button", "Toggle auto reveal button", async () => {
    settings.autoRevealButton = !settings.autoRevealButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-collapse-all-button", "Toggle collapse all button", async () => {
    settings.collapseAllButton = !settings.collapseAllButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-reading-mode-button", "Toggle reading mode button", async () => {
    settings.readingModeButton = !settings.readingModeButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-search-settings-button", "Toggle search settings button", async () => {
    settings.searchSettingsButton = !settings.searchSettingsButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-tab-list-icon", "Toggle tab list icon", async () => {
    settings.tabListIcon = toggleVisibilityState(settings.tabListIcon);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-new-tab-icon", "Toggle new tab icon", async () => {
    settings.newTabIcon = toggleVisibilityState(settings.newTabIcon);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-tab-close-button", "Toggle tab close button", async () => {
    settings.tabCloseButton = toggleVisibilityState(settings.tabCloseButton);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-status-bar", "Toggle status bar", async () => {
    settings.statusBar = !settings.statusBar;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-scroll-bars", "Toggle scroll bars", async () => {
    settings.scrollBars = toggleVisibilityState(settings.scrollBars);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-left-sidebar-toggle-button", "Toggle left sidebar toggle button", async () => {
    settings.leftSidebarToggleButton = toggleVisibilityState(settings.leftSidebarToggleButton);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-right-sidebar-toggle-button", "Toggle right sidebar toggle button", async () => {
    settings.rightSidebarToggleButton = toggleVisibilityState(settings.rightSidebarToggleButton);
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-tooltips", "Toggle tooltips", async () => {
    settings.tooltips = !settings.tooltips;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-search-suggestions", "Toggle search suggestions", async () => {
    settings.searchSuggestions = !settings.searchSuggestions;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-search-term-counts", "Toggle search term counts", async () => {
    settings.searchTermCounts = !settings.searchTermCounts;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-properties-reading-view", "Toggle properties in Reading view", async () => {
    settings.propertiesInReadingView = !settings.propertiesInReadingView;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-deemphasize-properties", "Toggle deemphasize properties", async () => {
    settings.deemphasizeProperties = !settings.deemphasizeProperties;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-properties-heading", "Toggle properties heading", async () => {
    settings.propertiesInHeading = !settings.propertiesInHeading;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-add-property-button", "Toggle add property button", async () => {
    settings.addPropertyButton = !settings.addPropertyButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-instructions", "Toggle instructions", async () => {
    settings.instructions = !settings.instructions;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-mobile-chevrons-icon", "Toggle mobile chevrons icon", async () => {
    settings.mobileChevronsIcon = !settings.mobileChevronsIcon;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-navigate-back-button", "Toggle navigate back button", async () => {
    settings.navigateBackButton = !settings.navigateBackButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-navigate-forward-button", "Toggle navigate forward button", async () => {
    settings.navigateForwardButton = !settings.navigateForwardButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-quick-switcher-button", "Toggle quick switcher button", async () => {
    settings.quickSwitcherButton = !settings.quickSwitcherButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-mobile-new-tab-button", "Toggle mobile new tab button", async () => {
    settings.mobileNewTabButton = !settings.mobileNewTabButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-open-tab-button", "Toggle open tab button", async () => {
    settings.openTabButton = !settings.openTabButton;
    await saveSettings();
    refresh();
  });
  registerToggleCommand(plugin, "toggle-ribbon-menu-button", "Toggle ribbon menu button", async () => {
    settings.ribbonMenuButton = !settings.ribbonMenuButton;
    await saveSettings();
    refresh();
  });
}
function registerToggleCommand(plugin, id, name, callback) {
  plugin.addCommand({
    id,
    name,
    callback
  });
}
function toggleVisibilityState(currentState) {
  if (currentState === "reveal") {
    return "hide";
  }
  return currentState === "show" ? "hide" : "show";
}

// src/ui/SettingsTab.ts
var import_obsidian11 = require("obsidian");

// src/ui/common/TabRenderer.ts
var import_obsidian2 = require("obsidian");
var TabRenderer = class {
  constructor(app, plugin) {
    this.app = app;
    this.plugin = plugin;
  }
  getSettings() {
    return this.plugin.settings;
  }
  async saveSettings() {
    await this.plugin.saveSettings();
    this.plugin.refresh();
  }
  createDropdownSetting(container, name, description, value, options, onChange) {
    return new import_obsidian2.Setting(container).setName(name).setDesc(description).addDropdown((dropdown) => {
      Object.entries(options).forEach(([key, label]) => {
        dropdown.addOption(key, label);
      });
      dropdown.setValue(value);
      dropdown.onChange(async (value2) => {
        onChange(value2);
        await this.saveSettings();
      });
      return dropdown;
    });
  }
  createToggleSetting(container, name, description, value, onChange) {
    return new import_obsidian2.Setting(container).setName(name).setDesc(description).addToggle((toggle) => {
      toggle.setValue(value);
      toggle.onChange(async (value2) => {
        onChange(value2);
        await this.saveSettings();
      });
      return toggle;
    });
  }
  createSliderSetting(container, name, description, value, min, max, step, onChange) {
    return new import_obsidian2.Setting(container).setName(name).setDesc(description).addSlider((slider) => {
      slider.setLimits(min, max, step).setValue(value).setDynamicTooltip().onChange(async (value2) => {
        onChange(value2);
        await this.saveSettings();
      });
      return slider;
    });
  }
};

// src/utils/settings-compat.ts
var import_obsidian3 = require("obsidian");
var ObsidianModule = __toESM(require("obsidian"), 1);
function createSettingsGroup(containerEl, heading, manifestId) {
  if ((0, import_obsidian3.requireApiVersion)("1.11.0")) {
    const SettingGroupClass = ObsidianModule.SettingGroup;
    if (SettingGroupClass) {
      const group = heading ? new SettingGroupClass(containerEl).setHeading(heading) : new SettingGroupClass(containerEl);
      return {
        addSetting(cb) {
          group.addSetting(cb);
        }
      };
    }
  }
  if (manifestId) {
    containerEl.addClass(`${manifestId}-settings-compat`);
  }
  {
    if (heading) {
      const headingEl = containerEl.createDiv("setting-group-heading");
      headingEl.createEl("h3", { text: heading });
    }
    return {
      addSetting(cb) {
        const setting = new import_obsidian3.Setting(containerEl);
        cb(setting);
      }
    };
  }
}

// src/modals/CommandPickerModal.ts
var import_obsidian4 = require("obsidian");
var CommandPickerModal = class extends import_obsidian4.FuzzySuggestModal {
  constructor(app, onSelect) {
    super(app);
    this.onSelect = onSelect;
  }
  getItems() {
    const commandRegistry = this.app.commands;
    const commandMap = /* @__PURE__ */ new Map();
    if (commandRegistry && typeof commandRegistry.listCommands === "function") {
      try {
        const commands = commandRegistry.listCommands();
        for (const command of commands) {
          if (command && command.id && command.name && !commandMap.has(command.id)) {
            commandMap.set(command.id, {
              id: command.id,
              name: command.name
            });
          }
        }
      } catch (e) {
      }
    }
    return Array.from(commandMap.values()).sort((a, b) => a.name.localeCompare(b.name));
  }
  getItemText(item) {
    return item.name;
  }
  onChooseItem(item, evt) {
    this.onSelect(item.id);
  }
};

// src/modals/IconPickerModal.ts
var import_obsidian5 = require("obsidian");
var getIconList = () => {
  if (import_obsidian5.requireApiVersion && (0, import_obsidian5.requireApiVersion)("1.7.3") && import_obsidian5.getIconIds) {
    try {
      return (0, import_obsidian5.getIconIds)();
    } catch (e) {
    }
  }
  return [
    "settings-2",
    "settings",
    "help-circle",
    "info",
    "star",
    "heart",
    "bookmark",
    "home",
    "search",
    "bell",
    "mail",
    "user",
    "users",
    "folder",
    "file",
    "file-text",
    "image",
    "video",
    "music",
    "calendar",
    "clock",
    "edit",
    "pencil",
    "trash",
    "copy",
    "cut",
    "paste",
    "download",
    "upload",
    "save",
    "share",
    "link",
    "external-link",
    "lock",
    "unlock",
    "eye",
    "eye-off",
    "key",
    "shield",
    "check",
    "x",
    "plus",
    "minus",
    "arrow-left",
    "arrow-right",
    "arrow-up",
    "arrow-down",
    "chevron-left",
    "chevron-right",
    "chevron-up",
    "chevron-down",
    "menu",
    "more-horizontal",
    "more-vertical",
    "grid",
    "list",
    "layout",
    "columns",
    "rows",
    "maximize",
    "minimize",
    "zoom-in",
    "zoom-out",
    "refresh-cw",
    "play",
    "pause",
    "stop",
    "sun",
    "moon",
    "cloud",
    "zap",
    "wand-2",
    "wand",
    "wand-sparkles",
    "palette",
    "brush",
    "sliders",
    "power",
    "wifi",
    "bluetooth",
    "monitor",
    "laptop",
    "smartphone",
    "camera",
    "mic",
    "headphones",
    "code",
    "terminal",
    "terminal-square",
    "github",
    "gitlab",
    "git-branch",
    "git-commit",
    "database",
    "server",
    "cloud-download",
    "cloud-upload",
    "tag",
    "tags",
    "flag",
    "pin",
    "map-pin",
    "compass",
    "globe",
    "rocket",
    "car",
    "bike",
    "robot",
    "apple",
    "windows",
    "linux",
    "chrome",
    "firefox",
    "safari",
    "credit-card",
    "wallet",
    "coins",
    "book",
    "book-open",
    "award",
    "trophy",
    "badge",
    "wrench",
    "tool",
    "package",
    "box",
    "archive",
    "send",
    "reply",
    "forward",
    "mail-open",
    "tag-plus",
    "tag-minus",
    "flag-off",
    "pin-off",
    "map-pin-off",
    "navigation",
    "map",
    "earth",
    "plane",
    "ship",
    "anchor",
    "helicopter",
    "drone",
    "android",
    "keyhole",
    "keys",
    "fingerprint",
    "scan",
    "qr-code",
    "barcode",
    "receipt",
    "piggy-bank",
    "banknote"
  ];
};
var LUCIDE_ICONS = getIconList().map((id) => ({
  id,
  name: id.replace(/^lucide-/, "").replace(/-/g, " ").replace(/(^\w{1})|(\s+\w{1})/g, (letter) => letter.toUpperCase())
})).sort((a, b) => a.name.localeCompare(b.name));
var IconPickerModal = class extends import_obsidian5.FuzzySuggestModal {
  constructor(app, onSelect) {
    super(app);
    this.onSelect = onSelect;
  }
  getItems() {
    return LUCIDE_ICONS;
  }
  getItemText(item) {
    return item.name;
  }
  onChooseItem(item, evt) {
    this.onSelect(item.id);
    this.close();
  }
  // Override to show icon preview
  renderSuggestion(match, el) {
    const item = match.item;
    el.addClass("mod-complex");
    const content = el.createDiv({ cls: "suggestion-content" });
    content.createDiv({ cls: "suggestion-title", text: item.name });
    const aux = el.createDiv({ cls: "suggestion-aux" });
    const iconSpan = aux.createSpan({ cls: "suggestion-flair ui-tweaker-icon-no-bg" });
    (0, import_obsidian5.setIcon)(iconSpan, item.id);
  }
};

// src/ui/tabs/HiderTab.ts
var HiderTab = class extends TabRenderer {
  render(container) {
    container.empty();
    const generalGroup = createSettingsGroup(container, void 0, "ui-tweaker");
    this.addVisibilitySetting(
      generalGroup,
      "Title bar",
      "Hide title bar until hover. Turn off to always show.",
      "titleBar"
    );
    this.addVisibilitySetting(
      generalGroup,
      "File explorer nav header",
      "Hide file explorer navigation header until hover. Elegantly reveals on hover.",
      "fileExplorerNavHeader"
    );
    this.addVisibilitySetting(
      generalGroup,
      "Other nav headers",
      "Hide navigation headers for tag, backlinks, outgoing links, outline, and bookmarks panes until hover.",
      "otherNavHeaders"
    );
    this.addVisibilitySetting(
      generalGroup,
      "Left tab headers",
      "Hide left panel tab headers until hover. Elegantly reveals on hover.",
      "leftTabHeaders"
    );
    this.addVisibilitySetting(
      generalGroup,
      "Right tab headers",
      "Hide right panel tab headers until hover. Elegantly reveals on hover.",
      "rightTabHeaders"
    );
    generalGroup.addSetting((setting) => {
      setting.setName("Collapse ribbon").setDesc("Collapse the left ribbon to a thin strip until hover. Elegantly expands on hover.").addToggle(
        (toggle) => toggle.setValue(this.getSettings().ribbonRevealOnHover).onChange((value) => {
          this.getSettings().ribbonRevealOnHover = value;
          void this.saveSettings();
        })
      );
    });
    const navigationGroup = createSettingsGroup(container, "Navigation", "ui-tweaker");
    this.addToggleSetting(navigationGroup, "Hide tab bar", "Hides the tab container at the top of the window.", "tabBar");
    this.addToggleSetting(navigationGroup, "Make top of window draggable without tab bar", 'Enables window dragging from the top of the window when the tab bar is hidden. Only works when "Hide tab bar" is enabled.', "enableWindowDragging");
    this.addToggleSetting(navigationGroup, "Hide tab header when only one tab", "Hide the tab bar automatically when only 1 tab is open.", "tabBarHideWhenSingle");
    this.addToggleSetting(navigationGroup, 'Hide "Reading mode" button', 'Hide "Reading mode" button in view headers.', "readingModeButton");
    this.addToggleSetting(navigationGroup, 'Hide "Bookmarked" button', 'Hide "Bookmarked" button in view headers.', "bookmarkedButton");
    this.addToggleSetting(navigationGroup, 'Hide "Search settings" button', 'Hide "Search settings" button in search pane.', "searchSettingsButton");
    const vaultProfileGroup = createSettingsGroup(container, "Vault profile area", "ui-tweaker");
    this.addVisibilitySetting(
      vaultProfileGroup,
      "Vault switcher",
      "Hide vault switcher until hover. Does not work when vault name is hidden.",
      "vaultSwitcher"
    );
    this.addVisibilitySetting(
      vaultProfileGroup,
      "Help button",
      "Hide help button until hover. Elegantly reveals on hover.",
      "helpButton"
    );
    this.renderHelpButtonReplacement(container, vaultProfileGroup);
    this.addVisibilitySetting(
      vaultProfileGroup,
      "Settings button",
      "Hide settings button until hover. Elegantly reveals on hover.",
      "settingsButton"
    );
    vaultProfileGroup.addSetting((setting) => {
      setting.setName("Vault switcher background transparency").setDesc("Adjust the transparency of the vault switcher background when hidden. Range: 0 (fully transparent) to 1 (fully opaque).").addSlider(
        (slider) => slider.setLimits(0, 1, 0.01).setValue(this.getSettings().vaultSwitcherBackgroundTransparency).setDynamicTooltip().onChange((value) => {
          this.getSettings().vaultSwitcherBackgroundTransparency = value;
          void this.saveSettings();
        })
      );
    });
    const tabIconsGroup = createSettingsGroup(container, "Tab icons", "ui-tweaker");
    this.addVisibilitySetting(
      tabIconsGroup,
      "Hide tab list icon",
      "Hides the tab list icon. You can still access tabs via other methods.",
      "tabListIcon"
    );
    this.addVisibilitySetting(
      tabIconsGroup,
      "Hide new tab icon",
      "Hides the new tab icon. You can still create new tabs with Ctrl+T (Cmd+T on Mac).",
      "newTabIcon"
    );
    this.addVisibilitySetting(
      tabIconsGroup,
      "Hide tab close button",
      "Hides the close button on tabs. You can still close tabs with middle click or other methods.",
      "tabCloseButton"
    );
    const statusUIGroup = createSettingsGroup(container, "Status & UI elements", "ui-tweaker");
    this.addToggleSetting(statusUIGroup, "Hide status bar", "Hides word count, character count and backlink count.", "statusBar");
    this.addVisibilitySetting(
      statusUIGroup,
      "Scroll bars",
      "Control scrollbar visibility. Reveal option hides scrollbars until hover.",
      "scrollBars"
    );
    this.addVisibilitySetting(
      statusUIGroup,
      "Hide left sidebar toggle button",
      "Hides the left sidebar toggle button.",
      "leftSidebarToggleButton"
    );
    this.addVisibilitySetting(
      statusUIGroup,
      "Hide right sidebar toggle button",
      "Hides the right sidebar toggle button.",
      "rightSidebarToggleButton"
    );
    this.addToggleSetting(statusUIGroup, "Hide tooltips", "Hides all tooltips.", "tooltips");
    this.addToggleSetting(statusUIGroup, "Hide instructions", "Hides instructional tips in modals.", "instructions");
    const searchGroup = createSettingsGroup(container, "Search", "ui-tweaker");
    this.addToggleSetting(searchGroup, "Hide search suggestions", "Hides suggestions in search pane.", "searchSuggestions");
    this.addToggleSetting(searchGroup, "Hide count of search term matches", "Hides the number of matches within each search result.", "searchTermCounts");
    const propertiesGroup = createSettingsGroup(container, "Properties", "ui-tweaker");
    this.addToggleSetting(propertiesGroup, "Hide properties in Reading view", "Hides the properties section in Reading view.", "propertiesInReadingView");
    this.addToggleSetting(propertiesGroup, "Deemphasize properties", "Softens visual prominence of file properties. They become more visible on hover.", "deemphasizeProperties");
    this.addToggleSetting(propertiesGroup, "Hide properties heading", 'Hide "Properties" heading above properties.', "propertiesInHeading");
    this.addToggleSetting(propertiesGroup, 'Hide "Add property" button', 'Hide "Add property" button below properties.', "addPropertyButton");
  }
  addVisibilitySetting(group, name, desc, key) {
    group.addSetting((setting) => {
      setting.setName(name).setDesc(desc).addDropdown((dropdown) => {
        const currentValue = this.getSettings()[key];
        const stringValue = typeof currentValue === "string" ? currentValue : "show";
        dropdown.addOption("show", "Show").addOption("hide", "Hide").addOption("reveal", "Reveal").setValue(stringValue).onChange((value) => {
          this.getSettings()[key] = value;
          void this.saveSettings();
        });
      });
    });
  }
  addToggleSetting(group, name, desc, key) {
    group.addSetting((setting) => {
      setting.setName(name).setDesc(desc).addToggle(
        (toggle) => toggle.setValue(Boolean(this.getSettings()[key])).onChange((value) => {
          this.getSettings()[key] = value;
          void this.saveSettings();
        })
      );
    });
  }
  renderHelpButtonReplacement(container, group) {
    const settings = this.getSettings();
    if (!settings.helpButtonReplacement) {
      settings.helpButtonReplacement = {
        enabled: false,
        commandId: "",
        iconId: "wrench"
      };
    }
    const dependentSettings = [];
    group.addSetting((setting) => {
      setting.setName("Replace help button with custom action").setDesc("Replace the help button with a custom icon and command. This will hide the original help button and show your custom button instead.").addToggle(
        (toggle) => toggle.setValue(settings.helpButtonReplacement.enabled).onChange((value) => {
          settings.helpButtonReplacement.enabled = value;
          dependentSettings.forEach((el) => {
            el.style.display = value ? "" : "none";
          });
          void this.saveSettings();
        })
      );
    });
    const getCommandName = (commandId) => {
      if (!commandId) return "Select command...";
      try {
        const commandRegistry = this.app.commands;
        if (commandRegistry && typeof commandRegistry.listCommands === "function") {
          const commands = commandRegistry.listCommands();
          const command = commands.find((cmd) => cmd && cmd.id === commandId);
          if (command == null ? void 0 : command.name) {
            return command.name;
          }
        }
      } catch (e) {
      }
      return "Select command...";
    };
    const getIconName = (iconId) => {
      if (!iconId) return "";
      return iconId.replace(/^lucide-/, "").split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
    };
    group.addSetting((setting) => {
      dependentSettings.push(setting.settingEl);
      setting.settingEl.style.display = settings.helpButtonReplacement.enabled ? "" : "none";
      setting.setName("Command").setDesc("Select the command to execute when the button is clicked").addButton(
        (button) => button.setButtonText(getCommandName(settings.helpButtonReplacement.commandId)).onClick(() => {
          const modal = new CommandPickerModal(this.app, (commandId) => {
            settings.helpButtonReplacement.commandId = commandId;
            button.setButtonText(getCommandName(commandId));
            void this.saveSettings();
          });
          modal.open();
        })
      );
    });
    group.addSetting((setting) => {
      dependentSettings.push(setting.settingEl);
      setting.settingEl.style.display = settings.helpButtonReplacement.enabled ? "" : "none";
      setting.setName("Icon").setDesc("Select the icon to display on the button").addButton(
        (button) => button.setButtonText(getIconName(settings.helpButtonReplacement.iconId) || "Select icon...").onClick(() => {
          const modal = new IconPickerModal(this.app, (iconId) => {
            settings.helpButtonReplacement.iconId = iconId;
            button.setButtonText(getIconName(iconId));
            void this.saveSettings();
          });
          modal.open();
        })
      );
    });
  }
};

// src/ui/tabs/TabBarTab.ts
var import_obsidian7 = require("obsidian");

// src/modals/NamePickerModal.ts
var import_obsidian6 = require("obsidian");
var NamePickerModal = class extends import_obsidian6.Modal {
  constructor(app, defaultName, onSubmit) {
    super(app);
    this.defaultName = defaultName;
    this.onSubmit = onSubmit;
  }
  onOpen() {
    const { contentEl } = this;
    contentEl.empty();
    contentEl.createEl("h2", { text: "Enter name" });
    const inputContainer = contentEl.createDiv();
    const input = new import_obsidian6.TextComponent(inputContainer);
    input.setValue(this.defaultName);
    input.setPlaceholder("Enter custom name...");
    input.inputEl.addClass("ui-tweaker-name-input");
    input.inputEl.select();
    const buttonContainer = contentEl.createDiv({ cls: "modal-button-container" });
    const submitButton = buttonContainer.createEl("button", { text: "OK", cls: "mod-cta" });
    const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
    const handleSubmit = () => {
      const value = input.getValue().trim();
      if (value) {
        this.onSubmit(value);
        this.close();
      }
    };
    submitButton.addEventListener("click", handleSubmit);
    cancelButton.addEventListener("click", () => this.close());
    input.inputEl.addEventListener("keydown", (evt) => {
      if (evt.key === "Enter") {
        evt.preventDefault();
        handleSubmit();
      }
      if (evt.key === "Escape") {
        evt.preventDefault();
        this.close();
      }
    });
  }
  onClose() {
    const { contentEl } = this;
    contentEl.empty();
  }
};

// src/utils/chooseCommand.ts
async function chooseNewCommand(plugin) {
  return new Promise((resolve, reject) => {
    let commandSelected = false;
    let iconSelected = false;
    const commandModal = new CommandPickerModal(plugin.app, (commandId) => {
      var _a;
      commandSelected = true;
      const commands = plugin.app.commands;
      const command = (_a = commands == null ? void 0 : commands.commands) == null ? void 0 : _a[commandId];
      setTimeout(() => {
        commandModal.close();
      }, 0);
      const displayName = (command == null ? void 0 : command.name) || "Custom Command";
      const iconModal = new IconPickerModal(plugin.app, (iconId) => {
        iconSelected = true;
        iconModal.close();
        setTimeout(() => {
          let nameSelected = false;
          const nameModal = new NamePickerModal(plugin.app, displayName, (customName) => {
            nameSelected = true;
            nameModal.close();
            resolve({
              id: commandId,
              icon: iconId,
              name: customName,
              displayName,
              mode: "any"
            });
          });
          nameModal.onClose = () => {
            setTimeout(() => {
              if (!nameSelected && iconSelected && commandSelected) {
                reject(new Error("No name selected"));
              }
            }, 0);
          };
          nameModal.open();
        }, 100);
      });
      iconModal.onClose = () => {
        setTimeout(() => {
          if (!iconSelected && commandSelected) {
            reject(new Error("No icon selected"));
          }
        }, 0);
      };
      setTimeout(() => {
        iconModal.open();
      }, 100);
    });
    commandModal.onClose = () => {
      setTimeout(() => {
        if (!commandSelected) {
          reject(new Error("No command selected"));
        }
      }, 0);
    };
    commandModal.open();
  });
}

// src/ui/tabs/TabBarTab.ts
function arrayMoveMutable(array, from, to) {
  const item = array[from];
  array.splice(from, 1);
  array.splice(to, 0, item);
}
var TabBarTab = class extends TabRenderer {
  constructor() {
    super(...arguments);
    this.expandedStates = /* @__PURE__ */ new Map();
  }
  render(container) {
    container.empty();
    const settings = this.getSettings();
    if (!settings.tabBarCommands) {
      settings.tabBarCommands = [];
    }
    settings.tabBarCommands.forEach((pair, index) => {
      this.renderCommandItem(container, pair, index);
    });
    if (settings.tabBarCommands.length > 0) {
      container.createEl("hr");
    }
    const addGroup = createSettingsGroup(container, void 0, "ui-tweaker");
    addGroup.addSetting((setting) => {
      setting.setName("Add command").setDesc("Add a new command button to the tab bar").addButton((button) => {
        const buttonEl = button.buttonEl;
        const iconContainer = buttonEl.createSpan({ cls: "ui-tweaker-add-icon" });
        (0, import_obsidian7.setIcon)(iconContainer, "lucide-image-plus");
        buttonEl.insertBefore(iconContainer, buttonEl.firstChild);
        button.setButtonText("Add command").setCta().onClick(() => {
          void (async () => {
            var _a;
            try {
              const pair = await chooseNewCommand(this.plugin);
              await ((_a = this.plugin.tabBarManager) == null ? void 0 : _a.addCommand(pair));
              this.render(container);
            } catch (e) {
            }
          })();
        });
      });
    });
  }
  renderCommandItem(container, pair, index) {
    const settings = this.getSettings();
    const group = createSettingsGroup(container, void 0, "ui-tweaker");
    const otherSettings = [];
    const displayName = pair.displayName || pair.name;
    group.addSetting((setting) => {
      var _a;
      setting.settingEl.addEventListener("click", (e) => {
        const target = e.target;
        const isChevronClick = target.closest(".ui-tweaker-collapse-icon") !== null;
        const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
        const isNameEdit = target.closest(".ui-tweaker-name-display") !== null || target.closest(".ui-tweaker-edit-icon") !== null || target.closest(".ui-tweaker-editable-name") !== null;
        if (!isChevronClick && !isExtraButton && !isNameEdit) {
          e.stopPropagation();
          e.stopImmediatePropagation();
          e.preventDefault();
          return false;
        }
      }, true);
      setting.settingEl.addEventListener("click", (e) => {
        const target = e.target;
        const isChevronClick = target.closest(".ui-tweaker-collapse-icon") !== null;
        const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
        const isNameEdit = target.closest(".ui-tweaker-name-display") !== null || target.closest(".ui-tweaker-edit-icon") !== null || target.closest(".ui-tweaker-editable-name") !== null;
        if (!isChevronClick && !isExtraButton && !isNameEdit) {
          e.stopPropagation();
          e.stopImmediatePropagation();
          e.preventDefault();
          return false;
        }
      }, false);
      const nameEl = setting.nameEl;
      setCssProps(nameEl, { display: "flex", alignItems: "center", gap: "0.5rem", width: "100%" });
      const chevronContainer = document.createElement("div");
      chevronContainer.className = "ui-tweaker-collapse-icon";
      setCssProps(chevronContainer, {
        cursor: "default",
        background: "transparent",
        padding: "0",
        margin: "0",
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center"
      });
      nameEl.insertBefore(chevronContainer, nameEl.firstChild);
      let isExpanded = (_a = this.expandedStates.get(pair.id)) != null ? _a : false;
      (0, import_obsidian7.setIcon)(chevronContainer, isExpanded ? "chevrons-down-up" : "chevrons-up-down");
      chevronContainer.addEventListener("click", (e) => {
        e.stopPropagation();
        e.stopImmediatePropagation();
        e.preventDefault();
        isExpanded = !isExpanded;
        this.expandedStates.set(pair.id, isExpanded);
        (0, import_obsidian7.setIcon)(chevronContainer, isExpanded ? "chevrons-down-up" : "chevrons-up-down");
        otherSettings.forEach((settingEl) => {
          setCssProps(settingEl, { display: isExpanded ? "" : "none" });
        });
      });
      const nameContainer = nameEl.createDiv({ cls: "ui-tweaker-editable-name" });
      setCssProps(nameContainer, { display: "flex", alignItems: "center", gap: "0.5rem" });
      const createNameDisplay = (name) => {
        nameContainer.empty();
        const display = nameContainer.createSpan({
          text: name === displayName ? name : `${name} (${displayName})`,
          cls: "ui-tweaker-name-display"
        });
        const iconContainer = nameContainer.createDiv({ cls: "ui-tweaker-edit-icon" });
        setCssProps(iconContainer, { opacity: "0.6" });
        (0, import_obsidian7.setIcon)(iconContainer, "lucide-pencil-line");
        const startEdit = () => {
          const currentName = pair.name;
          nameContainer.empty();
          const nameInput = nameContainer.createEl("input", {
            type: "text",
            value: currentName
          });
          nameInput.addClass("mod-text-input");
          nameInput.focus();
          nameInput.select();
          const saveName = () => {
            var _a2;
            nameInput.removeEventListener("blur", saveName);
            let newName = nameInput.value.trim();
            if (!newName) {
              newName = currentName;
            }
            pair.name = newName;
            (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.updateButtonNames();
            void (async () => {
              await this.saveSettings();
              this.render(container);
            })();
          };
          nameInput.addEventListener("keydown", (e) => {
            if (e.key === "Enter") {
              e.preventDefault();
              saveName();
            } else if (e.key === "Escape") {
              e.preventDefault();
              createNameDisplay(currentName);
            }
          });
          nameInput.addEventListener("blur", saveName);
        };
        display.addEventListener("click", startEdit);
        iconContainer.addEventListener("click", startEdit);
        iconContainer.addEventListener("mouseenter", () => {
          setCssProps(iconContainer, { opacity: "1" });
        });
        iconContainer.addEventListener("mouseleave", () => {
          setCssProps(iconContainer, { opacity: "0.6" });
        });
      };
      createNameDisplay(pair.name);
      setting.setDesc("").addExtraButton((button) => {
        const iconEl = button.extraSettingsEl;
        (0, import_obsidian7.setIcon)(iconEl, pair.icon);
        iconEl.setAttribute("data-command-id", pair.id);
        if (pair.color && pair.color !== "#000000") {
          setCssProps(iconEl, { color: pair.color });
        } else {
          iconEl.style.removeProperty("color");
        }
        button.setTooltip("Change icon");
        button.onClick(() => {
          const modal = new IconPickerModal(this.app, (iconId) => {
            void (async () => {
              var _a2;
              if (iconId && iconId !== pair.icon) {
                pair.icon = iconId;
                await this.saveSettings();
                (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.reorder();
                this.render(container);
              }
            })();
          });
          modal.open();
        });
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("chevron-up");
        if (index > 0) {
          button.setTooltip("Move up");
          button.onClick(() => {
            const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
            const scrollPos = scrollContainer.scrollTop;
            void (async () => {
              var _a2;
              arrayMoveMutable(settings.tabBarCommands, index, index - 1);
              await this.saveSettings();
              (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.reorder();
              this.render(container);
              requestAnimationFrame(() => {
                scrollContainer.scrollTop = scrollPos;
                setTimeout(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 50);
                }, 0);
              });
            })();
          });
        } else {
          button.setTooltip("Already at top");
          button.extraSettingsEl.addClass("ui-tweaker-disabled-button");
          setCssProps(button.extraSettingsEl, { pointerEvents: "none" });
        }
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("chevron-down");
        if (index < settings.tabBarCommands.length - 1) {
          button.setTooltip("Move down");
          button.onClick(() => {
            const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
            const scrollPos = scrollContainer.scrollTop;
            void (async () => {
              var _a2;
              arrayMoveMutable(settings.tabBarCommands, index, index + 1);
              await this.saveSettings();
              (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.reorder();
              this.render(container);
              requestAnimationFrame(() => {
                scrollContainer.scrollTop = scrollPos;
                setTimeout(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 50);
                }, 0);
              });
            })();
          });
        } else {
          button.setTooltip("Already at bottom");
          button.extraSettingsEl.addClass("ui-tweaker-disabled-button");
          setCssProps(button.extraSettingsEl, { pointerEvents: "none" });
        }
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("trash");
        button.setTooltip("Delete");
        button.extraSettingsEl.addClass("mod-warning");
        setCssProps(button.extraSettingsEl, { color: "var(--text-error)" });
        button.onClick(() => {
          void (async () => {
            var _a2;
            settings.tabBarCommands.splice(index, 1);
            await this.saveSettings();
            await ((_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.removeCommand(pair));
            this.render(container);
          })();
        });
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      setting.setName("Device mode").setDesc("Choose which devices this command appears on").addDropdown((dropdown) => {
        const appId = this.app.appId || "this-device";
        dropdown.addOption("any", "All devices").addOption("desktop", "Desktop only").addOption("mobile", "Mobile only").addOption(appId, "This device");
        const currentValue = pair.mode === "any" || pair.mode === "desktop" || pair.mode === "mobile" ? pair.mode : appId;
        dropdown.setValue(currentValue);
        dropdown.onChange((value) => {
          void (async () => {
            var _a;
            pair.mode = value;
            await this.saveSettings();
            (_a = this.plugin.tabBarManager) == null ? void 0 : _a.reorder();
            this.render(container);
          })();
        });
        dropdown.selectEl.addEventListener("click", (e) => e.stopPropagation());
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      const hasColor = pair.color !== void 0;
      setting.setName("Custom color").setDesc("Set a custom color for this icon").addColorPicker((colorPicker) => {
        var _a;
        const currentColor = (_a = pair.color) != null ? _a : "#000000";
        colorPicker.setValue(currentColor);
        const controlEl = setting.controlEl;
        controlEl.addEventListener("click", (e) => e.stopPropagation());
        setTimeout(() => {
          const colorInput = controlEl.querySelector('input[type="color"]');
          if (colorInput) {
            colorInput.addEventListener("click", (e) => e.stopPropagation());
          }
        }, 0);
        if (hasColor) {
          setTimeout(() => {
            const colorPickerEl = controlEl.querySelector(".color-picker") || controlEl.lastElementChild;
            const resetButton = controlEl.createEl("button", {
              cls: "clickable-icon ui-tweaker-color-reset",
              attr: { "aria-label": "Reset to default color" }
            });
            (0, import_obsidian7.setIcon)(resetButton, "lucide-rotate-cw");
            setCssProps(resetButton, { marginRight: "0.5rem" });
            resetButton.addEventListener("click", (e) => {
              e.stopPropagation();
              e.stopImmediatePropagation();
              e.preventDefault();
              void (async () => {
                var _a2;
                pair.color = void 0;
                const iconButton = container.querySelector(`[data-command-id="${pair.id}"]`);
                if (iconButton) {
                  iconButton.style.removeProperty("color");
                }
                await this.saveSettings();
                (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.reorder();
                this.render(container);
              })();
            });
            if (colorPickerEl) {
              controlEl.insertBefore(resetButton, colorPickerEl);
            } else {
              controlEl.insertBefore(resetButton, controlEl.firstChild);
            }
          }, 0);
        }
        colorPicker.onChange((value) => {
          if (value === "#000000") {
            pair.color = void 0;
          } else {
            pair.color = value;
          }
          const iconButton = container.querySelector(`[data-command-id="${pair.id}"]`);
          if (iconButton) {
            if (pair.color && pair.color !== "#000000") {
              setCssProps(iconButton, { color: pair.color });
            } else {
              iconButton.style.removeProperty("color");
            }
          }
          void (async () => {
            var _a2;
            await this.saveSettings();
            (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.reorder();
            this.render(container);
          })();
        });
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      const hasToggleIcon = pair.toggleIcon !== void 0;
      setting.setName("Toggle icon").setDesc("Icon to show when command is toggled on (leave empty to disable toggle). Commands with check callback work automatically. See readme for plugin developer compatibility notes.").setTooltip("For plugin developers: Commands with checkCallback work automatically. See https://github.com/davidvkimball/obsidian-ui-tweaker#toggle-icon-feature-compatibility for details.").addButton((button) => {
        const currentToggleIcon = pair.toggleIcon || "None";
        button.setButtonText(currentToggleIcon === "None" ? "Set toggle icon..." : currentToggleIcon).onClick(() => {
          const modal = new IconPickerModal(this.app, (iconId) => {
            void (async () => {
              var _a;
              if (iconId) {
                pair.toggleIcon = iconId;
              } else {
                pair.toggleIcon = void 0;
              }
              await this.saveSettings();
              (_a = this.plugin.tabBarManager) == null ? void 0 : _a.reorder();
              this.render(container);
            })();
          });
          modal.open();
        });
        button.buttonEl.addEventListener("click", (e) => e.stopPropagation());
        if (hasToggleIcon) {
          setTimeout(() => {
            const controlEl = setting.controlEl;
            const buttonEl = controlEl.querySelector("button") || controlEl.lastElementChild;
            const resetButton = controlEl.createEl("button", {
              cls: "clickable-icon ui-tweaker-toggle-icon-reset",
              attr: { "aria-label": "Reset toggle icon" }
            });
            (0, import_obsidian7.setIcon)(resetButton, "lucide-rotate-cw");
            setCssProps(resetButton, { marginRight: "0.5rem" });
            resetButton.addEventListener("click", (e) => {
              e.stopPropagation();
              e.stopImmediatePropagation();
              e.preventDefault();
              const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
              const scrollPos = scrollContainer.scrollTop;
              void (async () => {
                var _a;
                pair.toggleIcon = void 0;
                await this.saveSettings();
                (_a = this.plugin.tabBarManager) == null ? void 0 : _a.reorder();
                this.render(container);
                requestAnimationFrame(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 0);
                });
              })();
            });
            if (buttonEl) {
              controlEl.insertBefore(resetButton, buttonEl);
            } else {
              controlEl.insertBefore(resetButton, controlEl.firstChild);
            }
          }, 0);
        }
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      setting.setName("Show only on these file types").setDesc('Show button only on specified file types or views. Enter comma-separated file extensions (like "md,mdx") or view types for views without files (like "{{graph}}"). Leave empty to show on all. Use {{graph}} for graph view and {{empty}} for blank/new tabs.').addText((text) => {
        var _a;
        text.setPlaceholder("Example: md, mdx");
        text.setValue((_a = pair.showOnFileTypes) != null ? _a : "");
        text.onChange((value) => {
          void (async () => {
            var _a2;
            pair.showOnFileTypes = value.trim() || void 0;
            await this.saveSettings();
            (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.reorder();
          })();
        });
        text.inputEl.addEventListener("click", (e) => e.stopPropagation());
        text.inputEl.addEventListener("focus", (e) => e.stopPropagation());
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      setting.setName("Never show on these file types").setDesc('Hide button on specified file types or views. Enter comma-separated file extensions (like "jpg,png") or view types for views without files (like "{{graph}}"). Leave empty to allow all. Use {{graph}} for graph view and {{empty}} for blank/new tabs.').addText((text) => {
        var _a;
        text.setPlaceholder("{{graph}},{{empty}}");
        text.setValue((_a = pair.hideOnFileTypes) != null ? _a : "");
        text.onChange((value) => {
          void (async () => {
            var _a2;
            pair.hideOnFileTypes = value.trim() || void 0;
            await this.saveSettings();
            (_a2 = this.plugin.tabBarManager) == null ? void 0 : _a2.reorder();
          })();
        });
        text.inputEl.addEventListener("click", (e) => e.stopPropagation());
        text.inputEl.addEventListener("focus", (e) => e.stopPropagation());
      });
    });
    setTimeout(() => {
      var _a;
      const savedExpanded = (_a = this.expandedStates.get(pair.id)) != null ? _a : false;
      otherSettings.forEach((settingEl) => {
        setCssProps(settingEl, { display: savedExpanded ? "" : "none" });
      });
    }, 0);
  }
};

// src/ui/tabs/StatusBarTab.ts
var import_obsidian8 = require("obsidian");
function arrayMoveMutable2(array, from, to) {
  const item = array[from];
  array.splice(from, 1);
  array.splice(to, 0, item);
}
var dragging = false;
var StatusBarTab = class extends TabRenderer {
  render(container) {
    container.empty();
    const settings = this.getSettings();
    this.container = container;
    if (!settings.statusBarItems) {
      settings.statusBarItems = [];
    }
    const wrapper = container.createDiv("ui-tweaker-status-bar-rows-wrapper");
    const rowsContainer = wrapper.createDiv("ui-tweaker-status-bar-rows-container");
    settings.statusBarItems.forEach((item, index) => {
      if (item.type === "existing") {
        this.renderExistingRow(rowsContainer, item, settings, index, settings.statusBarItems.length);
      } else {
        this.renderCustomRow(rowsContainer, item, settings, index, settings.statusBarItems.length);
      }
    });
    if (settings.statusBarItems.length > 0) {
      container.createEl("hr");
    }
    const addGroup = createSettingsGroup(container, void 0, "ui-tweaker");
    addGroup.addSetting((setting) => {
      setting.setName("Add command").setDesc("Add a new command button to the status bar").addButton((button) => {
        const buttonEl = button.buttonEl;
        const iconContainer = buttonEl.createSpan({ cls: "ui-tweaker-add-icon" });
        (0, import_obsidian8.setIcon)(iconContainer, "lucide-image-plus");
        buttonEl.insertBefore(iconContainer, buttonEl.firstChild);
        button.setButtonText("Add command").setCta().onClick(() => {
          void (async () => {
            var _a;
            try {
              const pair = await chooseNewCommand(this.plugin);
              await ((_a = this.plugin.statusBarManager) == null ? void 0 : _a.addCustomCommand(pair));
              const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.parentElement;
              const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0;
              this.render(container);
              requestAnimationFrame(() => {
                if (scrollContainer) {
                  scrollContainer.scrollTop = scrollTop;
                }
              });
            } catch (e) {
            }
          })();
        });
      });
    });
  }
  /**
   * Render an existing status bar item row (EXACTLY like Status Bar Organizer)
   */
  renderExistingRow(rowsContainer, item, settings, index, totalItems) {
    var _a;
    const statusBarContainer = (_a = this.plugin.app.statusBar) == null ? void 0 : _a.containerEl;
    const actualElement = statusBarContainer == null ? void 0 : statusBarContainer.querySelector(`[data-ui-tweaker-status-bar-id="${item.id}"]`);
    const exists = !!actualElement;
    const entry = rowsContainer.createDiv("ui-tweaker-status-bar-row");
    entry.addClass("ui-tweaker-row");
    if (!exists) entry.addClass("ui-tweaker-status-bar-row-disabled");
    if (item.hidden) entry.addClass("ui-tweaker-status-bar-row-hidden");
    entry.setAttribute("data-ui-tweaker-id", item.id);
    const handle = entry.createSpan("ui-tweaker-status-bar-row-handle");
    handle.addEventListener(
      "mousedown",
      (event) => this.handleMouseDown(event, rowsContainer, item, settings)
    );
    const titleSpan = entry.createSpan("ui-tweaker-status-bar-row-title");
    titleSpan.textContent = item.name;
    const previewSpan = entry.createSpan("ui-tweaker-status-bar-row-preview");
    if (exists && actualElement) {
      const cloned = actualElement.cloneNode(true);
      setCssProps(cloned, { display: "", visibility: "", opacity: "" });
      cloned.querySelectorAll("*").forEach((child) => {
        setCssProps(child, { display: "", visibility: "", opacity: "" });
      });
      previewSpan.appendChild(cloned);
    }
    entry.createSpan("ui-tweaker-status-bar-row-reset-color");
    entry.createSpan("ui-tweaker-status-bar-row-color-picker");
    entry.createSpan("ui-tweaker-status-bar-row-md-only");
    const lockSpan = entry.createSpan("ui-tweaker-status-bar-row-lock");
    const lockIcon = item.sticky === "right" ? "corner-right-down" : item.sticky === "left" ? "corner-right-up" : "unlock";
    lockSpan.setAttribute("aria-label", item.sticky ? `Pinned to ${item.sticky === "right" ? "End" : "Start"}` : "Unlocked - click to pin to end");
    lockSpan.addEventListener("click", (e) => {
      e.stopPropagation();
      this.toggleLock(item, lockSpan, index, totalItems, rowsContainer, settings);
    });
    (0, import_obsidian8.setIcon)(lockSpan, lockIcon);
    if (item.sticky) {
      lockSpan.addClass("ui-tweaker-locked");
    }
    const visibilitySpan = entry.createSpan("ui-tweaker-status-bar-row-visibility");
    if (item.type === "custom") {
      visibilitySpan.setAttribute("aria-label", "Delete item");
      visibilitySpan.addClass("mod-warning");
      setCssProps(visibilitySpan, { color: "var(--text-error)" });
      visibilitySpan.addEventListener("click", () => {
        void this.removeItem(rowsContainer, item, settings);
      });
      (0, import_obsidian8.setIcon)(visibilitySpan, "trash-2");
    } else {
      visibilitySpan.setAttribute("aria-label", item.hidden ? "Hidden - click to show" : "Visible - click to hide");
      visibilitySpan.addEventListener("click", () => {
        this.toggleVisibility(item, visibilitySpan, entry);
      });
      (0, import_obsidian8.setIcon)(visibilitySpan, item.hidden ? "eye-off" : "eye");
    }
  }
  /**
   * Render a custom status bar item row (EXACTLY like Status Bar Organizer, but with editable name)
   */
  renderCustomRow(rowsContainer, item, settings, index, totalItems) {
    const entry = rowsContainer.createDiv("ui-tweaker-status-bar-row");
    entry.addClass("ui-tweaker-row");
    if (item.hidden) entry.addClass("ui-tweaker-status-bar-row-hidden");
    entry.setAttribute("data-ui-tweaker-id", item.id);
    const handle = entry.createSpan("ui-tweaker-status-bar-row-handle");
    handle.addEventListener(
      "mousedown",
      (event) => this.handleMouseDown(event, rowsContainer, item, settings)
    );
    const titleSpan = entry.createSpan("ui-tweaker-status-bar-row-title");
    const displayName = item.displayName || item.name;
    const nameText = item.name === displayName ? item.name : `${item.name} (${displayName})`;
    titleSpan.textContent = nameText;
    titleSpan.addEventListener("dblclick", () => {
      const currentName = item.name;
      const input = document.createElement("input");
      input.type = "text";
      input.value = currentName;
      input.addClass("mod-text-input");
      setCssProps(input, { width: "100%" });
      titleSpan.empty();
      titleSpan.appendChild(input);
      input.focus();
      input.select();
      const saveName = () => {
        var _a;
        let newName = input.value.trim();
        if (!newName) newName = currentName;
        item.name = newName;
        (_a = this.plugin.statusBarManager) == null ? void 0 : _a.updateButtonNames();
        titleSpan.textContent = newName === displayName ? newName : `${newName} (${displayName})`;
        void this.saveSettings();
      };
      input.addEventListener("keydown", (e) => {
        if (e.key === "Enter") {
          e.preventDefault();
          saveName();
        } else if (e.key === "Escape") {
          e.preventDefault();
          titleSpan.textContent = nameText;
        }
      });
      input.addEventListener("blur", saveName);
    });
    const previewSpan = entry.createSpan("ui-tweaker-status-bar-row-preview");
    if (item.icon) {
      const previewIcon = previewSpan.createSpan("status-bar-item mod-clickable");
      (0, import_obsidian8.setIcon)(previewIcon, item.icon);
      if (item.color && item.color !== "#000000") {
        setCssProps(previewIcon, { color: item.color });
      }
    }
    const resetColorContainer = entry.createSpan("ui-tweaker-status-bar-row-reset-color");
    if (item.color) {
      const resetButton = resetColorContainer.createEl("button", {
        cls: "clickable-icon ui-tweaker-color-reset",
        attr: { "aria-label": "Reset to default color" }
      });
      (0, import_obsidian8.setIcon)(resetButton, "rotate-cw");
      resetButton.addEventListener("click", (e) => {
        var _a;
        e.stopPropagation();
        item.color = void 0;
        const previewIcon = previewSpan.querySelector(".clickable-icon");
        if (previewIcon) {
          previewIcon.style.removeProperty("color");
        }
        (_a = this.plugin.statusBarManager) == null ? void 0 : _a.reorder();
        void this.saveSettings();
        if (this.container) {
          this.render(this.container);
        }
      });
    }
    const colorPickerContainer = entry.createSpan("ui-tweaker-status-bar-row-color-picker");
    const colorPickerEl = colorPickerContainer.createDiv();
    const colorPicker = new import_obsidian8.ColorComponent(colorPickerEl);
    colorPicker.setValue(item.color || "#000000");
    colorPicker.onChange((value) => {
      var _a;
      if (value === "#000000") {
        item.color = void 0;
      } else {
        item.color = value;
      }
      const previewIcon = previewSpan.querySelector(".clickable-icon");
      if (previewIcon) {
        if (item.color && item.color !== "#000000") {
          setCssProps(previewIcon, { color: item.color });
        } else {
          previewIcon.style.removeProperty("color");
        }
      }
      (_a = this.plugin.statusBarManager) == null ? void 0 : _a.reorder();
      void this.saveSettings();
      if (this.container) {
        this.render(this.container);
      }
    });
    const mdOnlySpan = entry.createSpan("ui-tweaker-status-bar-row-md-only");
    mdOnlySpan.setAttribute("aria-label", item.mdOnly ? "Only show on Markdown files (enabled)" : "Only show on Markdown files (disabled)");
    mdOnlySpan.addEventListener("click", (e) => {
      var _a;
      e.stopPropagation();
      item.mdOnly = !item.mdOnly;
      (0, import_obsidian8.setIcon)(mdOnlySpan, item.mdOnly ? "file-check" : "file-x");
      mdOnlySpan.setAttribute("aria-label", item.mdOnly ? "Only show on Markdown files (enabled)" : "Only show on Markdown files (disabled)");
      if (item.mdOnly) {
        mdOnlySpan.addClass("ui-tweaker-active");
      } else {
        mdOnlySpan.removeClass("ui-tweaker-active");
      }
      (_a = this.plugin.statusBarManager) == null ? void 0 : _a.reorder();
      void this.saveSettings();
    });
    (0, import_obsidian8.setIcon)(mdOnlySpan, item.mdOnly ? "file-check" : "file-x");
    if (item.mdOnly) {
      mdOnlySpan.addClass("ui-tweaker-active");
    }
    const lockSpan = entry.createSpan("ui-tweaker-status-bar-row-lock");
    const lockIcon = item.sticky === "right" ? "corner-right-down" : item.sticky === "left" ? "corner-right-up" : "unlock";
    lockSpan.setAttribute("aria-label", item.sticky ? `Pinned to ${item.sticky === "right" ? "End" : "Start"}` : "Unlocked - click to pin to end");
    lockSpan.addEventListener("click", (e) => {
      e.stopPropagation();
      this.toggleLock(item, lockSpan, index, totalItems, rowsContainer, settings);
    });
    (0, import_obsidian8.setIcon)(lockSpan, lockIcon);
    if (item.sticky) {
      lockSpan.addClass("ui-tweaker-locked");
    }
    const visibilitySpan = entry.createSpan("ui-tweaker-status-bar-row-visibility");
    if (item.type === "custom") {
      visibilitySpan.setAttribute("aria-label", "Delete item");
      visibilitySpan.addClass("mod-warning");
      setCssProps(visibilitySpan, { color: "var(--text-error)" });
      visibilitySpan.addEventListener("click", () => {
        void this.removeItem(rowsContainer, item, settings);
      });
      (0, import_obsidian8.setIcon)(visibilitySpan, "trash-2");
    } else {
      visibilitySpan.setAttribute("aria-label", item.hidden ? "Hidden - click to show" : "Visible - click to hide");
      visibilitySpan.addEventListener("click", () => {
        this.toggleVisibility(item, visibilitySpan, entry);
      });
      (0, import_obsidian8.setIcon)(visibilitySpan, item.hidden ? "eye-off" : "eye");
    }
  }
  /**
   * Toggle lock position based on current position
   */
  toggleLock(item, lockSpan, currentIndex, totalItems, rowsContainer, settings) {
    var _a;
    if (!item.sticky) {
      item.sticky = "right";
      const oldIndex = settings.statusBarItems.findIndex((i) => i.id === item.id);
      if (oldIndex !== -1) {
        arrayMoveMutable2(settings.statusBarItems, oldIndex, settings.statusBarItems.length - 1);
      }
    } else if (item.sticky === "right") {
      item.sticky = "left";
      const oldIndex = settings.statusBarItems.findIndex((i) => i.id === item.id);
      if (oldIndex !== -1) {
        arrayMoveMutable2(settings.statusBarItems, oldIndex, 0);
      }
    } else {
      item.sticky = false;
    }
    (_a = this.plugin.statusBarManager) == null ? void 0 : _a.reorder();
    void this.saveSettings();
    if (this.container) {
      this.render(this.container);
    }
  }
  /**
   * Toggle visibility (exactly like Status Bar Organizer)
   */
  toggleVisibility(item, visibilitySpan, entry) {
    var _a;
    item.hidden = !item.hidden;
    if (item.hidden) {
      entry.addClass("ui-tweaker-status-bar-row-hidden");
      (0, import_obsidian8.setIcon)(visibilitySpan, "eye-off");
      visibilitySpan.setAttribute("aria-label", "Hidden - click to show");
    } else {
      entry.removeClass("ui-tweaker-status-bar-row-hidden");
      (0, import_obsidian8.setIcon)(visibilitySpan, "eye");
      visibilitySpan.setAttribute("aria-label", "Visible - click to hide");
    }
    (_a = this.plugin.statusBarManager) == null ? void 0 : _a.reorder();
    void this.saveSettings();
  }
  /**
   * Remove item (exactly like Status Bar Organizer)
   */
  async removeItem(rowsContainer, item, settings) {
    var _a;
    const entry = rowsContainer.querySelector(`[data-ui-tweaker-id="${item.id}"]`);
    if (entry) {
      rowsContainer.removeChild(entry);
    }
    await ((_a = this.plugin.statusBarManager) == null ? void 0 : _a.removeItem(item));
    void this.saveSettings();
  }
  /**
   * Handle mouse down for dragging (exactly like Status Bar Organizer)
   */
  handleMouseDown(event, rowsContainer, item, settings) {
    var _a, _b;
    if (dragging) return;
    dragging = true;
    const entry = rowsContainer.querySelector(`[data-ui-tweaker-id="${item.id}"]`);
    if (!entry) return;
    const stationaryRow = entry;
    stationaryRow.addClass("ui-tweaker-status-bar-row-clone");
    const movableRow = document.createElement("div");
    movableRow.addClass("ui-tweaker-status-bar-row");
    movableRow.addClass("ui-tweaker-status-bar-row-drag");
    setCssProps(movableRow, {
      display: "grid",
      gridTemplateColumns: "1.25em 0.5fr 0.8fr 2em 2em 2em 2em 2em 2em"
    });
    if (item.hidden) movableRow.addClass("ui-tweaker-status-bar-row-hidden");
    if (item.type === "existing") {
      const statusBarContainer = (_a = this.plugin.app.statusBar) == null ? void 0 : _a.containerEl;
      const actualElement = statusBarContainer == null ? void 0 : statusBarContainer.querySelector(`[data-ui-tweaker-id="${item.id}"]`);
      if (!actualElement) movableRow.addClass("ui-tweaker-status-bar-row-disabled");
    }
    const wrapper = rowsContainer.closest(".ui-tweaker-status-bar-rows-wrapper") || rowsContainer.parentElement || rowsContainer;
    wrapper.appendChild(movableRow);
    const containerX = wrapper.getBoundingClientRect().left;
    const containerY = wrapper.getBoundingClientRect().top;
    const stationaryRect = stationaryRow.getBoundingClientRect();
    setCssProps(movableRow, {
      position: "absolute",
      left: stationaryRect.left - containerX + "px",
      top: stationaryRect.top - containerY + "px",
      width: stationaryRow.offsetWidth + "px"
    });
    movableRow.createSpan("ui-tweaker-status-bar-row-handle");
    const dragTitle = movableRow.createSpan("ui-tweaker-status-bar-row-title");
    dragTitle.textContent = item.name;
    const dragPreview = movableRow.createSpan("ui-tweaker-status-bar-row-preview");
    if (item.type === "existing") {
      const statusBarContainer = (_b = this.plugin.app.statusBar) == null ? void 0 : _b.containerEl;
      const actualElement = statusBarContainer == null ? void 0 : statusBarContainer.querySelector(`[data-ui-tweaker-status-bar-id="${item.id}"]`);
      if (actualElement) {
        const cloned = actualElement.cloneNode(true);
        cloned.removeAttribute("aria-label");
        cloned.removeAttribute("title");
        cloned.querySelectorAll("[aria-label], [title]").forEach((el) => {
          el.removeAttribute("aria-label");
          el.removeAttribute("title");
        });
        dragPreview.appendChild(cloned);
      }
    } else if (item.icon) {
      const previewIcon = dragPreview.createSpan("status-bar-item clickable-icon");
      (0, import_obsidian8.setIcon)(previewIcon, item.icon);
      previewIcon.removeAttribute("aria-label");
      previewIcon.removeAttribute("title");
      if (item.color && item.color !== "#000000") {
        setCssProps(previewIcon, { color: item.color });
      }
    }
    movableRow.createSpan("ui-tweaker-status-bar-row-reset-color");
    movableRow.createSpan("ui-tweaker-status-bar-row-color-picker");
    movableRow.createSpan("ui-tweaker-status-bar-row-md-only");
    const dragLock = movableRow.createSpan("ui-tweaker-status-bar-row-lock");
    const lockIcon = item.sticky === "right" ? "corner-right-down" : item.sticky === "left" ? "corner-right-up" : "unlock";
    (0, import_obsidian8.setIcon)(dragLock, lockIcon);
    const dragVisibility = movableRow.createSpan("ui-tweaker-status-bar-row-visibility");
    (0, import_obsidian8.setIcon)(dragVisibility, item.hidden ? "eye-off" : "eye");
    let offsetX = event.clientX - movableRow.getBoundingClientRect().left;
    let offsetY = event.clientY - movableRow.getBoundingClientRect().top;
    offsetX = offsetX + containerX;
    offsetY = offsetY + containerY;
    let index = Array.from(rowsContainer.children).indexOf(stationaryRow);
    const handleMouseMove = (e) => {
      var _a2;
      setCssProps(movableRow, {
        left: e.clientX - offsetX + "px",
        top: e.clientY - offsetY + "px"
      });
      const dist = movableRow.getBoundingClientRect().top - stationaryRow.getBoundingClientRect().top;
      if (Math.abs(dist) > stationaryRow.offsetHeight * 0.75) {
        const dir = dist / Math.abs(dist);
        const newIndex = Math.max(0, Math.min(index + dir, rowsContainer.children.length - 1));
        if (newIndex !== index) {
          rowsContainer.removeChild(stationaryRow);
          if (newIndex < rowsContainer.children.length) {
            rowsContainer.insertBefore(stationaryRow, rowsContainer.children[newIndex]);
          } else {
            rowsContainer.appendChild(stationaryRow);
          }
          if (settings.statusBarItems) {
            const oldIndex = settings.statusBarItems.findIndex((i) => i.id === item.id);
            if (oldIndex !== -1 && oldIndex !== newIndex) {
              arrayMoveMutable2(settings.statusBarItems, oldIndex, newIndex);
              (_a2 = this.plugin.statusBarManager) == null ? void 0 : _a2.reorder();
            }
          }
          index = newIndex;
        }
      }
    };
    const handleMouseUp = () => {
      var _a2;
      stationaryRow.removeClass("ui-tweaker-status-bar-row-clone");
      if (movableRow.parentElement === wrapper) {
        wrapper.removeChild(movableRow);
      }
      dragging = false;
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseup", handleMouseUp);
      (_a2 = this.plugin.statusBarManager) == null ? void 0 : _a2.reorder();
      void this.saveSettings();
    };
    window.addEventListener("mousemove", handleMouseMove);
    window.addEventListener("mouseup", handleMouseUp);
  }
};

// src/ui/tabs/ExplorerTab.ts
var import_obsidian9 = require("obsidian");
function arrayMoveMutable3(array, from, to) {
  const item = array[from];
  array.splice(from, 1);
  array.splice(to, 0, item);
}
var ExplorerTab = class extends TabRenderer {
  constructor() {
    super(...arguments);
    this.expandedStates = /* @__PURE__ */ new Map();
  }
  render(container) {
    container.empty();
    const settings = this.getSettings();
    if (!settings.explorerCommands) {
      settings.explorerCommands = [];
    }
    if (!settings.explorerButtonItems) {
      settings.explorerButtonItems = [];
    }
    if (!settings.nativeExplorerButtonColors) {
      settings.nativeExplorerButtonColors = {
        newNote: void 0,
        newFolder: void 0,
        sortOrder: void 0,
        autoReveal: void 0,
        collapseAll: void 0
      };
    }
    if (!settings.nativeExplorerButtonIcons) {
      settings.nativeExplorerButtonIcons = {
        newNote: void 0,
        newFolder: void 0,
        sortOrder: void 0,
        autoReveal: void 0,
        collapseAll: void 0
      };
    }
    settings.explorerButtonItems.forEach((item, index) => {
      this.renderButtonItem(container, item, index);
    });
    if (settings.explorerButtonItems.length > 0) {
      container.createEl("hr");
    }
    const addGroup = createSettingsGroup(container, void 0, "ui-tweaker");
    addGroup.addSetting((setting) => {
      setting.setName("Add command").setDesc("Add a new command button to the file explorer navigation area").addButton((button) => {
        const buttonEl = button.buttonEl;
        const iconContainer = buttonEl.createSpan({ cls: "ui-tweaker-add-icon" });
        (0, import_obsidian9.setIcon)(iconContainer, "lucide-image-plus");
        buttonEl.insertBefore(iconContainer, buttonEl.firstChild);
        button.setButtonText("Add command").setCta().onClick(() => {
          void (async () => {
            var _a;
            try {
              const pair = await chooseNewCommand(this.plugin);
              settings.explorerCommands.push(pair);
              const item = {
                id: `custom-${pair.id}`,
                name: pair.name,
                ariaLabel: pair.name,
                type: "custom",
                commandId: pair.id,
                icon: pair.icon,
                displayName: pair.displayName,
                mode: pair.mode,
                color: pair.color,
                showOnFileTypes: pair.showOnFileTypes,
                hideOnFileTypes: pair.hideOnFileTypes,
                toggleIcon: pair.toggleIcon,
                useActiveClass: pair.useActiveClass,
                hidden: false
              };
              settings.explorerButtonItems.push(item);
              await this.saveSettings();
              (_a = this.plugin.explorerManager) == null ? void 0 : _a.reorder();
              this.render(container);
            } catch (e) {
            }
          })();
        });
      });
    });
    const warningDiv = container.createEl("div", {
      cls: "callout",
      attr: { "data-callout": "warning" }
    });
    warningDiv.createEl("p", {
      text: "When clicking on a command in the explorer, the explorer view will become focused. This might interfere with commands that are supposed to be executed on an active file or explorer."
    });
  }
  renderNativeButtonControls(container, mainContainer) {
    container.empty();
    const settings = this.getSettings();
    const group = createSettingsGroup(container, "Native explorer buttons", "ui-tweaker");
    const scrollContainer = mainContainer || container;
    const renderNativeButton = (name, settingKey, colorKey) => {
      var _a, _b;
      const isHidden = settings[settingKey];
      const color = (_a = settings.nativeExplorerButtonColors) == null ? void 0 : _a[colorKey];
      const iconOverride = (_b = settings.nativeExplorerButtonIcons) == null ? void 0 : _b[colorKey];
      group.addSetting((setting) => {
        setting.setName(name).setDesc("").addExtraButton((button) => {
          const iconEl = button.extraSettingsEl;
          (0, import_obsidian9.setIcon)(iconEl, isHidden ? "eye-off" : "eye");
          button.setTooltip(isHidden ? "Show button" : "Hide button");
          button.onClick(() => {
            void (async () => {
              const currentValue = settings[settingKey];
              settings[settingKey] = !currentValue;
              await this.saveSettings();
              const newIsHidden = settings[settingKey];
              (0, import_obsidian9.setIcon)(iconEl, newIsHidden ? "eye-off" : "eye");
              button.setTooltip(newIsHidden ? "Show button" : "Hide button");
            })();
          });
          button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
        });
        if (color) {
          setting.addColorPicker((colorPicker) => {
            colorPicker.setValue(color);
            const controlEl = setting.controlEl;
            controlEl.addEventListener("click", (e) => e.stopPropagation());
            setTimeout(() => {
              const colorInput = controlEl.querySelector('input[type="color"]');
              if (colorInput) {
                colorInput.addEventListener("click", (e) => e.stopPropagation());
              }
            }, 0);
            setTimeout(() => {
              const colorPickerEl = controlEl.querySelector(".color-picker") || controlEl.lastElementChild;
              const resetButton = controlEl.createEl("button", {
                cls: "clickable-icon ui-tweaker-color-reset",
                attr: { "aria-label": "Reset to default color" }
              });
              (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
              setCssProps(resetButton, { marginRight: "0.5rem" });
              resetButton.addEventListener("click", (e) => {
                e.stopPropagation();
                e.stopImmediatePropagation();
                e.preventDefault();
                const scrollPos = scrollContainer.scrollTop;
                void (async () => {
                  var _a2;
                  if (!settings.nativeExplorerButtonColors) {
                    settings.nativeExplorerButtonColors = {};
                  }
                  settings.nativeExplorerButtonColors[colorKey] = void 0;
                  await this.saveSettings();
                  (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                  this.renderNativeButtonControls(container, mainContainer);
                  requestAnimationFrame(() => {
                    scrollContainer.scrollTop = scrollPos;
                  });
                })();
              });
              if (colorPickerEl) {
                controlEl.insertBefore(resetButton, colorPickerEl);
              } else {
                controlEl.insertBefore(resetButton, controlEl.firstChild);
              }
            }, 0);
            colorPicker.onChange((value) => {
              void (async () => {
                var _a2;
                if (!settings.nativeExplorerButtonColors) {
                  settings.nativeExplorerButtonColors = {};
                }
                settings.nativeExplorerButtonColors[colorKey] = value;
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
              })();
            });
          });
        } else {
          setting.addButton((button) => {
            button.setButtonText("Set color...").onClick(() => {
              const scrollPos = scrollContainer.scrollTop;
              if (!settings.nativeExplorerButtonColors) {
                settings.nativeExplorerButtonColors = {};
              }
              settings.nativeExplorerButtonColors[colorKey] = "#000000";
              void (async () => {
                var _a2;
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                this.renderNativeButtonControls(container, mainContainer);
                requestAnimationFrame(() => {
                  scrollContainer.scrollTop = scrollPos;
                });
              })();
            });
            button.buttonEl.addEventListener("click", (e) => e.stopPropagation());
          });
        }
        setting.addButton((button) => {
          const currentIcon = iconOverride || "Default";
          button.setButtonText(currentIcon === "Default" ? "Set icon..." : currentIcon).onClick(() => {
            const modal = new IconPickerModal(this.app, (iconId) => {
              void (async () => {
                var _a2;
                const scrollPos = scrollContainer.scrollTop;
                if (!settings.nativeExplorerButtonIcons) {
                  settings.nativeExplorerButtonIcons = {};
                }
                if (iconId) {
                  settings.nativeExplorerButtonIcons[colorKey] = iconId;
                } else {
                  settings.nativeExplorerButtonIcons[colorKey] = void 0;
                }
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                this.renderNativeButtonControls(container, mainContainer);
                requestAnimationFrame(() => {
                  scrollContainer.scrollTop = scrollPos;
                });
              })();
            });
            modal.open();
          });
          button.buttonEl.addEventListener("click", (e) => e.stopPropagation());
          if (iconOverride) {
            setTimeout(() => {
              const controlEl = setting.controlEl;
              const buttonEl = controlEl.querySelector("button") || controlEl.lastElementChild;
              const resetButton = controlEl.createEl("button", {
                cls: "clickable-icon ui-tweaker-icon-reset",
                attr: { "aria-label": "Reset to default icon" }
              });
              (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
              setCssProps(resetButton, { marginRight: "0.5rem" });
              resetButton.addEventListener("click", (e) => {
                e.stopPropagation();
                e.stopImmediatePropagation();
                e.preventDefault();
                const scrollPos = scrollContainer.scrollTop;
                void (async () => {
                  var _a2;
                  if (!settings.nativeExplorerButtonIcons) {
                    settings.nativeExplorerButtonIcons = {};
                  }
                  settings.nativeExplorerButtonIcons[colorKey] = void 0;
                  await this.saveSettings();
                  (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                  this.renderNativeButtonControls(container, mainContainer);
                  requestAnimationFrame(() => {
                    scrollContainer.scrollTop = scrollPos;
                  });
                })();
              });
              if (buttonEl) {
                controlEl.insertBefore(resetButton, buttonEl);
              } else {
                controlEl.insertBefore(resetButton, controlEl.firstChild);
              }
            }, 0);
          }
        });
      });
    };
    renderNativeButton("New note", "newNoteButton", "newNote");
    renderNativeButton("New folder", "newFolderButton", "newFolder");
    renderNativeButton("Sort order", "sortOrderButton", "sortOrder");
    renderNativeButton("Auto-reveal", "autoRevealButton", "autoReveal");
    renderNativeButton("Collapse all", "collapseAllButton", "collapseAll");
  }
  renderButtonItem(container, item, index) {
    var _a, _b;
    const settings = this.getSettings();
    const group = createSettingsGroup(container, void 0, "ui-tweaker");
    const otherSettings = [];
    const pair = item.type === "custom" && item.commandId ? settings.explorerCommands.find((c) => c.id === item.commandId) : null;
    const displayName = item.type === "custom" && pair ? pair.displayName || pair.name : item.name;
    const nativeButtonMap = {
      "native-newNote": { settingKey: "newNoteButton", colorKey: "newNote" },
      "native-newFolder": { settingKey: "newFolderButton", colorKey: "newFolder" },
      "native-sortOrder": { settingKey: "sortOrderButton", colorKey: "sortOrder" },
      "native-autoReveal": { settingKey: "autoRevealButton", colorKey: "autoReveal" },
      "native-collapseAll": { settingKey: "collapseAllButton", colorKey: "collapseAll" }
    };
    const nativeButtonInfo = item.type === "native" ? nativeButtonMap[item.id] : null;
    const isHidden = nativeButtonInfo ? settings[nativeButtonInfo.settingKey] : item.hidden;
    const color = nativeButtonInfo ? (_a = settings.nativeExplorerButtonColors) == null ? void 0 : _a[nativeButtonInfo.colorKey] : item.color && item.color !== "#000000" ? item.color : void 0;
    const iconOverride = nativeButtonInfo ? (_b = settings.nativeExplorerButtonIcons) == null ? void 0 : _b[nativeButtonInfo.colorKey] : item.icon || void 0;
    group.addSetting((setting) => {
      var _a2;
      if (item.type === "external") {
        setting.settingEl.addEventListener("click", (e) => {
          const target = e.target;
          const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
          if (!isExtraButton) {
            e.stopPropagation();
            e.stopImmediatePropagation();
            e.preventDefault();
            return false;
          }
        }, true);
        setting.settingEl.addEventListener("click", (e) => {
          const target = e.target;
          const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
          if (!isExtraButton) {
            e.stopPropagation();
            e.stopImmediatePropagation();
            e.preventDefault();
            return false;
          }
        }, false);
      } else {
        setting.settingEl.addEventListener("click", (e) => {
          const target = e.target;
          const isChevronClick = target.closest(".ui-tweaker-collapse-icon") !== null;
          const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
          const isNameEdit = target.closest(".ui-tweaker-name-display") !== null || target.closest(".ui-tweaker-edit-icon") !== null || target.closest(".ui-tweaker-editable-name") !== null;
          if (!isChevronClick && !isExtraButton && !isNameEdit) {
            e.stopPropagation();
            e.stopImmediatePropagation();
            e.preventDefault();
            return false;
          }
        }, true);
        setting.settingEl.addEventListener("click", (e) => {
          const target = e.target;
          const isChevronClick = target.closest(".ui-tweaker-collapse-icon") !== null;
          const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
          const isNameEdit = target.closest(".ui-tweaker-name-display") !== null || target.closest(".ui-tweaker-edit-icon") !== null || target.closest(".ui-tweaker-editable-name") !== null;
          if (!isChevronClick && !isExtraButton && !isNameEdit) {
            e.stopPropagation();
            e.stopImmediatePropagation();
            e.preventDefault();
            return false;
          }
        }, false);
      }
      const nameEl = setting.nameEl;
      setCssProps(nameEl, { display: "flex", alignItems: "center", gap: "0.5rem", width: "100%" });
      let chevronContainer = null;
      let isExpanded = false;
      if (item.type === "native" || item.type === "custom") {
        chevronContainer = document.createElement("div");
        chevronContainer.className = "ui-tweaker-collapse-icon";
        setCssProps(chevronContainer, {
          cursor: "default",
          background: "transparent",
          padding: "0",
          margin: "0",
          display: "inline-flex",
          alignItems: "center",
          justifyContent: "center"
        });
        nameEl.insertBefore(chevronContainer, nameEl.firstChild);
        isExpanded = (_a2 = this.expandedStates.get(item.id)) != null ? _a2 : false;
        (0, import_obsidian9.setIcon)(chevronContainer, isExpanded ? "chevrons-down-up" : "chevrons-up-down");
        chevronContainer.addEventListener("click", (e) => {
          e.stopPropagation();
          e.stopImmediatePropagation();
          e.preventDefault();
          isExpanded = !isExpanded;
          this.expandedStates.set(item.id, isExpanded);
          (0, import_obsidian9.setIcon)(chevronContainer, isExpanded ? "chevrons-down-up" : "chevrons-up-down");
          otherSettings.forEach((settingEl) => {
            setCssProps(settingEl, { display: isExpanded ? "" : "none" });
          });
        });
      }
      const nameContainer = nameEl.createDiv({ cls: "ui-tweaker-editable-name" });
      setCssProps(nameContainer, { display: "flex", alignItems: "center", gap: "0.5rem" });
      const createNameDisplay = (name) => {
        nameContainer.empty();
        const display = nameContainer.createSpan({
          text: name === displayName ? name : `${name} (${displayName})`,
          cls: "ui-tweaker-name-display"
        });
        if (item.type === "custom") {
          const iconContainer = nameContainer.createDiv({ cls: "ui-tweaker-edit-icon" });
          setCssProps(iconContainer, { opacity: "0.6" });
          (0, import_obsidian9.setIcon)(iconContainer, "lucide-pencil-line");
          const startEdit = () => {
            const currentName = item.name;
            nameContainer.empty();
            const nameInput = nameContainer.createEl("input", {
              type: "text",
              value: currentName
            });
            nameInput.addClass("mod-text-input");
            nameInput.focus();
            nameInput.select();
            const saveName = () => {
              var _a3;
              nameInput.removeEventListener("blur", saveName);
              let newName = nameInput.value.trim();
              if (!newName) {
                newName = currentName;
              }
              item.name = newName;
              if (pair) {
                pair.name = newName;
              }
              (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.updateButtonNames();
              void (async () => {
                await this.saveSettings();
                this.render(container);
              })();
            };
            nameInput.addEventListener("keydown", (e) => {
              if (e.key === "Enter") {
                e.preventDefault();
                saveName();
              } else if (e.key === "Escape") {
                e.preventDefault();
                createNameDisplay(currentName);
              }
            });
            nameInput.addEventListener("blur", saveName);
          };
          display.addEventListener("click", startEdit);
          iconContainer.addEventListener("click", startEdit);
          iconContainer.addEventListener("mouseenter", () => {
            setCssProps(iconContainer, { opacity: "1" });
          });
          iconContainer.addEventListener("mouseleave", () => {
            setCssProps(iconContainer, { opacity: "0.6" });
          });
        }
      };
      createNameDisplay(item.name);
      setting.setDesc("").addExtraButton((button) => {
        if (item.type === "custom" && pair) {
          const iconEl = button.extraSettingsEl;
          (0, import_obsidian9.setIcon)(iconEl, pair.icon);
          iconEl.setAttribute("data-explorer-command-id", pair.id);
          if (pair.color && pair.color !== "#000000") {
            setCssProps(iconEl, { color: pair.color });
          } else {
            iconEl.style.removeProperty("color");
          }
          button.setTooltip("Change icon");
          button.onClick(() => {
            const modal = new IconPickerModal(this.app, (iconId) => {
              void (async () => {
                var _a3;
                if (iconId && iconId !== pair.icon) {
                  pair.icon = iconId;
                  item.icon = iconId;
                  await this.saveSettings();
                  (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
                  this.render(container);
                }
              })();
            });
            modal.open();
          });
        } else if (item.type === "native" && iconOverride) {
          const iconEl = button.extraSettingsEl;
          (0, import_obsidian9.setIcon)(iconEl, iconOverride);
          button.setTooltip("Change icon");
          button.onClick(() => {
            const modal = new IconPickerModal(this.app, (iconId) => {
              void (async () => {
                var _a3;
                if (!nativeButtonInfo) return;
                if (!settings.nativeExplorerButtonIcons) {
                  settings.nativeExplorerButtonIcons = {};
                }
                if (iconId) {
                  settings.nativeExplorerButtonIcons[nativeButtonInfo.colorKey] = iconId;
                } else {
                  settings.nativeExplorerButtonIcons[nativeButtonInfo.colorKey] = void 0;
                }
                await this.saveSettings();
                (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.applyNativeIconOverrides();
                this.render(container);
              })();
            });
            modal.open();
          });
        } else {
          setCssProps(button.extraSettingsEl, { display: "none" });
        }
        button.extraSettingsEl.addEventListener("mouseenter", (e) => e.stopPropagation());
        button.extraSettingsEl.addEventListener("mouseleave", (e) => e.stopPropagation());
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("chevron-up");
        if (index > 0) {
          button.setTooltip("Move up");
          button.onClick(() => {
            const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
            const scrollPos = scrollContainer.scrollTop;
            void (async () => {
              var _a3;
              arrayMoveMutable3(settings.explorerButtonItems, index, index - 1);
              await this.saveSettings();
              (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
              this.render(container);
              requestAnimationFrame(() => {
                scrollContainer.scrollTop = scrollPos;
                setTimeout(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 50);
                }, 0);
              });
            })();
          });
        } else {
          button.setTooltip("Already at top");
          button.extraSettingsEl.addClass("ui-tweaker-disabled-button");
          setCssProps(button.extraSettingsEl, { pointerEvents: "none" });
        }
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("chevron-down");
        if (index < settings.explorerButtonItems.length - 1) {
          button.setTooltip("Move down");
          button.onClick(() => {
            const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
            const scrollPos = scrollContainer.scrollTop;
            void (async () => {
              var _a3;
              arrayMoveMutable3(settings.explorerButtonItems, index, index + 1);
              await this.saveSettings();
              (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
              this.render(container);
              requestAnimationFrame(() => {
                scrollContainer.scrollTop = scrollPos;
                setTimeout(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 50);
                }, 0);
              });
            })();
          });
        } else {
          button.setTooltip("Already at bottom");
          button.extraSettingsEl.addClass("ui-tweaker-disabled-button");
          setCssProps(button.extraSettingsEl, { pointerEvents: "none" });
        }
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      });
      if (item.type === "custom") {
        setting.addExtraButton((button) => {
          button.setIcon("trash");
          button.setTooltip("Delete");
          button.extraSettingsEl.addClass("mod-warning");
          setCssProps(button.extraSettingsEl, { color: "var(--text-error)" });
          button.onClick(() => {
            void (async () => {
              var _a3;
              const itemIdx = settings.explorerButtonItems.indexOf(item);
              if (itemIdx > -1) {
                settings.explorerButtonItems.splice(itemIdx, 1);
              }
              if (pair) {
                const cmdIdx = settings.explorerCommands.indexOf(pair);
                if (cmdIdx > -1) {
                  settings.explorerCommands.splice(cmdIdx, 1);
                }
              }
              await this.saveSettings();
              (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
              this.render(container);
            })();
          });
          button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
        });
      }
      if (item.type === "native" && nativeButtonInfo || item.type === "external") {
        setting.addExtraButton((button) => {
          const iconEl = button.extraSettingsEl;
          (0, import_obsidian9.setIcon)(iconEl, isHidden ? "eye-off" : "eye");
          button.setTooltip(isHidden ? "Show button" : "Hide button");
          button.onClick(() => {
            void (async () => {
              var _a3;
              if (item.type === "native" && nativeButtonInfo) {
                settings[nativeButtonInfo.settingKey] = !settings[nativeButtonInfo.settingKey];
                item.hidden = settings[nativeButtonInfo.settingKey];
              } else if (item.type === "external") {
                item.hidden = !item.hidden;
              }
              await this.saveSettings();
              const newIsHidden = item.hidden;
              (0, import_obsidian9.setIcon)(iconEl, newIsHidden ? "eye-off" : "eye");
              button.setTooltip(newIsHidden ? "Show button" : "Hide button");
              (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
            })();
          });
          button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
        });
      }
    });
    if (item.type === "native" || item.type === "custom") {
      if (item.type === "native" && nativeButtonInfo) {
        group.addSetting((setting) => {
          otherSettings.push(setting.settingEl);
          const hasColor = color !== void 0;
          setting.setName("Custom color").setDesc("Set a custom color for this icon").addColorPicker((colorPicker) => {
            const currentColor = color != null ? color : "#000000";
            colorPicker.setValue(currentColor);
            const controlEl = setting.controlEl;
            controlEl.addEventListener("click", (e) => e.stopPropagation());
            setTimeout(() => {
              const colorInput = controlEl.querySelector('input[type="color"]');
              if (colorInput) {
                colorInput.addEventListener("click", (e) => e.stopPropagation());
              }
            }, 0);
            if (hasColor) {
              setTimeout(() => {
                const colorPickerEl = controlEl.querySelector(".color-picker") || controlEl.lastElementChild;
                const resetButton = controlEl.createEl("button", {
                  cls: "clickable-icon ui-tweaker-color-reset",
                  attr: { "aria-label": "Reset to default color" }
                });
                (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
                setCssProps(resetButton, { marginRight: "0.5rem" });
                resetButton.addEventListener("click", (e) => {
                  e.stopPropagation();
                  e.stopImmediatePropagation();
                  e.preventDefault();
                  void (async () => {
                    var _a2;
                    if (!settings.nativeExplorerButtonColors) {
                      settings.nativeExplorerButtonColors = {};
                    }
                    settings.nativeExplorerButtonColors[nativeButtonInfo.colorKey] = void 0;
                    await this.saveSettings();
                    (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                    this.render(container);
                  })();
                });
                if (colorPickerEl) {
                  controlEl.insertBefore(resetButton, colorPickerEl);
                }
              }, 0);
            }
            colorPicker.onChange((value) => {
              void (async () => {
                var _a2;
                if (!settings.nativeExplorerButtonColors) {
                  settings.nativeExplorerButtonColors = {};
                }
                const newColor = value === "#000000" ? void 0 : value;
                settings.nativeExplorerButtonColors[nativeButtonInfo.colorKey] = newColor;
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                const existingReset = controlEl.querySelector(".ui-tweaker-color-reset");
                if (newColor && !existingReset) {
                  const colorPickerEl = controlEl.querySelector(".color-picker") || controlEl.lastElementChild;
                  const resetButton = controlEl.createEl("button", {
                    cls: "clickable-icon ui-tweaker-color-reset",
                    attr: { "aria-label": "Reset to default color" }
                  });
                  (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
                  setCssProps(resetButton, { marginRight: "0.5rem" });
                  resetButton.addEventListener("click", (e) => {
                    e.stopPropagation();
                    e.stopImmediatePropagation();
                    e.preventDefault();
                    void (async () => {
                      var _a3;
                      if (!settings.nativeExplorerButtonColors) {
                        settings.nativeExplorerButtonColors = {};
                      }
                      settings.nativeExplorerButtonColors[nativeButtonInfo.colorKey] = void 0;
                      await this.saveSettings();
                      (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.applyNativeIconOverrides();
                      this.render(container);
                    })();
                  });
                  if (colorPickerEl) {
                    controlEl.insertBefore(resetButton, colorPickerEl);
                  }
                } else if (!newColor && existingReset) {
                  existingReset.remove();
                }
              })();
            });
          });
        });
        group.addSetting((setting) => {
          otherSettings.push(setting.settingEl);
          const hasIconOverride = iconOverride !== void 0;
          setting.setName("Icon override").setDesc("Override the default icon for this button").addButton((button) => {
            const currentIcon = iconOverride || "Default";
            button.setButtonText(currentIcon === "Default" ? "Set icon..." : currentIcon).onClick(() => {
              const modal = new IconPickerModal(this.app, (iconId) => {
                void (async () => {
                  var _a2;
                  if (!settings.nativeExplorerButtonIcons) {
                    settings.nativeExplorerButtonIcons = {};
                  }
                  if (iconId) {
                    settings.nativeExplorerButtonIcons[nativeButtonInfo.colorKey] = iconId;
                  } else {
                    settings.nativeExplorerButtonIcons[nativeButtonInfo.colorKey] = void 0;
                  }
                  await this.saveSettings();
                  (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                  this.render(container);
                })();
              });
              modal.open();
            });
            button.buttonEl.addEventListener("click", (e) => e.stopPropagation());
            if (hasIconOverride) {
              setTimeout(() => {
                const controlEl = setting.controlEl;
                const buttonEl = controlEl.querySelector("button") || controlEl.lastElementChild;
                const resetButton = controlEl.createEl("button", {
                  cls: "clickable-icon ui-tweaker-icon-override-reset",
                  attr: { "aria-label": "Reset icon override" }
                });
                (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
                setCssProps(resetButton, { marginRight: "0.5rem" });
                resetButton.addEventListener("click", (e) => {
                  e.stopPropagation();
                  e.stopImmediatePropagation();
                  e.preventDefault();
                  void (async () => {
                    var _a2;
                    if (!settings.nativeExplorerButtonIcons) {
                      settings.nativeExplorerButtonIcons = {};
                    }
                    settings.nativeExplorerButtonIcons[nativeButtonInfo.colorKey] = void 0;
                    await this.saveSettings();
                    (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.applyNativeIconOverrides();
                    this.render(container);
                  })();
                });
                if (buttonEl) {
                  controlEl.insertBefore(resetButton, buttonEl);
                } else {
                  controlEl.insertBefore(resetButton, controlEl.firstChild);
                }
              }, 0);
            }
          });
        });
      } else if (item.type === "custom" && pair) {
        group.addSetting((setting) => {
          otherSettings.push(setting.settingEl);
          setting.setName("Device mode").setDesc("Choose which devices this button appears on").addDropdown((dropdown) => {
            const appId = this.app.appId || "this-device";
            dropdown.addOption("any", "All devices").addOption("desktop", "Desktop only").addOption("mobile", "Mobile only").addOption(appId, "This device").setValue(pair.mode || "any").onChange((value) => {
              void (async () => {
                var _a2;
                pair.mode = value;
                item.mode = value;
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
                this.render(container);
              })();
            });
            dropdown.selectEl.addEventListener("click", (e) => e.stopPropagation());
          });
        });
        group.addSetting((setting) => {
          otherSettings.push(setting.settingEl);
          const hasColor = pair.color !== void 0;
          setting.setName("Custom color").setDesc("Set a custom color for this icon").addColorPicker((colorPicker) => {
            var _a2;
            const currentColor = (_a2 = pair.color) != null ? _a2 : "#000000";
            colorPicker.setValue(currentColor);
            const controlEl = setting.controlEl;
            controlEl.addEventListener("click", (e) => e.stopPropagation());
            setTimeout(() => {
              const colorInput = controlEl.querySelector('input[type="color"]');
              if (colorInput) {
                colorInput.addEventListener("click", (e) => e.stopPropagation());
              }
            }, 0);
            if (hasColor) {
              setTimeout(() => {
                const colorPickerEl = controlEl.querySelector(".color-picker") || controlEl.lastElementChild;
                const resetButton = controlEl.createEl("button", {
                  cls: "clickable-icon ui-tweaker-color-reset",
                  attr: { "aria-label": "Reset to default color" }
                });
                (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
                setCssProps(resetButton, { marginRight: "0.5rem" });
                resetButton.addEventListener("click", (e) => {
                  e.stopPropagation();
                  e.stopImmediatePropagation();
                  e.preventDefault();
                  void (async () => {
                    var _a3;
                    pair.color = void 0;
                    item.color = void 0;
                    await this.saveSettings();
                    (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
                    this.render(container);
                  })();
                });
                if (colorPickerEl) {
                  controlEl.insertBefore(resetButton, colorPickerEl);
                }
              }, 0);
            }
            colorPicker.onChange((value) => {
              const newColor = value === "#000000" ? void 0 : value;
              pair.color = newColor;
              item.color = newColor;
              const iconButton = container.querySelector(`[data-explorer-command-id="${pair.id}"]`);
              if (iconButton) {
                if (newColor && newColor !== "#000000") {
                  setCssProps(iconButton, { color: newColor });
                } else {
                  iconButton.style.removeProperty("color");
                }
              }
              const controlEl2 = setting.controlEl;
              const existingReset = controlEl2.querySelector(".ui-tweaker-color-reset");
              if (newColor && !existingReset) {
                const colorPickerEl = controlEl2.querySelector(".color-picker") || controlEl2.lastElementChild;
                const resetButton = controlEl2.createEl("button", {
                  cls: "clickable-icon ui-tweaker-color-reset",
                  attr: { "aria-label": "Reset to default color" }
                });
                (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
                setCssProps(resetButton, { marginRight: "0.5rem" });
                resetButton.addEventListener("click", (e) => {
                  e.stopPropagation();
                  e.stopImmediatePropagation();
                  e.preventDefault();
                  void (async () => {
                    var _a3;
                    pair.color = void 0;
                    item.color = void 0;
                    await this.saveSettings();
                    (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
                    this.render(container);
                  })();
                });
                if (colorPickerEl) {
                  controlEl2.insertBefore(resetButton, colorPickerEl);
                }
              } else if (!newColor && existingReset) {
                existingReset.remove();
              }
              void (async () => {
                var _a3;
                await this.saveSettings();
                (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
              })();
            });
          });
        });
        group.addSetting((setting) => {
          otherSettings.push(setting.settingEl);
          setting.setName("Toggle icon").setDesc("Icon to show when command is toggled on (leave empty to disable toggle). Commands with check callback work automatically. See readme for plugin developer compatibility notes.").setTooltip("For plugin developers: Commands with checkCallback work automatically. See https://github.com/davidvkimball/obsidian-ui-tweaker#toggle-icon-feature-compatibility for details.").addButton((button) => {
            const currentToggleIcon = pair.toggleIcon || "None";
            button.setButtonText(currentToggleIcon === "None" ? "Set toggle icon..." : currentToggleIcon).onClick(() => {
              const modal = new IconPickerModal(this.app, (iconId) => {
                void (async () => {
                  var _a2;
                  if (iconId) {
                    pair.toggleIcon = iconId;
                    item.toggleIcon = iconId;
                  } else {
                    pair.toggleIcon = void 0;
                    item.toggleIcon = void 0;
                  }
                  await this.saveSettings();
                  (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
                  this.render(container);
                })();
              });
              modal.open();
            });
            button.buttonEl.addEventListener("click", (e) => e.stopPropagation());
          });
        });
        group.addSetting((setting) => {
          otherSettings.push(setting.settingEl);
          setting.setName("Use active class instead of icon swap").setDesc("When toggled on, add is-active class instead of swapping icon (explorer only)").addToggle((toggle) => {
            var _a2;
            toggle.setValue((_a2 = pair.useActiveClass) != null ? _a2 : false);
            toggle.onChange((value) => {
              void (async () => {
                var _a3;
                pair.useActiveClass = value;
                item.useActiveClass = value;
                await this.saveSettings();
                (_a3 = this.plugin.explorerManager) == null ? void 0 : _a3.reorder();
                this.render(container);
              })();
            });
            toggle.toggleEl.addEventListener("click", (e) => e.stopPropagation());
          });
        });
      }
    }
    setTimeout(() => {
      var _a2;
      const savedExpanded = (_a2 = this.expandedStates.get(item.id)) != null ? _a2 : false;
      otherSettings.forEach((settingEl) => {
        setCssProps(settingEl, { display: savedExpanded ? "" : "none" });
      });
    }, 0);
  }
  renderCommandItem(container, pair, index) {
    const settings = this.getSettings();
    const group = createSettingsGroup(container, void 0, "ui-tweaker");
    const otherSettings = [];
    const displayName = pair.displayName || pair.name;
    group.addSetting((setting) => {
      var _a;
      setting.settingEl.addEventListener("click", (e) => {
        const target = e.target;
        const isChevronClick = target.closest(".ui-tweaker-collapse-icon") !== null;
        const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
        const isNameEdit = target.closest(".ui-tweaker-name-display") !== null || target.closest(".ui-tweaker-edit-icon") !== null || target.closest(".ui-tweaker-editable-name") !== null;
        if (!isChevronClick && !isExtraButton && !isNameEdit) {
          e.stopPropagation();
          e.stopImmediatePropagation();
          e.preventDefault();
          return false;
        }
      }, true);
      setting.settingEl.addEventListener("click", (e) => {
        const target = e.target;
        const isChevronClick = target.closest(".ui-tweaker-collapse-icon") !== null;
        const isExtraButton = target.closest(".extra-setting-button") !== null || target.closest(".clickable-icon.extra-setting-button") !== null;
        const isNameEdit = target.closest(".ui-tweaker-name-display") !== null || target.closest(".ui-tweaker-edit-icon") !== null || target.closest(".ui-tweaker-editable-name") !== null;
        if (!isChevronClick && !isExtraButton && !isNameEdit) {
          e.stopPropagation();
          e.stopImmediatePropagation();
          e.preventDefault();
          return false;
        }
      }, false);
      const nameEl = setting.nameEl;
      setCssProps(nameEl, { display: "flex", alignItems: "center", gap: "0.5rem", width: "100%" });
      const chevronContainer = document.createElement("div");
      chevronContainer.className = "ui-tweaker-collapse-icon";
      setCssProps(chevronContainer, {
        cursor: "default",
        background: "transparent",
        padding: "0",
        margin: "0",
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center"
      });
      nameEl.insertBefore(chevronContainer, nameEl.firstChild);
      let isExpanded = (_a = this.expandedStates.get(pair.id)) != null ? _a : false;
      (0, import_obsidian9.setIcon)(chevronContainer, isExpanded ? "chevrons-down-up" : "chevrons-up-down");
      chevronContainer.addEventListener("click", (e) => {
        e.stopPropagation();
        e.stopImmediatePropagation();
        e.preventDefault();
        isExpanded = !isExpanded;
        this.expandedStates.set(pair.id, isExpanded);
        (0, import_obsidian9.setIcon)(chevronContainer, isExpanded ? "chevrons-down-up" : "chevrons-up-down");
        otherSettings.forEach((settingEl) => {
          setCssProps(settingEl, { display: isExpanded ? "" : "none" });
        });
      });
      const nameContainer = nameEl.createDiv({ cls: "ui-tweaker-editable-name" });
      setCssProps(nameContainer, { display: "flex", alignItems: "center", gap: "0.5rem" });
      const createNameDisplay = (name) => {
        nameContainer.empty();
        const display = nameContainer.createSpan({
          text: name === displayName ? name : `${name} (${displayName})`,
          cls: "ui-tweaker-name-display"
        });
        const iconContainer = nameContainer.createDiv({ cls: "ui-tweaker-edit-icon" });
        setCssProps(iconContainer, { opacity: "0.6" });
        (0, import_obsidian9.setIcon)(iconContainer, "lucide-pencil-line");
        const startEdit = () => {
          const currentName = pair.name;
          nameContainer.empty();
          const nameInput = nameContainer.createEl("input", {
            type: "text",
            value: currentName
          });
          nameInput.addClass("mod-text-input");
          nameInput.focus();
          nameInput.select();
          const saveName = () => {
            var _a2;
            nameInput.removeEventListener("blur", saveName);
            let newName = nameInput.value.trim();
            if (!newName) {
              newName = currentName;
            }
            pair.name = newName;
            (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.updateButtonNames();
            void (async () => {
              await this.saveSettings();
              this.render(container);
            })();
          };
          nameInput.addEventListener("keydown", (e) => {
            if (e.key === "Enter") {
              e.preventDefault();
              saveName();
            } else if (e.key === "Escape") {
              e.preventDefault();
              createNameDisplay(currentName);
            }
          });
          nameInput.addEventListener("blur", saveName);
        };
        display.addEventListener("click", startEdit);
        iconContainer.addEventListener("click", startEdit);
        iconContainer.addEventListener("mouseenter", () => {
          setCssProps(iconContainer, { opacity: "1" });
        });
        iconContainer.addEventListener("mouseleave", () => {
          setCssProps(iconContainer, { opacity: "0.6" });
        });
      };
      createNameDisplay(pair.name);
      setting.setDesc("").addExtraButton((button) => {
        const iconEl = button.extraSettingsEl;
        (0, import_obsidian9.setIcon)(iconEl, pair.icon);
        iconEl.setAttribute("data-explorer-command-id", pair.id);
        if (pair.color && pair.color !== "#000000") {
          setCssProps(iconEl, { color: pair.color });
        } else {
          iconEl.style.removeProperty("color");
        }
        button.setTooltip("Change icon");
        button.onClick(() => {
          const modal = new IconPickerModal(this.app, (iconId) => {
            void (async () => {
              var _a2;
              if (iconId && iconId !== pair.icon) {
                pair.icon = iconId;
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
                this.render(container);
              }
            })();
          });
          modal.open();
        });
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("chevron-up");
        if (index > 0) {
          button.setTooltip("Move up");
          button.onClick(() => {
            const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
            const scrollPos = scrollContainer.scrollTop;
            void (async () => {
              var _a2;
              arrayMoveMutable3(settings.explorerCommands, index, index - 1);
              await this.saveSettings();
              (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
              this.render(container);
              requestAnimationFrame(() => {
                scrollContainer.scrollTop = scrollPos;
                setTimeout(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 50);
                }, 0);
              });
            })();
          });
        } else {
          button.setTooltip("Already at top");
          button.extraSettingsEl.addClass("ui-tweaker-disabled-button");
          setCssProps(button.extraSettingsEl, { pointerEvents: "none" });
        }
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("chevron-down");
        if (index < settings.explorerCommands.length - 1) {
          button.setTooltip("Move down");
          button.onClick(() => {
            const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
            const scrollPos = scrollContainer.scrollTop;
            void (async () => {
              var _a2;
              arrayMoveMutable3(settings.explorerCommands, index, index + 1);
              await this.saveSettings();
              (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
              this.render(container);
              requestAnimationFrame(() => {
                scrollContainer.scrollTop = scrollPos;
                setTimeout(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 50);
                }, 0);
              });
            })();
          });
        } else {
          button.setTooltip("Already at bottom");
          button.extraSettingsEl.addClass("ui-tweaker-disabled-button");
          setCssProps(button.extraSettingsEl, { pointerEvents: "none" });
        }
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      }).addExtraButton((button) => {
        button.setIcon("trash");
        button.setTooltip("Delete");
        button.extraSettingsEl.addClass("mod-warning");
        setCssProps(button.extraSettingsEl, { color: "var(--text-error)" });
        button.onClick(() => {
          void (async () => {
            var _a2;
            const idx = settings.explorerCommands.indexOf(pair);
            if (idx > -1) {
              settings.explorerCommands.splice(idx, 1);
              await this.saveSettings();
              (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
              this.render(container);
            }
          })();
        });
        button.extraSettingsEl.addEventListener("click", (e) => e.stopPropagation());
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      setting.setName("Device mode").setDesc("Choose which devices this button appears on").addDropdown((dropdown) => {
        const appId = this.app.appId || "this-device";
        dropdown.addOption("any", "All devices").addOption("desktop", "Desktop only").addOption("mobile", "Mobile only").addOption(appId, "This device").setValue(pair.mode || "any").onChange((value) => {
          void (async () => {
            var _a;
            pair.mode = value;
            await this.saveSettings();
            (_a = this.plugin.explorerManager) == null ? void 0 : _a.reorder();
            this.render(container);
          })();
        });
        dropdown.selectEl.addEventListener("click", (e) => e.stopPropagation());
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      const hasColor = pair.color !== void 0;
      setting.setName("Custom color").setDesc("Set a custom color for this icon").addColorPicker((colorPicker) => {
        var _a;
        const currentColor = (_a = pair.color) != null ? _a : "#000000";
        colorPicker.setValue(currentColor);
        const controlEl = setting.controlEl;
        controlEl.addEventListener("click", (e) => e.stopPropagation());
        setTimeout(() => {
          const colorInput = controlEl.querySelector('input[type="color"]');
          if (colorInput) {
            colorInput.addEventListener("click", (e) => e.stopPropagation());
          }
        }, 0);
        if (hasColor) {
          setTimeout(() => {
            const colorPickerEl = controlEl.querySelector(".color-picker") || controlEl.lastElementChild;
            const resetButton = controlEl.createEl("button", {
              cls: "clickable-icon ui-tweaker-color-reset",
              attr: { "aria-label": "Reset to default color" }
            });
            (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
            setCssProps(resetButton, { marginRight: "0.5rem" });
            resetButton.addEventListener("click", (e) => {
              e.stopPropagation();
              e.stopImmediatePropagation();
              e.preventDefault();
              void (async () => {
                var _a2;
                pair.color = void 0;
                const iconButton = container.querySelector(`[data-explorer-command-id="${pair.id}"]`);
                if (iconButton) {
                  iconButton.style.removeProperty("color");
                }
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
                this.render(container);
              })();
            });
            if (colorPickerEl) {
              controlEl.insertBefore(resetButton, colorPickerEl);
            } else {
              controlEl.insertBefore(resetButton, controlEl.firstChild);
            }
          }, 0);
        }
        colorPicker.onChange((value) => {
          const newColor = value === "#000000" ? void 0 : value;
          pair.color = newColor;
          const iconButton = container.querySelector(`[data-explorer-command-id="${pair.id}"]`);
          if (iconButton) {
            if (newColor && newColor !== "#000000") {
              setCssProps(iconButton, { color: newColor });
            } else {
              iconButton.style.removeProperty("color");
            }
          }
          const controlEl2 = setting.controlEl;
          const existingReset = controlEl2.querySelector(".ui-tweaker-color-reset");
          if (newColor && !existingReset) {
            const colorPickerEl = controlEl2.querySelector(".color-picker") || controlEl2.lastElementChild;
            const resetButton = controlEl2.createEl("button", {
              cls: "clickable-icon ui-tweaker-color-reset",
              attr: { "aria-label": "Reset to default color" }
            });
            (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
            setCssProps(resetButton, { marginRight: "0.5rem" });
            resetButton.addEventListener("click", (e) => {
              e.stopPropagation();
              e.stopImmediatePropagation();
              e.preventDefault();
              void (async () => {
                var _a2;
                pair.color = void 0;
                const iconButton2 = container.querySelector(`[data-explorer-command-id="${pair.id}"]`);
                if (iconButton2) {
                  iconButton2.style.removeProperty("color");
                }
                await this.saveSettings();
                (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
                this.render(container);
              })();
            });
            if (colorPickerEl) {
              controlEl2.insertBefore(resetButton, colorPickerEl);
            } else {
              controlEl2.insertBefore(resetButton, controlEl2.firstChild);
            }
          } else if (!newColor && existingReset) {
            existingReset.remove();
          }
          void (async () => {
            var _a2;
            await this.saveSettings();
            (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
          })();
        });
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      const hasToggleIcon = pair.toggleIcon !== void 0;
      setting.setName("Toggle icon").setDesc("Icon to show when command is toggled on (leave empty to disable toggle). Commands with check callback work automatically. See readme for plugin developer compatibility notes.").setTooltip("For plugin developers: Commands with checkCallback work automatically. See https://github.com/davidvkimball/obsidian-ui-tweaker#toggle-icon-feature-compatibility for details.").addButton((button) => {
        const currentToggleIcon = pair.toggleIcon || "None";
        button.setButtonText(currentToggleIcon === "None" ? "Set toggle icon..." : currentToggleIcon).onClick(() => {
          const modal = new IconPickerModal(this.app, (iconId) => {
            void (async () => {
              var _a;
              if (iconId) {
                pair.toggleIcon = iconId;
              } else {
                pair.toggleIcon = void 0;
              }
              await this.saveSettings();
              (_a = this.plugin.explorerManager) == null ? void 0 : _a.reorder();
              this.render(container);
            })();
          });
          modal.open();
        });
        button.buttonEl.addEventListener("click", (e) => e.stopPropagation());
        if (hasToggleIcon) {
          setTimeout(() => {
            const controlEl = setting.controlEl;
            const buttonEl = controlEl.querySelector("button") || controlEl.lastElementChild;
            const resetButton = controlEl.createEl("button", {
              cls: "clickable-icon ui-tweaker-toggle-icon-reset",
              attr: { "aria-label": "Reset toggle icon" }
            });
            (0, import_obsidian9.setIcon)(resetButton, "lucide-rotate-cw");
            setCssProps(resetButton, { marginRight: "0.5rem" });
            resetButton.addEventListener("click", (e) => {
              e.stopPropagation();
              e.stopImmediatePropagation();
              e.preventDefault();
              const scrollContainer = container.closest(".vertical-tab-content") || container.closest(".settings-content") || container.closest(".vertical-tab-content-container") || container;
              const scrollPos = scrollContainer.scrollTop;
              void (async () => {
                var _a;
                pair.toggleIcon = void 0;
                await this.saveSettings();
                (_a = this.plugin.explorerManager) == null ? void 0 : _a.reorder();
                this.render(container);
                requestAnimationFrame(() => {
                  scrollContainer.scrollTop = scrollPos;
                  setTimeout(() => {
                    scrollContainer.scrollTop = scrollPos;
                  }, 0);
                });
              })();
            });
            if (buttonEl) {
              controlEl.insertBefore(resetButton, buttonEl);
            } else {
              controlEl.insertBefore(resetButton, controlEl.firstChild);
            }
          }, 0);
        }
      });
    });
    group.addSetting((setting) => {
      otherSettings.push(setting.settingEl);
      setting.setName("Use active class instead of icon swap").setDesc("When toggled on, add is-active class instead of swapping icon (explorer only)").addToggle((toggle) => {
        var _a;
        toggle.setValue((_a = pair.useActiveClass) != null ? _a : false);
        toggle.onChange((value) => {
          void (async () => {
            var _a2;
            pair.useActiveClass = value;
            await this.saveSettings();
            (_a2 = this.plugin.explorerManager) == null ? void 0 : _a2.reorder();
            this.render(container);
          })();
        });
        toggle.toggleEl.addEventListener("click", (e) => e.stopPropagation());
      });
    });
    setTimeout(() => {
      var _a;
      const savedExpanded = (_a = this.expandedStates.get(pair.id)) != null ? _a : false;
      otherSettings.forEach((settingEl) => {
        setCssProps(settingEl, { display: savedExpanded ? "" : "none" });
      });
    }, 0);
  }
};

// src/ui/tabs/MobileTab.ts
var MobileTab = class extends TabRenderer {
  render(container) {
    container.empty();
    const mobileGroup = createSettingsGroup(container, void 0, "ui-tweaker");
    this.addToggleSetting(mobileGroup, 'Hide "Mobile chevrons" icon', 'Hide "Mobile chevrons" icon (long-press flair) in mobile navbar.', "mobileChevronsIcon");
    this.addToggleSetting(mobileGroup, 'Hide "Navigate back" button', 'Hide "Navigate back" button in mobile navbar.', "navigateBackButton");
    this.addToggleSetting(mobileGroup, 'Hide "Navigate forward" button', 'Hide "Navigate forward" button in mobile navbar.', "navigateForwardButton");
    this.addToggleSetting(mobileGroup, 'Hide "Quick switcher" button', 'Hide "Quick switcher" button in mobile navbar.', "quickSwitcherButton");
    this.addToggleSetting(mobileGroup, 'Hide "New tab" button', 'Hide "New tab" button in mobile navbar.', "mobileNewTabButton");
    this.addToggleSetting(mobileGroup, 'Hide "Open tabs" button', 'Hide "Open tabs" button in mobile navbar.', "openTabButton");
    this.addToggleSetting(mobileGroup, 'Hide "Ribbon menu" button', 'Hide "Ribbon menu" button in mobile navbar.', "ribbonMenuButton");
    this.addToggleSetting(mobileGroup, "Swap mobile new tab icon", "Replace the new tab plus icon with a home button icon in mobile navbar.", "swapMobileNewTabIcon");
    this.addToggleSetting(mobileGroup, "Hide title", "Hide the title in mobile view headers.", "hideMobileTitle");
    this.addToggleSetting(mobileGroup, "Hide sync icon", "Hide sync status icons in mobile interface.", "hideMobileSyncIcon");
    this.addToggleSetting(mobileGroup, "Hide status bar", "Hide the status bar on mobile devices.", "hideStatusBarMobile");
    this.renderSyncButtonReplacement(container, mobileGroup);
    const mobileNavGroup = createSettingsGroup(container, "Mobile navigation menu", "ui-tweaker");
    this.addPositionSetting(mobileNavGroup, '"Navigate back" button position', 'Select the position for the "Navigate back" button (default 1).', "navigateButtonPosition");
    this.addPositionSetting(mobileNavGroup, '"Navigate forward" button position', 'Select the position for the "Navigate forward" button (default 2).', "navigationButtonPosition");
    this.addPositionSetting(mobileNavGroup, '"Quick switcher" button position', 'Select the position for the "Quick switcher" button (default 3).', "quickSwitcherPosition");
    this.addPositionSetting(mobileNavGroup, '"New tab" button position', 'Select the position for the "New tab" button (default 4).', "newTabPosition");
    this.addPositionSetting(mobileNavGroup, '"Open tabs" button position', 'Select the position for the "Open tabs" button (default 5).', "openTabsPosition");
    this.addPositionSetting(mobileNavGroup, '"Ribbon menu" button position', 'Select the position for the "Ribbon menu" button (default 6).', "ribbonMenuPosition");
  }
  addToggleSetting(group, name, desc, key) {
    group.addSetting((setting) => {
      setting.setName(name).setDesc(desc).addToggle(
        (toggle) => toggle.setValue(Boolean(this.getSettings()[key])).onChange((value) => {
          this.getSettings()[key] = value;
          void this.saveSettings();
        })
      );
    });
  }
  addPositionSetting(group, name, desc, key) {
    group.addSetting((setting) => {
      setting.setName(name).setDesc(desc).addDropdown((dropdown) => {
        for (let i = 1; i <= 6; i++) {
          dropdown.addOption(String(i), String(i));
        }
        const currentValue = this.getSettings()[key];
        const stringValue = typeof currentValue === "string" ? currentValue : "1";
        dropdown.setValue(stringValue).onChange((value) => {
          this.getSettings()[key] = value;
          void this.saveSettings();
        });
      });
    });
  }
  renderSyncButtonReplacement(container, group) {
    const settings = this.getSettings();
    if (!settings.syncButtonReplacement) {
      settings.syncButtonReplacement = {
        enabled: false,
        commandId: "ui-tweaker:open-settings",
        iconId: "wrench"
      };
    }
    const dependentSettings = [];
    group.addSetting((setting) => {
      setting.setName("Replace sync button with custom action").setDesc("Replace the sync button in the mobile sidebar with a custom icon and command. This will hide the original sync button and show your custom button instead.").addToggle(
        (toggle) => toggle.setValue(settings.syncButtonReplacement.enabled).onChange((value) => {
          settings.syncButtonReplacement.enabled = value;
          dependentSettings.forEach((el) => {
            el.style.display = value ? "" : "none";
          });
          void this.saveSettings();
        })
      );
    });
    const getCommandName = (commandId) => {
      if (!commandId) return "Select command...";
      try {
        const commandRegistry = this.app.commands;
        if (commandRegistry && typeof commandRegistry.listCommands === "function") {
          const commands = commandRegistry.listCommands();
          const command = commands.find((cmd) => cmd && cmd.id === commandId);
          if (command == null ? void 0 : command.name) {
            return command.name;
          }
        }
      } catch (e) {
      }
      return "Select command...";
    };
    const getIconName = (iconId) => {
      if (!iconId) return "";
      return iconId.replace(/^lucide-/, "").split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
    };
    group.addSetting((setting) => {
      dependentSettings.push(setting.settingEl);
      setting.settingEl.style.display = settings.syncButtonReplacement.enabled ? "" : "none";
      setting.setName("Command").setDesc("Select the command to execute when the button is clicked").addButton(
        (button) => button.setButtonText(getCommandName(settings.syncButtonReplacement.commandId)).onClick(() => {
          const modal = new CommandPickerModal(this.app, (commandId) => {
            settings.syncButtonReplacement.commandId = commandId;
            button.setButtonText(getCommandName(commandId));
            void this.saveSettings();
          });
          modal.open();
        })
      );
    });
    group.addSetting((setting) => {
      dependentSettings.push(setting.settingEl);
      setting.settingEl.style.display = settings.syncButtonReplacement.enabled ? "" : "none";
      setting.setName("Icon").setDesc("Select the icon to display on the button").addButton(
        (button) => button.setButtonText(getIconName(settings.syncButtonReplacement.iconId) || "Select icon...").onClick(() => {
          const modal = new IconPickerModal(this.app, (iconId) => {
            settings.syncButtonReplacement.iconId = iconId;
            button.setButtonText(getIconName(iconId));
            void this.saveSettings();
          });
          modal.open();
        })
      );
    });
  }
};

// src/ui/tabs/PropertiesTab.ts
var import_obsidian10 = require("obsidian");
var PropertiesTab = class extends TabRenderer {
  render(container) {
    var _a;
    this.container = container;
    container.empty();
    const settings = this.getSettings();
    if (!settings.propertyIconItems) {
      settings.propertyIconItems = [];
    }
    const topGroup = createSettingsGroup(container, void 0, "ui-tweaker");
    topGroup.addSetting((setting) => {
      setting.setName("Minimal property icons").setDesc("Hide the default property type icon and only show your custom icon.").addToggle((toggle) => {
        toggle.setValue(settings.minimalPropertyIcons).onChange(async (value) => {
          var _a2;
          settings.minimalPropertyIcons = value;
          await this.saveSettings();
          (_a2 = this.plugin.propertiesManager) == null ? void 0 : _a2.refresh();
        });
      });
    });
    topGroup.addSetting((setting) => {
      setting.setName("Right-click menu").setDesc('Add "Change icon" and "Remove icon" to the property context menu.').addToggle((toggle) => {
        toggle.setValue(settings.showPropertyMenuActions).onChange(async (value) => {
          settings.showPropertyMenuActions = value;
          await this.saveSettings();
        });
      });
    });
    const propGroup = createSettingsGroup(container, "Property Icons", "ui-tweaker");
    const metadataProps = Object.keys(((_a = this.app.metadataTypeManager) == null ? void 0 : _a.properties) || {});
    const savedProps = settings.propertyIconItems.map((i) => i.id);
    const allProperties = Array.from(new Set([...metadataProps, ...savedProps].map((p) => p.toLowerCase()))).sort();
    if (allProperties.length === 0) {
      container.createDiv("ui-tweaker-empty-state", (el) => {
        el.createEl("p", { text: "No properties found in your vault yet." });
        el.createEl("p", { text: "Add some properties to your notes to see them here.", cls: "sub-text" });
      });
      return;
    }
    allProperties.forEach((propName) => {
      this.renderPropertySetting(propGroup, propName);
    });
  }
  renderPropertySetting(group, propName) {
    const settings = this.getSettings();
    const normalizedPropName = propName.toLowerCase();
    let item = settings.propertyIconItems.find((i) => i.id.toLowerCase() === normalizedPropName);
    group.addSetting((setting) => {
      setting.setName(propName);
      if ((item == null ? void 0 : item.icon) || (item == null ? void 0 : item.color)) {
        setting.addExtraButton((button) => {
          button.setIcon("lucide-rotate-ccw").setTooltip("Reset to default").onClick(async () => {
            var _a;
            settings.propertyIconItems = settings.propertyIconItems.filter((i) => i.id.toLowerCase() !== normalizedPropName);
            await this.saveSettings();
            if (this.container) this.render(this.container);
            (_a = this.plugin.propertiesManager) == null ? void 0 : _a.refresh();
          });
        });
      }
      setting.addExtraButton((button) => {
        button.extraSettingsEl.addClass("ui-tweaker-property-icon-btn");
        const iconEl = button.extraSettingsEl;
        if (item == null ? void 0 : item.icon) {
          (0, import_obsidian10.setIcon)(iconEl, item.icon);
          if (item.color) {
            setCssProps(iconEl, { color: item.color });
          }
        } else {
          (0, import_obsidian10.setIcon)(iconEl, "lucide-plus-circle");
          setCssProps(iconEl, { opacity: "0.4" });
        }
        button.setTooltip((item == null ? void 0 : item.icon) ? `Icon: ${item.icon} (click to change)` : "Add icon");
        button.onClick(() => {
          const modal = new IconPickerModal(this.app, async (iconId) => {
            var _a;
            let currentItem = settings.propertyIconItems.find((i) => i.id.toLowerCase() === normalizedPropName);
            if (!currentItem) {
              currentItem = { id: normalizedPropName };
              settings.propertyIconItems.push(currentItem);
            }
            if (iconId) {
              currentItem.icon = iconId;
            } else {
              currentItem.icon = void 0;
            }
            if (!currentItem.icon && !currentItem.color) {
              settings.propertyIconItems = settings.propertyIconItems.filter((i) => i.id.toLowerCase() !== normalizedPropName);
            }
            await this.saveSettings();
            if (this.container) this.render(this.container);
            (_a = this.plugin.propertiesManager) == null ? void 0 : _a.refresh();
          });
          modal.open();
        });
      });
      if (item == null ? void 0 : item.icon) {
        const colorPicker = new import_obsidian10.ColorComponent(setting.controlEl);
        colorPicker.setValue(item.color || "#000000");
        colorPicker.onChange(async (value) => {
          var _a;
          const currentItem = settings.propertyIconItems.find((i) => i.id.toLowerCase() === normalizedPropName);
          if (!currentItem) return;
          currentItem.color = value === "#000000" ? void 0 : value;
          await this.saveSettings();
          const iconBtn = setting.settingEl.querySelector(".ui-tweaker-property-icon-btn");
          if (iconBtn) {
            if (currentItem.color) {
              setCssProps(iconBtn, { color: currentItem.color });
            } else {
              iconBtn.style.removeProperty("color");
            }
          }
          (_a = this.plugin.propertiesManager) == null ? void 0 : _a.refresh();
        });
      }
    });
  }
};

// src/ui/SettingsTab.ts
var UITweakerSettingTab = class extends import_obsidian11.PluginSettingTab {
  constructor(app, plugin) {
    super(app, plugin);
    this.icon = "lucide-wrench";
    this.id = "ui-tweaker";
    this.tabContentMap = /* @__PURE__ */ new Map();
    this.tabButtons = /* @__PURE__ */ new Map();
    this.activeTabId = null;
    this.plugin = plugin;
  }
  display() {
    const { containerEl } = this;
    containerEl.empty();
    containerEl.addClass("ui-tweaker-settings-tab-root");
    this.tabContentMap.clear();
    this.tabButtons.clear();
    const tabs = [
      { id: "hider", name: "Hider", renderer: new HiderTab(this.app, this.plugin) },
      { id: "status-bar", name: "Status bar", renderer: new StatusBarTab(this.app, this.plugin) },
      { id: "tab-bar", name: "Tab bar", renderer: new TabBarTab(this.app, this.plugin) },
      { id: "explorer", name: "Explorer", renderer: new ExplorerTab(this.app, this.plugin) },
      { id: "properties", name: "Properties", renderer: new PropertiesTab(this.app, this.plugin) },
      { id: "mobile", name: "Mobile", renderer: new MobileTab(this.app, this.plugin) }
    ];
    const tabsWrapper = containerEl.createDiv("ui-tweaker-settings-tabs");
    const navEl = tabsWrapper.createDiv("ui-tweaker-settings-tabs-nav");
    navEl.setAttribute("role", "tablist");
    const contentWrapper = tabsWrapper.createDiv("ui-tweaker-settings-tabs-content");
    tabs.forEach((tab) => {
      const buttonComponent = new import_obsidian11.ButtonComponent(navEl);
      buttonComponent.setButtonText(tab.name);
      buttonComponent.removeCta();
      buttonComponent.buttonEl.addClass("ui-tweaker-settings-tab-button");
      buttonComponent.buttonEl.addClass("clickable-icon");
      buttonComponent.buttonEl.setAttribute("role", "tab");
      buttonComponent.buttonEl.setAttribute("aria-selected", "false");
      buttonComponent.onClick(() => {
        void this.activateTab(tab.id, tabs, contentWrapper);
      });
      this.tabButtons.set(tab.id, buttonComponent);
    });
    const initialTabId = this.activeTabId && tabs.some((t) => t.id === this.activeTabId) ? this.activeTabId : tabs[0].id;
    void this.activateTab(initialTabId, tabs, contentWrapper);
  }
  async activateTab(id, tabs, contentWrapper) {
    const definition = tabs.find((tab) => tab.id === id);
    if (!definition) return;
    if (!this.tabContentMap.has(id)) {
      const tabContainer = contentWrapper.createDiv("ui-tweaker-settings-tab");
      await definition.renderer.render(tabContainer);
      this.tabContentMap.set(id, tabContainer);
    }
    if (this.activeTabId && this.activeTabId !== id) {
      const prevContent = this.tabContentMap.get(this.activeTabId);
      if (prevContent) prevContent.removeClass("is-active");
      const prevButton = this.tabButtons.get(this.activeTabId);
      if (prevButton) {
        prevButton.buttonEl.removeClass("is-active");
        prevButton.buttonEl.setAttribute("aria-selected", "false");
        prevButton.removeCta();
      }
    }
    const newContent = this.tabContentMap.get(id);
    if (newContent) newContent.addClass("is-active");
    const newButton = this.tabButtons.get(id);
    if (newButton) {
      newButton.buttonEl.addClass("is-active");
      newButton.buttonEl.setAttribute("aria-selected", "true");
      newButton.setCta();
    }
    this.activeTabId = id;
    contentWrapper.scrollTop = 0;
  }
};

// src/manager/TabBarManager.ts
var import_obsidian13 = require("obsidian");

// src/utils/commandUtils.ts
var import_obsidian12 = require("obsidian");

// src/utils/command-logic.ts
function parseFileAndViewTypes(types) {
  const result = { fileTypes: [], viewTypes: [] };
  if (!types || !types.trim()) return result;
  const parts = types.split(",").map((p) => p.trim()).filter((p) => p);
  for (const part of parts) {
    const viewTypeMatch = part.match(/^\{\{(\w+)\}\}$/);
    if (viewTypeMatch) {
      result.viewTypes.push(viewTypeMatch[1].toLowerCase());
    } else {
      const ext = part.replace(/^\./, "").toLowerCase();
      if (ext) {
        result.fileTypes.push(ext);
      }
    }
  }
  return result;
}
var CommandToggleTracker = class {
  constructor() {
    this.toggleStates = /* @__PURE__ */ new Map();
    this.previousStates = /* @__PURE__ */ new Map();
    this.executionCounts = /* @__PURE__ */ new Map();
  }
  recordExecution(id) {
    const currentCount = this.executionCounts.get(id) || 0;
    this.executionCounts.set(id, currentCount + 1);
    this.toggleStates.set(id, (currentCount + 1) % 2 === 1);
  }
  getTrackedState(id) {
    var _a;
    return (_a = this.toggleStates.get(id)) != null ? _a : null;
  }
  getPreviousState(id) {
    var _a;
    return (_a = this.previousStates.get(id)) != null ? _a : null;
  }
  resetState(id) {
    this.toggleStates.delete(id);
    this.previousStates.delete(id);
    this.executionCounts.delete(id);
  }
  syncState(id, actualState) {
    const currentTrackedState = this.toggleStates.get(id);
    if (currentTrackedState !== void 0) {
      this.previousStates.set(id, currentTrackedState);
    }
    if (currentTrackedState !== actualState) {
      const currentCount = this.executionCounts.get(id) || 0;
      this.executionCounts.set(id, currentCount + 1);
      this.toggleStates.set(id, actualState);
      return true;
    }
    return false;
  }
  hasStateChanged(id, currentState) {
    const previousState = this.previousStates.get(id);
    return previousState !== void 0 && previousState !== currentState;
  }
};

// src/utils/commandUtils.ts
function isMarkdownView(leaf) {
  if (!(leaf == null ? void 0 : leaf.view)) return false;
  if (leaf.view instanceof import_obsidian12.MarkdownView) {
    const file = leaf.view.file;
    if (!file) return false;
    const ext = file.extension.toLowerCase();
    return ext === "md" || ext === "mdx";
  }
  return false;
}
function getFileExtension(leaf) {
  if (!(leaf == null ? void 0 : leaf.view)) return null;
  const view = leaf.view;
  const file = view.file;
  if (!file) return null;
  return file.extension.toLowerCase();
}
function getViewType(leaf) {
  if (!(leaf == null ? void 0 : leaf.view)) return null;
  const view = leaf.view;
  if (view.getViewType && typeof view.getViewType === "function") {
    return view.getViewType().toLowerCase();
  }
  if (leaf.view instanceof import_obsidian12.MarkdownView) {
    return "markdown";
  }
  const fileExt = getFileExtension(leaf);
  if (!fileExt) {
    return "empty";
  }
  return null;
}
function matchesFileTypeFilter(leaf, showOnFileTypes, hideOnFileTypes) {
  if (!(leaf == null ? void 0 : leaf.view)) return false;
  const showFilters = parseFileAndViewTypes(showOnFileTypes);
  const hideFilters = parseFileAndViewTypes(hideOnFileTypes);
  const fileExt = getFileExtension(leaf);
  const viewType = getViewType(leaf);
  if (hideFilters.fileTypes.length > 0 && fileExt && hideFilters.fileTypes.includes(fileExt)) {
    return false;
  }
  if (hideFilters.viewTypes.length > 0 && viewType && hideFilters.viewTypes.includes(viewType)) {
    return false;
  }
  if (showFilters.fileTypes.length > 0 || showFilters.viewTypes.length > 0) {
    const matchesFileType = fileExt ? showFilters.fileTypes.includes(fileExt) : false;
    const matchesViewType = viewType ? showFilters.viewTypes.includes(viewType) : false;
    return matchesFileType || matchesViewType;
  }
  return true;
}
function isModeActive(mode, plugin) {
  var _a;
  const app = plugin.app;
  const isMobile = (_a = app.isMobile) != null ? _a : false;
  const appId = app.appId;
  if (mode !== "any" && mode !== "desktop" && mode !== "mobile") {
    return mode === appId;
  }
  return mode === "any" || mode === "mobile" && isMobile || mode === "desktop" && !isMobile;
}
function getCommandFromId(id, plugin) {
  var _a, _b;
  const commands = plugin.app.commands;
  return (_b = (_a = commands == null ? void 0 : commands.commands) == null ? void 0 : _a[id]) != null ? _b : null;
}
var commandToggleTracker = new CommandToggleTracker();
function isCommandChecked(id, plugin) {
  var _a, _b, _c, _d, _e, _f;
  if (id === "theme:toggle-light-dark") {
    const isDark = document.body.classList.contains("theme-dark");
    commandToggleTracker.syncState(id, isDark);
    return isDark;
  }
  if (id === "editing-toolbar:hide-show-menu" || id === "hide-show-menu") {
    const plugins = plugin.app.plugins;
    const editingToolbarPlugin = (_a = plugins == null ? void 0 : plugins.plugins) == null ? void 0 : _a["editing-toolbar"];
    if (((_b = editingToolbarPlugin == null ? void 0 : editingToolbarPlugin.settings) == null ? void 0 : _b.cMenuVisibility) !== void 0) {
      const isVisible = editingToolbarPlugin.settings.cMenuVisibility;
      commandToggleTracker.syncState(id, isVisible);
      return isVisible;
    }
    return (_c = commandToggleTracker.getTrackedState(id)) != null ? _c : false;
  }
  const command = getCommandFromId(id, plugin);
  if (!command) {
    return (_d = commandToggleTracker.getTrackedState(id)) != null ? _d : false;
  }
  if (typeof command.checkCallback === "function") {
    try {
      const result = command.checkCallback(true);
      const isChecked = result === true;
      commandToggleTracker.syncState(id, isChecked);
      return isChecked;
    } catch (e) {
      return (_e = commandToggleTracker.getTrackedState(id)) != null ? _e : false;
    }
  }
  return (_f = commandToggleTracker.getTrackedState(id)) != null ? _f : false;
}
function recordCommandExecution(id) {
  commandToggleTracker.recordExecution(id);
}

// src/manager/TabBarManager.ts
var TabBarManager = class {
  constructor(plugin) {
    this.buttons = /* @__PURE__ */ new WeakMap();
    this.plugin = plugin;
    this.init();
  }
  get pairs() {
    return this.plugin.settings.tabBarCommands || [];
  }
  init() {
    this.plugin.register(() => {
      this.removeButtonsFromAllLeaves();
    });
    this.plugin.registerEvent(
      this.plugin.app.workspace.on("layout-change", () => {
        this.addButtonsToAllLeaves();
      })
    );
    this.plugin.app.workspace.onLayoutReady(
      () => setTimeout(() => this.addButtonsToAllLeaves(), 100)
    );
  }
  addPageHeaderButton(leaf, pair) {
    const { id } = pair;
    const name = pair.name;
    const { view } = leaf;
    if (!(view instanceof import_obsidian13.ItemView)) {
      return;
    }
    const buttons = this.buttonsFor(leaf, true);
    if (!buttons) {
      return;
    }
    if (buttons.has(id)) {
      const existingButton = buttons.get(id);
      if (existingButton) {
        existingButton.setAttribute("aria-label", name);
        existingButton.setAttribute("title", name);
        if (pair.color && pair.color !== "#000000") {
          setCssProps(existingButton, { color: pair.color });
        } else {
          existingButton.style.removeProperty("color");
        }
        this.updateButtonToggleState(existingButton, pair);
        return;
      }
    }
    if (!matchesFileTypeFilter(leaf, pair.showOnFileTypes, pair.hideOnFileTypes)) {
      return;
    }
    const initialIcon = this.getIconForToggleState(pair);
    const buttonIcon = view.addAction(initialIcon, name, () => {
      this.plugin.app.workspace.setActiveLeaf(leaf, { focus: true });
      const commands = this.plugin.app.commands;
      if (commands == null ? void 0 : commands.executeCommandById) {
        void commands.executeCommandById(id);
        setTimeout(() => {
          this.updateButtonToggleState(buttonIcon, pair);
          this.updateAllButtonsForCommand(id);
        }, 100);
      }
    });
    buttons.set(id, buttonIcon);
    buttonIcon.addClasses(["ui-tweaker-tab-bar-button", id]);
    if (pair.color && pair.color !== "#000000") {
      setCssProps(buttonIcon, { color: pair.color });
    }
    this.updateButtonToggleState(buttonIcon, pair);
    buttonIcon.addEventListener("contextmenu", (event) => {
      event.stopImmediatePropagation();
      new import_obsidian13.Menu().addItem((item) => {
        item.setTitle("Change icon").setIcon("lucide-image-plus").onClick(() => {
          const modal = new IconPickerModal(this.plugin.app, (iconId) => {
            if (iconId && iconId !== pair.icon) {
              pair.icon = iconId;
              void this.plugin.saveSettings();
              this.reorder();
            }
          });
          modal.open();
        });
      }).addItem((item) => {
        item.setTitle("Delete").setIcon("lucide-trash").onClick(() => {
          void this.removeCommand(pair);
        });
        const dom = item.dom;
        if (dom) {
          dom.classList.add("mod-warning");
          const iconEl = dom.querySelector(".menu-item-icon svg");
          if (iconEl) {
            setCssProps(iconEl, { color: "var(--text-error)" });
          }
        }
      }).showAtMouseEvent(event);
    });
  }
  buttonsFor(leaf, create = false) {
    if (!(leaf.view instanceof import_obsidian13.ItemView)) return;
    if (create && !this.buttons.has(leaf.view))
      this.buttons.set(leaf.view, /* @__PURE__ */ new Map());
    return this.buttons.get(leaf.view);
  }
  addButtonsToAllLeaves(refresh = false) {
    requestAnimationFrame(() => {
      this.plugin.app.workspace.iterateAllLeaves((leaf) => {
        this.addButtonsToLeaf(leaf, refresh);
      });
    });
  }
  removeButtonsFromAllLeaves() {
    requestAnimationFrame(
      () => this.plugin.app.workspace.iterateAllLeaves(
        (leaf) => this.removeButtonsFromLeaf(leaf)
      )
    );
  }
  addButtonsToLeaf(leaf, refresh = false) {
    var _a;
    if (!(leaf.view instanceof import_obsidian13.ItemView)) {
      return;
    }
    if (refresh) {
      this.removeButtonsFromLeaf(leaf);
    } else if ((_a = this.buttonsFor(leaf)) == null ? void 0 : _a.size) {
      return;
    }
    for (let i = this.pairs.length - 1; i >= 0; i--) {
      const pair = this.pairs[i];
      if (isModeActive(pair.mode, this.plugin)) {
        this.addPageHeaderButton(leaf, pair);
      }
    }
  }
  removeButtonsFromLeaf(leaf) {
    const buttons = this.buttonsFor(leaf);
    if (buttons) {
      for (const button of buttons.values()) button.detach();
      buttons == null ? void 0 : buttons.clear();
    }
  }
  reorder() {
    this.addButtonsToAllLeaves(true);
  }
  /**
   * Update button names/tooltips for all existing buttons
   */
  updateButtonNames() {
    this.plugin.app.workspace.iterateAllLeaves((leaf) => {
      if (!(leaf.view instanceof import_obsidian13.ItemView)) return;
      const buttons = this.buttonsFor(leaf);
      if (!buttons) return;
      for (const [id, button] of buttons.entries()) {
        const pair = this.pairs.find((p) => p.id === id);
        if (pair) {
          button.setAttribute("aria-label", pair.name);
          button.setAttribute("title", pair.name);
          if (pair.color && pair.color !== "#000000") {
            setCssProps(button, { color: pair.color });
          } else {
            button.style.removeProperty("color");
          }
          this.updateButtonToggleState(button, pair);
        }
      }
    });
  }
  /**
   * Get icon for current toggle state
   */
  getIconForToggleState(pair) {
    if (!pair.toggleIcon) {
      return pair.icon;
    }
    const isChecked = isCommandChecked(pair.id, this.plugin);
    return isChecked ? pair.toggleIcon : pair.icon;
  }
  /**
   * Update button toggle state (icon swap only for tab bar)
   */
  updateButtonToggleState(button, pair) {
    if (!pair.toggleIcon) {
      (0, import_obsidian13.setIcon)(button, pair.icon);
      return;
    }
    const isChecked = isCommandChecked(pair.id, this.plugin);
    (0, import_obsidian13.setIcon)(button, isChecked ? pair.toggleIcon : pair.icon);
  }
  /**
   * Update all buttons for a specific command ID across all leaves
   */
  updateAllButtonsForCommand(commandId) {
    const pair = this.pairs.find((p) => p.id === commandId);
    if (!pair) return;
    this.plugin.app.workspace.iterateAllLeaves((leaf) => {
      if (!(leaf.view instanceof import_obsidian13.ItemView)) return;
      const buttons = this.buttonsFor(leaf);
      if (!buttons) return;
      const button = buttons.get(commandId);
      if (button) {
        this.updateButtonToggleState(button, pair);
      }
    });
  }
  /**
   * Refresh toggle states for all buttons
   */
  refreshToggleStates() {
    this.plugin.app.workspace.iterateAllLeaves((leaf) => {
      if (!(leaf.view instanceof import_obsidian13.ItemView)) return;
      const buttons = this.buttonsFor(leaf);
      if (!buttons) return;
      for (const [id, button] of buttons.entries()) {
        const pair = this.pairs.find((p) => p.id === id);
        if (pair && pair.toggleIcon) {
          this.updateButtonToggleState(button, pair);
        }
      }
    });
  }
  async addCommand(pair) {
    if (!this.plugin.settings.tabBarCommands) {
      this.plugin.settings.tabBarCommands = [];
    }
    this.plugin.settings.tabBarCommands.push(pair);
    this.addButtonsToAllLeaves(true);
    await this.plugin.saveSettings();
  }
  async removeCommand(pair) {
    if (!this.plugin.settings.tabBarCommands) return;
    const index = this.plugin.settings.tabBarCommands.indexOf(pair);
    if (index > -1) {
      this.plugin.settings.tabBarCommands.splice(index, 1);
    }
    this.addButtonsToAllLeaves(true);
    await this.plugin.saveSettings();
  }
  async updateCommand(oldPair, newPair) {
    if (!this.plugin.settings.tabBarCommands) return;
    const index = this.plugin.settings.tabBarCommands.indexOf(oldPair);
    if (index > -1) {
      this.plugin.settings.tabBarCommands[index] = newPair;
      this.addButtonsToAllLeaves(true);
      await this.plugin.saveSettings();
    }
  }
};

// src/manager/StatusBarManager.ts
var import_obsidian14 = require("obsidian");
var StatusBarManager = class {
  constructor(plugin) {
    this.customActions = /* @__PURE__ */ new Map();
    this.container = null;
    this.isReordering = false;
    this.plugin = plugin;
    this.init();
  }
  // Flag to prevent observer from triggering during reorder
  get items() {
    return this.plugin.settings.statusBarItems || [];
  }
  init() {
    this.plugin.app.workspace.onLayoutReady(() => {
      var _a, _b;
      this.container = (_b = (_a = this.plugin.app.statusBar) == null ? void 0 : _a.containerEl) != null ? _b : null;
      if (!this.container) {
        return;
      }
      if (!this.plugin.settings.statusBarItems) {
        this.plugin.settings.statusBarItems = [];
      }
      this.consolidateSettingsAndElements();
      this.reorder();
      let observerTimeout = null;
      this.observer = new MutationObserver(() => {
        if (this.isReordering) {
          return;
        }
        if (observerTimeout) {
          clearTimeout(observerTimeout);
        }
        observerTimeout = setTimeout(() => {
          if (!this.isReordering) {
            this.consolidateSettingsAndElements();
            this.reorder();
          }
        }, 200);
      });
      this.observer.observe(this.container, { childList: true, subtree: false });
      this.plugin.register(() => {
        this.cleanup();
      });
    });
  }
  /**
   * Remove all buttons created by this manager from the DOM
   */
  cleanup() {
    if (this.observer) {
      this.observer.disconnect();
    }
    this.customActions.forEach((action) => action.remove());
    this.customActions.clear();
    if (this.container) {
      const managedButtons = this.container.querySelectorAll('[data-ui-tweaker-managed="true"]');
      managedButtons.forEach((btn) => btn.remove());
      const hiddenItems = this.container.querySelectorAll(".ui-tweaker-status-bar-hidden");
      hiddenItems.forEach((item) => item.removeClass("ui-tweaker-status-bar-hidden"));
    }
  }
  /**
   * Check if a class is a dynamic state class that should be filtered out
   * Dynamic state classes change based on plugin state (e.g., obsidian-git statusbar states)
   */
  isDynamicStateClass(className) {
    const dynamicPatterns = [
      /-statusbar-(idle|pull|push|commit|message|status|add|conflict|paused|failed-init)$/,
      // Common state classes that shouldn't be part of an element's identity
      /^(is-active|is-loading|is-hidden|is-collapsed|is-selected|is-flashing|mod-active|mod-loading)$/,
      // obsidian-git specific dynamic classes
      /^obsidian-git-statusbar-/
    ];
    return dynamicPatterns.some((pattern) => pattern.test(className));
  }
  /**
   * Generate a canonical name from an element's classes
   * Filters out dynamic state classes and uses only stable plugin identifiers
   */
  generateCanonicalName(element, allClasses) {
    var _a;
    const ignoredClasses = ["mod-clickable", "status-bar-item", "ui-tweaker-status-bar-item", "ui-tweaker-status-bar-hidden"];
    const pluginClass = allClasses.find(
      (cls) => cls.includes("plugin-") || cls.includes("obsidian-git") || cls.includes("-git") || cls.startsWith("git-") && cls !== "git-changes-status-bar"
    );
    if (pluginClass) {
      if (pluginClass.includes("obsidian-git") || pluginClass.startsWith("git-")) {
        if (allClasses.some((cls) => cls.startsWith("obsidian-git-statusbar-"))) return "plugin-obsidian-git-status";
        if (allClasses.includes("git-changes-status-bar")) return "plugin-obsidian-git-changes";
        const textContent = (_a = element.textContent) == null ? void 0 : _a.trim();
        const looksLikeBranch = textContent && textContent.length > 0 && /^[a-z0-9][a-z0-9._\-/]*$/i.test(textContent) && textContent.length < 30 && !textContent.includes(":") && !/^[0-9]/.test(textContent) && !element.getAttribute("data-ui-tweaker-managed");
        if (looksLikeBranch) return "plugin-obsidian-git-branch";
        return "plugin-obsidian-git";
      }
      const stableClasses2 = allClasses.filter(
        (cls) => !this.isDynamicStateClass(cls) && !ignoredClasses.includes(cls) && cls !== pluginClass
      );
      if (stableClasses2.length > 0) {
        return `${pluginClass}-${stableClasses2.join("-")}`;
      }
      return pluginClass;
    }
    const stableClasses = allClasses.filter(
      (cls) => !this.isDynamicStateClass(cls) && !ignoredClasses.includes(cls)
    );
    if (stableClasses.length > 0) {
      return stableClasses.join("-");
    }
    return "status-bar-item";
  }
  /**
   * Extract canonical name from a saved ID
   * Removes the index suffix and filters out dynamic state classes
   * This handles legacy IDs that might have been created with dynamic classes
   */
  getCanonicalNameFromId(id) {
    const parts = id.split(";");
    parts.pop();
    const fullName = parts.join(";");
    if (fullName.includes("obsidian-git-statusbar-") || fullName === "plugin-obsidian-git") {
      const savedItem = this.items.find((i) => i.id === id);
      if (savedItem && savedItem.name && /^[a-z0-9][a-z0-9._\-/]*$/i.test(savedItem.name) && savedItem.name.length < 30 && !savedItem.name.includes("plugin-")) {
        return "plugin-obsidian-git-branch";
      }
      return "plugin-obsidian-git-status";
    }
    const pluginMatch = fullName.match(/^(plugin-[a-z0-9-]+)/i);
    if (pluginMatch) {
      return pluginMatch[1];
    }
    const nameParts = fullName.split("-");
    const filteredParts = [];
    let skipNext = false;
    for (let i = 0; i < nameParts.length; i++) {
      if (skipNext) {
        skipNext = false;
        continue;
      }
      if (nameParts[i] === "statusbar" && i < nameParts.length - 1) {
        const nextPart = nameParts[i + 1];
        if (["idle", "pull", "push", "commit", "message", "status", "add", "conflict", "paused"].includes(nextPart)) {
          skipNext = true;
          continue;
        }
        if (nextPart === "failed" && i < nameParts.length - 2 && nameParts[i + 2] === "init") {
          i += 2;
          continue;
        }
      }
      if (this.isDynamicStateClass(nameParts[i])) {
        continue;
      }
      filteredParts.push(nameParts[i]);
    }
    return filteredParts.length > 0 ? filteredParts.join("-") : fullName;
  }
  /**
   * Consolidate settings and elements (EXACTLY like Status Bar Organizer)
   * Merges saved items with current DOM elements, preserves order and settings
   * Saves immediately to prevent duplicates
   */
  consolidateSettingsAndElements() {
    if (!this.container) return;
    const existingElements = Array.from(this.container.children).filter(
      (el) => {
        const element = el;
        if (element.classList.contains("ui-tweaker-status-bar-item")) return false;
        if (element.getAttribute("data-ui-tweaker-managed") === "true") {
          const id = element.getAttribute("data-ui-tweaker-status-bar-id");
          if (!id || !this.items.some((item) => item.id === id)) {
            return false;
          }
        }
        return true;
      }
    );
    const savedItems = this.items.filter((item) => item.type === "existing");
    const savedItemsMap = new Map(savedItems.map((item) => [item.id, item]));
    const pluginElementCount = {};
    const matchedSavedIds = /* @__PURE__ */ new Set();
    const newItems = [];
    existingElements.forEach((element) => {
      var _a, _b;
      let id = element.getAttribute("data-ui-tweaker-status-bar-id");
      let canonicalName;
      let index;
      if (id) {
        const parsed = this.parseElementId(id);
        canonicalName = parsed.name;
        index = parsed.index;
      } else {
        const allClasses = Array.from(element.classList);
        canonicalName = this.generateCanonicalName(element, allClasses);
        index = canonicalName in pluginElementCount ? pluginElementCount[canonicalName] + 1 : 1;
        id = `${canonicalName};${index}`;
        element.setAttribute("data-ui-tweaker-status-bar-id", id);
      }
      pluginElementCount[canonicalName] = Math.max(index, pluginElementCount[canonicalName] || 0);
      const savedItem = savedItemsMap.get(id);
      if (savedItem) {
        matchedSavedIds.add(id);
        let elementName = element.getAttribute("aria-label") || element.getAttribute("title") || ((_a = element.textContent) == null ? void 0 : _a.trim());
        const isBranch = canonicalName === "plugin-obsidian-git-branch";
        const hasGenericName = !savedItem.name || savedItem.name === canonicalName || savedItem.name === "Status bar item" || savedItem.name.startsWith("plugin-");
        if (elementName && (isBranch || hasGenericName)) {
          savedItem.name = elementName.substring(0, 50);
        }
      } else {
        let elementName = element.getAttribute("aria-label") || element.getAttribute("title") || ((_b = element.textContent) == null ? void 0 : _b.trim()) || canonicalName;
        newItems.push({
          id,
          name: elementName.substring(0, 50),
          type: "existing",
          hidden: false,
          mdOnly: false
        });
      }
    });
    if (newItems.length > 0) {
      this.plugin.settings.statusBarItems.push(...newItems);
      void this.plugin.saveSettings();
    }
  }
  /**
   * Helper to parse internal ID into name and index
   */
  parseElementId(id) {
    const parts = id.split(";");
    const indexStr = parts.pop();
    const index = parseInt(indexStr || "1", 10);
    const name = parts.join(";");
    return { name, index };
  }
  /**
   * Reorder and apply visibility to all status bar items (like Status Bar Organizer)
   * Handles sticky items (left/right) and items that aren't currently visible
   * 
   * Note: Items with the same sticky position maintain their relative order
   * (e.g., if 3 items are sticky-left, they appear in the order they're in settings)
   */
  reorder() {
    var _a;
    if (!this.container) return;
    this.isReordering = true;
    this.customActions.forEach((action) => action.remove());
    this.customActions.clear();
    const allExistingElements = Array.from(this.container.children).filter(
      (el) => el.classList.contains("status-bar-item") && !el.classList.contains("ui-tweaker-status-bar-item")
    );
    const leftSticky = [];
    const rightSticky = [];
    const regular = [];
    const activeLeaf = this.plugin.app.workspace.getMostRecentLeaf();
    for (const item of this.items) {
      if (item.hidden) {
        if (item.type === "existing") {
          const element = allExistingElements.find(
            (el) => el.getAttribute("data-ui-tweaker-status-bar-id") === item.id
          );
          if (element) {
            element.addClass("ui-tweaker-status-bar-hidden");
          }
        }
        continue;
      }
      if (item.mdOnly && !isMarkdownView(activeLeaf)) {
        if (item.type === "existing") {
          const element = allExistingElements.find(
            (el) => el.getAttribute("data-ui-tweaker-status-bar-id") === item.id
          );
          if (element) {
            element.addClass("ui-tweaker-status-bar-hidden");
          }
        }
        continue;
      }
      if (item.type === "custom") {
        const commands = this.plugin.app.commands;
        const command = (_a = commands == null ? void 0 : commands.commands) == null ? void 0 : _a[item.commandId || ""];
        const mode = item.mode || "any";
        if (command && isModeActive(mode, this.plugin)) {
          this.addCustomAction(item);
          const action = this.customActions.get(item);
          if (action) {
            if (item.sticky === "left") {
              leftSticky.push(action);
            } else if (item.sticky === "right") {
              rightSticky.push(action);
            } else {
              regular.push(action);
            }
          }
        }
      } else {
        const element = allExistingElements.find(
          (el) => el.getAttribute("data-ui-tweaker-status-bar-id") === item.id
        );
        if (element) {
          element.removeClass("ui-tweaker-status-bar-hidden");
          if (item.sticky === "left") {
            leftSticky.push(element);
          } else if (item.sticky === "right") {
            rightSticky.push(element);
          } else {
            regular.push(element);
          }
        }
      }
    }
    const orderedElements = [...leftSticky, ...regular, ...rightSticky];
    orderedElements.forEach((element) => {
      if (this.container && element.parentElement === this.container) {
        this.container.appendChild(element);
      }
    });
    orderedElements.forEach((element, index) => {
      setCssProps(element, { order: (index + 1).toString() });
    });
    setTimeout(() => {
      this.isReordering = false;
    }, 50);
  }
  /**
   * Add a custom command action to the status bar (like Commander)
   */
  addCustomAction(item) {
    if (!this.container || !item.commandId) return;
    if (this.customActions.has(item)) return;
    const btn = this.container.createDiv({
      cls: "ui-tweaker-status-bar-item status-bar-item mod-clickable",
      attr: {
        "aria-label": item.name,
        "data-tooltip-position": "top",
        "data-ui-tweaker-status-bar-id": item.id,
        "data-ui-tweaker-managed": "true"
      }
    });
    if (item.icon) {
      (0, import_obsidian14.setIcon)(btn, item.icon);
    }
    if (item.color && item.color !== "#000000") {
      setCssProps(btn, { color: item.color });
    }
    btn.onclick = () => {
      const commands = this.plugin.app.commands;
      if ((commands == null ? void 0 : commands.executeCommandById) && item.commandId) {
        void commands.executeCommandById(item.commandId);
      }
    };
    btn.addEventListener("contextmenu", (event) => {
      event.stopImmediatePropagation();
      new import_obsidian14.Menu().addItem((menuItem) => {
        menuItem.setTitle("Change icon").setIcon("lucide-image-plus").onClick(() => {
          const modal = new IconPickerModal(this.plugin.app, (iconId) => {
            if (iconId && iconId !== item.icon) {
              item.icon = iconId;
              void this.plugin.saveSettings();
              this.reorder();
            }
          });
          modal.open();
        });
      }).addItem((menuItem) => {
        menuItem.setTitle("Delete").setIcon("lucide-trash").onClick(() => {
          void this.removeItem(item);
        });
        const dom = menuItem.dom;
        if (dom) {
          dom.classList.add("mod-warning");
          const iconEl = dom.querySelector(".menu-item-icon svg");
          if (iconEl) {
            setCssProps(iconEl, { color: "var(--text-error)" });
          }
        }
      }).showAtMouseEvent(event);
    });
    this.customActions.set(item, btn);
  }
  /**
   * Add a new custom command item
   */
  async addCustomCommand(pair) {
    if (!this.plugin.settings.statusBarItems) {
      this.plugin.settings.statusBarItems = [];
    }
    const hasMarkdownFilter = pair.showOnFileTypes && (pair.showOnFileTypes.includes("md") || pair.showOnFileTypes.includes("mdx"));
    const mdOnly = hasMarkdownFilter ? true : false;
    const item = {
      id: `custom-${pair.id}`,
      name: pair.name,
      displayName: pair.displayName,
      icon: pair.icon,
      type: "custom",
      hidden: false,
      mdOnly,
      commandId: pair.id,
      color: pair.color,
      mode: pair.mode
    };
    this.plugin.settings.statusBarItems.push(item);
    this.reorder();
    await this.plugin.saveSettings();
  }
  /**
   * Remove an item
   */
  async removeItem(item) {
    if (!this.plugin.settings.statusBarItems) return;
    const index = this.plugin.settings.statusBarItems.indexOf(item);
    if (index > -1) {
      this.plugin.settings.statusBarItems.splice(index, 1);
    }
    this.reorder();
    await this.plugin.saveSettings();
  }
  /**
   * Update item visibility
   */
  async updateItemVisibility(item, hidden) {
    item.hidden = hidden;
    this.reorder();
    await this.plugin.saveSettings();
  }
  /**
   * Update item md/mdx-only setting
   */
  async updateItemMdOnly(item, mdOnly) {
    item.mdOnly = mdOnly;
    this.reorder();
    await this.plugin.saveSettings();
  }
  /**
   * Update button names/tooltips for all existing custom buttons
   */
  updateButtonNames() {
    this.customActions.forEach((button, item) => {
      button.setAttribute("aria-label", item.name);
      if (item.color && item.color !== "#000000") {
        setCssProps(button, { color: item.color });
      } else {
        button.style.removeProperty("color");
      }
    });
  }
};

// src/manager/ExplorerManager.ts
var import_obsidian15 = require("obsidian");
var ExplorerManager = class {
  // Flag to prevent observer from triggering during reorder
  constructor(plugin) {
    this.buttons = /* @__PURE__ */ new Map();
    this.observers = [];
    this.isReordering = false;
    this.plugin = plugin;
    this.init();
  }
  init() {
    this.plugin.app.workspace.onLayoutReady(() => {
      if (!this.plugin.settings.explorerButtonItems) {
        this.plugin.settings.explorerButtonItems = [];
      }
      this.migrateExplorerCommands();
      this.consolidateSettingsAndElements();
      this.plugin.registerEvent(
        this.plugin.app.workspace.on("layout-change", () => {
          this.consolidateSettingsAndElements();
          this.reorder();
          this.applyNativeIconOverrides();
        })
      );
      this.addButtonsToAllLeaves();
      this.reorder();
      setTimeout(() => {
        this.setupMutationObserver();
      }, 100);
      this.plugin.register(() => {
        this.cleanup();
      });
    });
  }
  /**
   * Remove all buttons created by this manager from the DOM
   */
  cleanup() {
    this.observers.forEach((observer) => observer.disconnect());
    this.observers = [];
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    explorers.forEach((leaf) => {
      var _a, _b;
      const navButtonsContainer = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
      if (navButtonsContainer) {
        const managedButtons = navButtonsContainer.querySelectorAll('[data-ui-tweaker-managed="true"]');
        managedButtons.forEach((btn) => btn.remove());
      }
    });
    this.buttons.clear();
  }
  addButtonsToAllLeaves() {
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    explorers.forEach((leaf) => {
      this.addButtonsToExplorer(leaf);
    });
  }
  addButtonsToExplorer(leaf) {
    this.reorder();
  }
  /**
   * Migrate existing explorerCommands to explorerButtonItems
   */
  migrateExplorerCommands() {
  }
  createOrUpdateExplorerButton(container, pair, leaf) {
    const existingButton = container.querySelector(`[data-explorer-command-id="${pair.id}"]`);
    if (existingButton) {
      existingButton.setAttribute("aria-label", pair.name);
      if (pair.color && pair.color !== "#000000") {
        existingButton.style.color = pair.color;
      } else {
        existingButton.style.removeProperty("color");
      }
      this.updateButtonToggleState(existingButton, pair);
      return existingButton;
    }
    if (!isModeActive(pair.mode, this.plugin)) {
      return null;
    }
    const button = createDiv({
      cls: "clickable-icon nav-action-button",
      attr: {
        "data-explorer-command-id": pair.id,
        "aria-label": pair.name,
        "aria-label-position": "top",
        "data-ui-tweaker-managed": "true"
      }
    });
    this.updateButtonToggleState(button, pair);
    button.onclick = () => {
      const commands = this.plugin.app.commands;
      if (commands == null ? void 0 : commands.executeCommandById) {
        void commands.executeCommandById(pair.id);
        setTimeout(() => {
          this.updateButtonToggleState(button, pair);
          this.updateAllButtonsForCommand(pair.id);
        }, 100);
      }
    };
    this.buttons.set(pair.id, button);
    button.addEventListener("contextmenu", (event) => {
      event.stopImmediatePropagation();
      new import_obsidian15.Menu().addItem((item) => {
        item.setTitle("Change icon").setIcon("lucide-image-plus").onClick(() => {
          const modal = new IconPickerModal(this.plugin.app, (iconId) => {
            if (iconId && iconId !== pair.icon) {
              pair.icon = iconId;
              void this.plugin.saveSettings();
              this.reorder();
            }
          });
          modal.open();
        });
      }).addItem((item) => {
        item.setTitle("Delete").setIcon("lucide-trash").onClick(() => {
          void this.removeCommand(pair);
        });
        const dom = item.dom;
        if (dom) {
          dom.classList.add("mod-warning");
          const iconEl = dom.querySelector(".menu-item-icon svg");
          if (iconEl) {
            setCssProps(iconEl, { color: "var(--text-error)" });
          }
        }
      }).showAtMouseEvent(event);
    });
    container.appendChild(button);
    return button;
  }
  /**
   * Generate canonical name from button element
   */
  generateCanonicalName(element, ariaLabel) {
    const nativeButtonMap = {
      "New note": "newNote",
      "New folder": "newFolder",
      "Change sort order": "sortOrder",
      "Auto-reveal current file": "autoReveal",
      "Collapse all": "collapseAll",
      "Expand all": "collapseAll"
      // Both map to same key
    };
    if (nativeButtonMap[ariaLabel]) {
      return `native-${nativeButtonMap[ariaLabel]}`;
    }
    const commandId = element.getAttribute("data-explorer-command-id");
    if (commandId) {
      return `custom-${commandId}`;
    }
    const allClasses = Array.from(element.classList);
    const ignoredClasses = ["clickable-icon", "nav-action-button"];
    const stableClasses = allClasses.filter((cls) => !ignoredClasses.includes(cls));
    const pluginClass = stableClasses.find(
      (cls) => cls.includes("plugin-") || cls.includes("commander") || cls.includes("explorer-focus")
    );
    if (pluginClass) {
      const sanitizedAriaLabel = ariaLabel.toLowerCase().replace(/[^a-z0-9]+/g, "-");
      return `external-${pluginClass}-${sanitizedAriaLabel}`;
    }
    const sanitized = ariaLabel.toLowerCase().replace(/[^a-z0-9]+/g, "-");
    return `external-${sanitized}`;
  }
  /**
   * Consolidate settings and elements - detect all buttons and merge with saved items
   */
  consolidateSettingsAndElements() {
    var _a, _b;
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    if (explorers.length === 0) return;
    const firstExplorer = explorers[0];
    const navButtonsContainer = (_b = (_a = firstExplorer.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
    if (!navButtonsContainer) return;
    const existingButtons = Array.from(navButtonsContainer.querySelectorAll(".nav-action-button")).filter(
      (element) => {
        if (element.getAttribute("data-ui-tweaker-managed") === "true") {
          const commandId = element.getAttribute("data-explorer-command-id");
          if (!commandId || !this.plugin.settings.explorerButtonItems.some((item) => item.commandId === commandId)) {
            return false;
          }
        }
        return true;
      }
    );
    const savedItems = this.plugin.settings.explorerButtonItems || [];
    const savedItemsMap = new Map(savedItems.map((item) => [item.id, item]));
    const matchedSavedIds = /* @__PURE__ */ new Set();
    const newItems = [];
    const elementCount = {};
    existingButtons.forEach((element) => {
      const ariaLabel = element.getAttribute("aria-label") || "";
      const commandId = element.getAttribute("data-explorer-command-id");
      const canonicalName = this.generateCanonicalName(element, ariaLabel);
      let id = canonicalName;
      if (canonicalName.startsWith("native-")) {
        id = canonicalName;
      } else if (canonicalName.startsWith("custom-")) {
        id = canonicalName;
      } else {
        const baseName = canonicalName;
        const count = baseName in elementCount ? elementCount[baseName] + 1 : 1;
        elementCount[baseName] = count;
        id = count > 1 ? `${baseName};${count}` : baseName;
      }
      if (savedItemsMap.has(id)) {
        matchedSavedIds.add(id);
        const savedItem = savedItemsMap.get(id);
        if (!savedItem.name || savedItem.name === id || savedItem.name.startsWith("external-")) {
          savedItem.name = ariaLabel || savedItem.name || id;
        }
        if (ariaLabel) {
          savedItem.ariaLabel = ariaLabel;
        }
      } else {
        let type;
        if (canonicalName.startsWith("native-")) {
          type = "native";
        } else if (canonicalName.startsWith("custom-")) {
          type = "custom";
        } else {
          type = "external";
        }
        const newItem = {
          id,
          name: ariaLabel || id,
          ariaLabel,
          type,
          commandId: commandId || void 0,
          hidden: false
        };
        if (type === "custom" && commandId) {
          const existingCommand = this.plugin.settings.explorerCommands.find((c) => c.id === commandId);
          if (existingCommand) {
            newItem.icon = existingCommand.icon;
            newItem.displayName = existingCommand.displayName;
            newItem.mode = existingCommand.mode;
            newItem.color = existingCommand.color;
            newItem.showOnFileTypes = existingCommand.showOnFileTypes;
            newItem.hideOnFileTypes = existingCommand.hideOnFileTypes;
            newItem.toggleIcon = existingCommand.toggleIcon;
            newItem.useActiveClass = existingCommand.useActiveClass;
          }
        }
        newItems.push(newItem);
      }
    });
    if (newItems.length > 0) {
      this.plugin.settings.explorerButtonItems.push(...newItems);
      void this.plugin.saveSettings();
    }
  }
  /**
   * Set up mutation observer to detect new external buttons
   */
  setupMutationObserver() {
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    if (explorers.length === 0) return;
    explorers.forEach((explorer) => {
      var _a, _b;
      const navButtonsContainer = (_b = (_a = explorer.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
      if (!navButtonsContainer) return;
      let observerTimeout = null;
      const observer = new MutationObserver((mutations) => {
        if (this.isReordering) return;
        const hasNewNodes = mutations.some(
          (mutation) => mutation.addedNodes.length > 0 && Array.from(mutation.addedNodes).some(
            (node) => node instanceof HTMLElement && node.classList.contains("nav-action-button") && !node.hasAttribute("data-explorer-command-id")
            // Only external buttons (not our custom ones)
          )
        );
        if (!hasNewNodes) return;
        if (observerTimeout) {
          clearTimeout(observerTimeout);
        }
        observerTimeout = setTimeout(() => {
          if (!this.isReordering) {
            this.consolidateSettingsAndElements();
            this.reorder();
          }
        }, 1e3);
      });
      observer.observe(navButtonsContainer, { childList: true, subtree: false });
      this.observers.push(observer);
    });
  }
  /**
   * Reorder buttons based on settings order
   */
  reorder() {
    this.isReordering = true;
    this.observers.forEach((observer) => observer.disconnect());
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    explorers.forEach((leaf) => {
      var _a, _b;
      const navButtonsContainer = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
      if (!navButtonsContainer) return;
      const allButtons = Array.from(navButtonsContainer.querySelectorAll(".nav-action-button"));
      const buttonMap = /* @__PURE__ */ new Map();
      allButtons.forEach((button) => {
        const ariaLabel = button.getAttribute("aria-label") || "";
        const canonicalName = this.generateCanonicalName(button, ariaLabel);
        if (canonicalName.startsWith("native-")) {
          buttonMap.set(canonicalName, button);
        } else if (canonicalName.startsWith("custom-")) {
          buttonMap.set(canonicalName, button);
        } else {
          const savedItems = this.plugin.settings.explorerButtonItems || [];
          const matchingItem = savedItems.find((item) => {
            if (item.id === canonicalName) return true;
            if (item.id.startsWith(canonicalName + ";")) return true;
            return item.ariaLabel === ariaLabel && item.type === "external";
          });
          if (matchingItem) {
            buttonMap.set(matchingItem.id, button);
          }
        }
      });
      const orderedButtons = [];
      const items = this.plugin.settings.explorerButtonItems || [];
      items.forEach((item) => {
        if (item.hidden) {
          const button = buttonMap.get(item.id);
          if (button) {
            button.classList.add("ui-tweaker-explorer-button-hidden");
            buttonMap.delete(item.id);
          }
        }
      });
      for (const item of items) {
        if (item.hidden) continue;
        const button = buttonMap.get(item.id);
        if (button) {
          button.classList.remove("ui-tweaker-explorer-button-hidden");
          orderedButtons.push(button);
          buttonMap.delete(item.id);
        } else if (item.type === "custom") {
          const commandPair = this.plugin.settings.explorerCommands.find((c) => c.id === item.commandId);
          if (commandPair) {
            const newButton = this.createOrUpdateExplorerButton(navButtonsContainer, commandPair, leaf);
            if (newButton) {
              orderedButtons.push(newButton);
            }
          }
        }
      }
      buttonMap.forEach((button, id) => {
        const item = items.find((i) => i.id === id);
        if (!item && !id.startsWith("native-") && !id.startsWith("external-")) {
          button.remove();
        }
      });
      orderedButtons.forEach((button) => {
        if (button.parentElement === navButtonsContainer) {
          navButtonsContainer.appendChild(button);
        }
      });
      this.applyNativeIconOverrides();
    });
    setTimeout(() => {
      this.isReordering = false;
      this.observers = [];
      this.setupMutationObserver();
    }, 200);
  }
  /**
   * Update button toggle state (icon or is-active class)
   */
  updateButtonToggleState(button, pair) {
    if (!pair.toggleIcon && !pair.useActiveClass) {
      button.empty();
      (0, import_obsidian15.setIcon)(button, pair.icon);
      button.classList.remove("is-active");
      if (pair.color && pair.color !== "#000000") {
        button.style.color = pair.color;
      } else {
        button.style.removeProperty("color");
      }
      return;
    }
    const isChecked = isCommandChecked(pair.id, this.plugin);
    if (pair.useActiveClass) {
      const currentIcon = button.querySelector(".svg-icon");
      const iconName = pair.icon.replace("lucide-", "");
      if (!currentIcon || !currentIcon.classList.contains(iconName)) {
        button.empty();
        (0, import_obsidian15.setIcon)(button, pair.icon);
      }
      if (isChecked) {
        button.classList.add("is-active");
      } else {
        button.classList.remove("is-active");
      }
    } else if (pair.toggleIcon) {
      button.empty();
      (0, import_obsidian15.setIcon)(button, isChecked ? pair.toggleIcon : pair.icon);
      button.classList.remove("is-active");
    }
    if (pair.color && pair.color !== "#000000") {
      button.style.color = pair.color;
    } else {
      button.style.removeProperty("color");
    }
  }
  /**
   * Update button names/tooltips for all existing buttons
   */
  updateButtonNames() {
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    explorers.forEach((leaf) => {
      var _a, _b;
      const navButtonsContainer = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
      if (!navButtonsContainer) return;
      for (const pair of this.plugin.settings.explorerCommands) {
        const button = navButtonsContainer.querySelector(`[data-explorer-command-id="${pair.id}"]`);
        if (button) {
          button.setAttribute("aria-label", pair.name);
          this.updateButtonToggleState(button, pair);
        }
      }
    });
  }
  /**
   * Update all buttons for a specific command ID across all explorers
   */
  updateAllButtonsForCommand(commandId) {
    const pair = this.plugin.settings.explorerCommands.find((p) => p.id === commandId);
    if (!pair) return;
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    explorers.forEach((leaf) => {
      var _a, _b;
      const navButtonsContainer = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
      if (!navButtonsContainer) return;
      const button = navButtonsContainer.querySelector(`[data-explorer-command-id="${commandId}"]`);
      if (button) {
        this.updateButtonToggleState(button, pair);
      }
    });
  }
  /**
   * Refresh toggle states for all buttons
   */
  refreshToggleStates() {
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    explorers.forEach((leaf) => {
      var _a, _b;
      const navButtonsContainer = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
      if (!navButtonsContainer) return;
      for (const pair of this.plugin.settings.explorerCommands) {
        const button = navButtonsContainer.querySelector(`[data-explorer-command-id="${pair.id}"]`);
        if (button && (pair.toggleIcon || pair.useActiveClass)) {
          this.updateButtonToggleState(button, pair);
        }
      }
    });
  }
  /**
   * Apply icon overrides to native explorer buttons
   */
  applyNativeIconOverrides() {
    const explorers = this.plugin.app.workspace.getLeavesOfType("file-explorer");
    const iconOverrides = this.plugin.settings.nativeExplorerButtonIcons;
    const defaultIcons = {
      "New note": { icon: "lucide-edit", key: "newNote" },
      "New folder": { icon: "lucide-folder-plus", key: "newFolder" },
      "Change sort order": { icon: "lucide-sort-asc", key: "sortOrder" },
      "Auto-reveal current file": { icon: "lucide-gallery-vertical", key: "autoReveal" },
      "Collapse all": { icon: "lucide-chevrons-up-down", key: "collapseAll" }
    };
    explorers.forEach((leaf) => {
      var _a, _b;
      const navButtonsContainer = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.querySelector("div.nav-buttons-container");
      if (!navButtonsContainer) return;
      const nativeButtons = navButtonsContainer.querySelectorAll(".nav-action-button:not([data-explorer-command-id])");
      nativeButtons.forEach((button) => {
        const ariaLabel = button.getAttribute("aria-label");
        if (!ariaLabel) return;
        const buttonInfo = defaultIcons[ariaLabel];
        if (!buttonInfo) return;
        const iconKey = buttonInfo.key;
        const iconOverride = iconOverrides == null ? void 0 : iconOverrides[iconKey];
        const colorOverrides = this.plugin.settings.nativeExplorerButtonColors;
        const color = colorOverrides == null ? void 0 : colorOverrides[iconKey];
        button.empty();
        if (iconOverride) {
          (0, import_obsidian15.setIcon)(button, iconOverride);
        } else {
          (0, import_obsidian15.setIcon)(button, buttonInfo.icon);
        }
        if (color) {
          button.style.color = color;
        } else {
          button.style.removeProperty("color");
        }
      });
    });
  }
  /**
   * Remove a command from explorer
   */
  async removeCommand(pair) {
    if (!this.plugin.settings.explorerCommands) return;
    const index = this.plugin.settings.explorerCommands.indexOf(pair);
    if (index > -1) {
      this.plugin.settings.explorerCommands.splice(index, 1);
    }
    this.reorder();
    await this.plugin.saveSettings();
  }
};

// src/utils/ButtonReplacer.ts
var import_obsidian16 = require("obsidian");
var ButtonReplacer = class {
  constructor(selector, replacementIcon, callback, options) {
    this.selector = selector;
    this.replacementIcon = replacementIcon;
    this.callback = callback;
    this.options = options;
    this.customButton = null;
    this.originalButton = null;
    this.observer = null;
    this.installTimeout = null;
  }
  install() {
    this.tryInstall();
    this.installTimeout = window.setTimeout(() => this.tryInstall(), 500);
    if (this.options.survivalObserver) {
      this.setupObserver();
    }
  }
  tryInstall() {
    var _a, _b, _c, _d;
    const parent = this.options.parentSelector ? document.querySelector(this.options.parentSelector) : document.body;
    if (!parent) return;
    let originalBtn = null;
    if (this.options.findButton) {
      originalBtn = this.options.findButton(parent);
    } else {
      originalBtn = parent.querySelector(this.selector);
    }
    if (!originalBtn) {
      if (this.options.fallbackParentSelector) {
        this.tryFallbackInstall();
      }
      return;
    }
    if (this.customButton && this.customButton.parentElement && document.body.contains(this.customButton)) {
      return;
    }
    this.removeCustomButton();
    const customButton = originalBtn.cloneNode(true);
    customButton.removeAttribute("aria-label");
    customButton.setAttribute(`data-${this.options.uniqueId}`, "true");
    if (this.options.cssClass) {
      this.options.cssClass.split(" ").filter(Boolean).forEach((cls) => customButton.classList.add(cls));
    }
    if (this.options.stripClasses) {
      this.options.stripClasses.forEach((cls) => customButton.classList.remove(cls));
    }
    customButton.onclick = null;
    const iconContainer = ((_a = customButton.querySelector("svg")) == null ? void 0 : _a.parentElement) || customButton;
    try {
      const oldSvg = customButton.querySelector("svg");
      if (oldSvg) oldSvg.remove();
      (0, import_obsidian16.setIcon)(iconContainer, this.replacementIcon);
    } catch (e) {
      console.error(`[UI Tweaker] Failed to set icon ${this.replacementIcon}:`, e);
      try {
        (0, import_obsidian16.setIcon)(iconContainer, "wrench");
      } catch (e2) {
      }
    }
    const handler = (evt) => {
      evt.preventDefault();
      evt.stopPropagation();
      this.callback();
    };
    customButton.addEventListener("click", handler, (_b = this.options.useCapture) != null ? _b : true);
    if (this.options.handleTouch) {
      customButton.addEventListener("touchstart", handler, (_c = this.options.useCapture) != null ? _c : true);
    }
    (_d = originalBtn.parentElement) == null ? void 0 : _d.insertBefore(customButton, originalBtn);
    this.customButton = customButton;
    this.originalButton = originalBtn;
    if (this.options.onAfterInstall) {
      this.options.onAfterInstall(customButton, originalBtn);
    }
  }
  tryFallbackInstall() {
    var _a, _b;
    const fallbackParent = document.querySelector(this.options.fallbackParentSelector);
    if (!fallbackParent) return;
    if (fallbackParent.querySelector(`[data-${this.options.uniqueId}]`)) return;
    const customButton = document.createElement("div");
    customButton.className = `clickable-icon ${this.options.cssClass}`;
    customButton.setAttribute(`data-${this.options.uniqueId}`, "true");
    try {
      (0, import_obsidian16.setIcon)(customButton, this.replacementIcon);
    } catch (e) {
      (0, import_obsidian16.setIcon)(customButton, "wrench");
    }
    const handler = (evt) => {
      evt.preventDefault();
      evt.stopPropagation();
      this.callback();
    };
    customButton.addEventListener("click", handler, (_a = this.options.useCapture) != null ? _a : true);
    if (this.options.handleTouch) {
      customButton.addEventListener("touchstart", handler, (_b = this.options.useCapture) != null ? _b : true);
    }
    if (this.options.fallbackInsertBehavior === "start") {
      fallbackParent.prepend(customButton);
    } else {
      fallbackParent.appendChild(customButton);
    }
    this.customButton = customButton;
    this.originalButton = null;
    if (this.options.onAfterInstall) {
      this.options.onAfterInstall(customButton, null);
    }
  }
  uninstall() {
    if (this.installTimeout) {
      clearTimeout(this.installTimeout);
      this.installTimeout = null;
    }
    if (this.observer) {
      this.observer.disconnect();
      this.observer = null;
    }
    if (this.options.onBeforeUninstall) {
      this.options.onBeforeUninstall(this.customButton);
    }
    this.removeCustomButton();
    this.originalButton = null;
  }
  removeCustomButton() {
    if (this.customButton) {
      if (this.customButton.parentElement) {
        this.customButton.remove();
      }
      this.customButton = null;
    }
    const strays = document.querySelectorAll(`.${this.options.cssClass}`);
    strays.forEach((el) => el.remove());
  }
  setupObserver() {
    if (this.observer) this.observer.disconnect();
    let mutationCount = 0;
    let timer = null;
    this.observer = new MutationObserver(() => {
      mutationCount++;
      if (timer) window.clearTimeout(timer);
      const delay = mutationCount < 20 ? 0 : 100;
      if (delay === 0) {
        this.tryInstall();
      } else {
        timer = window.setTimeout(() => this.tryInstall(), delay);
      }
    });
    this.observer.observe(document.body, {
      childList: true,
      subtree: true,
      attributes: true,
      attributeFilter: ["class", "src", "aria-label"]
    });
  }
};

// src/manager/PropertiesManager.ts
var import_obsidian17 = require("obsidian");
var PropertiesManager = class {
  constructor(plugin) {
    this.observers = [];
    this.plugin = plugin;
    this.init();
  }
  init() {
    this.plugin.app.workspace.onLayoutReady(() => {
      this.refresh();
      this.setupObservers();
      this.plugin.registerEvent(
        this.plugin.app.workspace.on("layout-change", () => {
          this.refresh();
          this.setupObservers();
        })
      );
      this.plugin.registerDomEvent(window, "contextmenu", (evt) => {
        if (!this.plugin.settings.showPropertyMenuActions) return;
        const target = evt.target;
        const propEl = target.closest(".metadata-property") || target.closest(".all-properties-container .tree-item");
        if (propEl) {
          this.handleContextMenu(evt, propEl);
        }
      }, { capture: true });
      this.plugin.register(() => {
        this.observers.forEach((o) => o.disconnect());
      });
    });
  }
  /**
   * Force a refresh of all property icons
   */
  refresh() {
    this.plugin.app.workspace.iterateAllLeaves((leaf) => {
      const type = leaf.getViewState().type;
      if (type === "markdown" || type === "all-properties" || type === "file-properties") {
        this.refreshLeaf(leaf);
      }
    });
  }
  refreshLeaf(leaf) {
    const type = leaf.getViewState().type;
    const container = leaf.view.containerEl;
    if (type === "all-properties") {
      this.refreshAllPropertiesInContainer(container);
    } else {
      this.refreshFilePropertiesInContainer(container);
    }
  }
  setupObservers() {
    this.observers.forEach((o) => o.disconnect());
    this.observers = [];
    this.plugin.app.workspace.iterateAllLeaves((leaf) => {
      const type = leaf.getViewState().type;
      if (type === "all-properties") {
        const container = leaf.view.containerEl.querySelector(".all-properties-container") || leaf.view.containerEl.querySelector(".view-content > div");
        if (container) {
          const observer = new MutationObserver(() => this.refreshAllPropertiesInContainer(leaf.view.containerEl));
          observer.observe(container, { childList: true, subtree: true });
          this.observers.push(observer);
        }
      } else if (type === "markdown" || type === "file-properties") {
        const container = leaf.view.containerEl.querySelector(".metadata-container") || leaf.view.containerEl.querySelector(".metadata-properties");
        if (container) {
          const observer = new MutationObserver(() => this.refreshFilePropertiesInContainer(leaf.view.containerEl));
          observer.observe(container, { childList: true, subtree: true });
          this.observers.push(observer);
        }
      }
    });
  }
  refreshAllPropertiesInContainer(container) {
    const items = container.querySelectorAll(".tree-item");
    items.forEach((item) => {
      var _a;
      const textEl = item.querySelector(".tree-item-inner-text");
      if (!textEl) return;
      const propName = (_a = textEl.textContent) == null ? void 0 : _a.trim();
      if (!propName) return;
      const setting = this.plugin.settings.propertyIconItems.find((i) => i.id.toLowerCase() === propName.toLowerCase());
      const iconEl = item.querySelector(".tree-item-icon");
      if (iconEl) {
        if (setting == null ? void 0 : setting.icon) {
          this.applyIcon(iconEl, setting.icon, setting.color);
          item.addClass("ui-tweaker-property-custom-icon");
        } else if (item.hasClass("ui-tweaker-property-custom-icon")) {
          this.restoreNativeIcon(iconEl, propName);
          item.removeClass("ui-tweaker-property-custom-icon");
          this.triggerViewUpdate(container);
        }
      }
    });
  }
  refreshFilePropertiesInContainer(container) {
    const props = container.querySelectorAll(".metadata-property");
    props.forEach((prop) => {
      var _a;
      const keyInput = prop.querySelector(".metadata-property-key-input");
      const keyText = prop.querySelector(".metadata-property-key-text");
      const propName = (_a = (keyInput == null ? void 0 : keyInput.value) || (keyText == null ? void 0 : keyText.textContent)) == null ? void 0 : _a.trim();
      if (!propName) return;
      const setting = this.plugin.settings.propertyIconItems.find((i) => i.id.toLowerCase() === propName.toLowerCase());
      const iconContainer = prop.querySelector(".metadata-property-icon");
      if (iconContainer) {
        if (setting == null ? void 0 : setting.icon) {
          this.applyIcon(iconContainer, setting.icon, setting.color);
          prop.addClass("ui-tweaker-property-custom-icon");
        } else if (prop.hasClass("ui-tweaker-property-custom-icon")) {
          this.restoreNativeIcon(iconContainer, propName);
          prop.removeClass("ui-tweaker-property-custom-icon");
          this.triggerViewUpdate(container);
        }
        if (this.plugin.settings.minimalPropertyIcons) {
          prop.addClass("ui-tweaker-property-minimal");
        } else {
          prop.removeClass("ui-tweaker-property-minimal");
        }
      }
    });
  }
  restoreNativeIcon(el, propName) {
    el.style.removeProperty("color");
    const savedIcon = el.getAttribute("data-ui-tweaker-native-icon");
    if (savedIcon) {
      (0, import_obsidian17.setIcon)(el, savedIcon);
      el.removeAttribute("data-ui-tweaker-native-icon");
      return;
    }
    const type = this.getPropertyType(propName);
    (0, import_obsidian17.setIcon)(el, this.getDefaultIcon(propName, type));
  }
  getPropertyType(propName) {
    const typeManager = this.plugin.app.metadataTypeManager;
    const lowerName = propName.toLowerCase();
    if (lowerName === "tags") return "multiselect";
    if (lowerName === "aliases") return "multiselect";
    if (typeManager) {
      if (typeManager.getAssignedType) {
        const type = typeManager.getAssignedType(propName);
        if (type) return type;
      }
      const props = typeManager.properties || {};
      const key = Object.keys(props).find((k) => k.toLowerCase() === lowerName);
      if (key) return props[key].type || "text";
      if (typeManager.types && typeManager.types[propName]) {
        return typeManager.types[propName];
      }
    }
    return "text";
  }
  getDefaultIcon(propName, type) {
    const lowerName = propName.toLowerCase();
    if (lowerName === "tags") return "tags";
    if (lowerName === "aliases") return "forward";
    switch (type) {
      case "text":
        return "text-align-start";
      case "number":
        return "binary";
      case "checkbox":
      case "boolean":
        return "square-check-big";
      case "date":
        return "calendar";
      case "datetime":
        return "clock";
      case "list":
        return "list";
      case "multiselect":
        return "list";
      default:
        return "text-align-start";
    }
  }
  handleContextMenu(evt, propEl) {
    var _a;
    const keyInput = propEl.querySelector(".metadata-property-key-input");
    const keyText = propEl.querySelector(".tree-item-inner-text") || propEl.querySelector(".metadata-property-key-text");
    const propName = (_a = (keyInput == null ? void 0 : keyInput.value) || (keyText == null ? void 0 : keyText.textContent)) == null ? void 0 : _a.trim();
    if (!propName) return;
    const normalizedPropName = propName.toLowerCase();
    const setting = this.plugin.settings.propertyIconItems.find((i) => i.id.toLowerCase() === normalizedPropName);
    this.plugin.menuManager.reset();
    this.plugin.menuManager.addItemAfter(["action.changeType", "action"], (item) => {
      item.setTitle((setting == null ? void 0 : setting.icon) ? "Change icon" : "Add icon").setIcon("lucide-image-plus").onClick(() => {
        const modal = new IconPickerModal(this.plugin.app, async (iconId) => {
          let currentItem = this.plugin.settings.propertyIconItems.find((i) => i.id.toLowerCase() === normalizedPropName);
          if (!currentItem) {
            currentItem = { id: normalizedPropName };
            this.plugin.settings.propertyIconItems.push(currentItem);
          }
          currentItem.icon = iconId || void 0;
          if (!currentItem.icon && !currentItem.color) {
            this.plugin.settings.propertyIconItems = this.plugin.settings.propertyIconItems.filter((i) => i.id.toLowerCase() !== normalizedPropName);
          }
          await this.plugin.saveSettings();
          this.refresh();
        });
        modal.open();
      });
    });
    if (setting == null ? void 0 : setting.icon) {
      this.plugin.menuManager.addItemAfter(["action.changeType", "action"], (item) => {
        item.setTitle("Remove icon").setIcon("lucide-trash").onClick(async () => {
          const currentItem = this.plugin.settings.propertyIconItems.find((i) => i.id.toLowerCase() === normalizedPropName);
          if (currentItem) {
            currentItem.icon = void 0;
            if (!currentItem.color) {
              this.plugin.settings.propertyIconItems = this.plugin.settings.propertyIconItems.filter((i) => i.id.toLowerCase() !== normalizedPropName);
            }
            await this.plugin.saveSettings();
            this.refresh();
          }
        });
      });
    }
  }
  triggerViewUpdate(container) {
    this.plugin.app.workspace.iterateAllLeaves((leaf) => {
      if (leaf.view.containerEl.contains(container)) {
        const view = leaf.view;
        if (leaf.getViewState().type === "all-properties" && view.refresh) {
          view.refresh();
        } else {
          const metadataEditor = view.metadataEditor;
          if (metadataEditor && metadataEditor.render) {
            metadataEditor.render();
          }
        }
      }
    });
  }
  applyIcon(el, icon, color) {
    if (!el.hasAttribute("data-ui-tweaker-native-icon")) {
      const svg = el.querySelector("svg");
      if (svg) {
        const lucideClass = Array.from(svg.classList).find((c) => c.startsWith("lucide-") && c !== "lucide-icon");
        if (lucideClass) {
          const nativeName = lucideClass.replace("lucide-", "");
          el.setAttribute("data-ui-tweaker-native-icon", nativeName);
        }
      }
    }
    const isLucide = icon.startsWith("lucide-") || icon.match(/^[a-z0-9-]+$/);
    if (isLucide) {
      const iconName = icon.startsWith("lucide-") ? icon.substring(7) : icon;
      const currentIcon = el.querySelector(`.lucide-${iconName}`);
      if (!currentIcon) {
        el.empty();
        (0, import_obsidian17.setIcon)(el, icon);
      }
    } else {
      if (el.textContent !== icon) {
        el.empty();
        el.textContent = icon;
        el.addClass("ui-tweaker-emoji-icon");
      }
    }
    if (color) {
      setCssProps(el, { color });
    } else {
      el.style.removeProperty("color");
    }
  }
};

// src/manager/MenuManager.ts
var import_obsidian18 = require("obsidian");
var MenuManager = class {
  constructor() {
    this.menu = null;
    this.queuedActions = [];
    const manager = this;
    this.showAtPositionOriginal = import_obsidian18.Menu.prototype.showAtPosition;
    this.showAtPositionProxy = new Proxy(import_obsidian18.Menu.prototype.showAtPosition, {
      apply(target, thisArg, argArray) {
        manager.menu = thisArg;
        if (manager.queuedActions.length > 0) {
          manager.runQueuedActions();
        }
        return target.apply(thisArg, argArray);
      }
    });
    import_obsidian18.Menu.prototype.showAtPosition = this.showAtPositionProxy;
  }
  /**
   * Run all actions in the queue on the current menu.
   */
  runQueuedActions() {
    const actions = this.queuedActions;
    this.queuedActions = [];
    for (const action of actions) {
      action();
    }
  }
  /**
   * Add a menu item to the current menu (or queue it if no menu is open).
   */
  addItem(callback) {
    if (this.menu) {
      this.menu.addItem(callback);
    } else {
      this.queuedActions.push(() => this.addItem(callback));
    }
    return this;
  }
  /**
   * Add a menu item after the given sections.
   * This uses private API to reorder sections.
   */
  addItemAfter(preSections, callback) {
    if (this.menu) {
      if (typeof preSections === "string") preSections = [preSections];
      this.menu.addItem((item) => {
        callback(item);
        const menu = this.menu;
        const itemInternal = item;
        if (!menu || !itemInternal.section) return;
        const sections = menu.sections || [];
        const currentSection = itemInternal.section;
        let index = 0;
        for (const preSection of preSections) {
          const pos = sections.lastIndexOf(preSection);
          if (pos !== -1) {
            index = pos + 1;
            break;
          }
        }
        const sectionIdx = sections.indexOf(currentSection);
        if (sectionIdx !== -1) {
          sections.splice(sectionIdx, 1);
          sections.splice(index, 0, currentSection);
        }
      });
    } else {
      this.queuedActions.push(() => this.addItemAfter(preSections, callback));
    }
    return this;
  }
  /**
   * Clear the queue.
   */
  flush() {
    this.queuedActions = [];
  }
  /**
   * Reset for a new cycle.
   */
  reset() {
    this.menu = null;
    this.flush();
  }
  /**
   * Restore original method.
   */
  unload() {
    if (import_obsidian18.Menu.prototype.showAtPosition === this.showAtPositionProxy) {
      import_obsidian18.Menu.prototype.showAtPosition = this.showAtPositionOriginal;
    }
  }
};

// src/main.ts
var UITweakerPlugin = class extends import_obsidian19.Plugin {
  constructor() {
    super(...arguments);
    // Track wrapped commands to avoid double-wrapping and allow cleanup
    this.wrappedCommands = /* @__PURE__ */ new Map();
  }
  get isMobile() {
    return import_obsidian19.Platform.isMobile || document.body.classList.contains("is-mobile") || document.body.classList.contains("emulate-mobile");
  }
  async onload() {
    await this.loadSettings();
    this.menuManager = new MenuManager();
    this.uiManager = new UIManager(this, this.settings);
    this.uiManager.applyStyles();
    if (!this.settings.tabBarCommands) {
      this.settings.tabBarCommands = [];
    }
    this.tabBarManager = new TabBarManager(this);
    if (!this.settings.statusBarItems) {
      this.settings.statusBarItems = [];
    }
    this.statusBarManager = new StatusBarManager(this);
    if (!this.settings.explorerCommands) {
      this.settings.explorerCommands = [];
    }
    this.explorerManager = new ExplorerManager(this);
    this.propertiesManager = new PropertiesManager(this);
    registerCommands({
      plugin: this,
      settings: this.settings,
      saveSettings: () => this.saveSettings(),
      refresh: () => this.refresh()
    });
    this.setupToggleStateRefresh();
    this.setupToggleStateObservers();
    this.settingTab = new UITweakerSettingTab(this.app, this);
    this.addSettingTab(this.settingTab);
    this.setupHelpButtonReplacement();
    if (this.isMobile) {
      this.setupSyncButtonReplacement();
    } else {
      document.body.classList.remove("ui-tweaker-hide-sync-button");
    }
  }
  onunload() {
    var _a, _b;
    if (this.uiManager) {
      this.uiManager.cleanup();
    }
    if (this.explorerManager) {
      this.explorerManager.cleanup();
    }
    if (this.statusBarManager) {
      this.statusBarManager.cleanup();
    }
    if (this.menuManager) {
      this.menuManager.unload();
    }
    (_a = this.helpButtonReplacer) == null ? void 0 : _a.uninstall();
    (_b = this.syncButtonReplacer) == null ? void 0 : _b.uninstall();
    for (const wrapper of this.wrappedCommands.values()) {
      wrapper.restore();
    }
    this.wrappedCommands.clear();
    document.body.classList.remove("ui-tweaker-hide-help-button");
    document.body.classList.remove("ui-tweaker-hide-sync-button");
  }
  async loadSettings() {
    try {
      const data = await this.loadData();
      if (!data || typeof data !== "object" || Array.isArray(data)) {
        this.settings = Object.assign({}, DEFAULT_SETTINGS);
        await this.saveSettings();
        return;
      }
      this.settings = Object.assign({}, DEFAULT_SETTINGS, data);
      if (!this.settings.helpButtonReplacement) {
        this.settings.helpButtonReplacement = {
          enabled: false,
          commandId: "",
          iconId: "settings-2"
        };
      } else {
        if (!this.settings.helpButtonReplacement.iconId) {
          this.settings.helpButtonReplacement.iconId = "wrench";
        }
      }
      if (!this.settings.syncButtonReplacement) {
        this.settings.syncButtonReplacement = {
          enabled: false,
          commandId: "",
          iconId: "wrench"
        };
      } else {
        if (!this.settings.syncButtonReplacement.iconId) {
          this.settings.syncButtonReplacement.iconId = "wrench";
        }
      }
      if (this.settings.tabBarCommands) {
        let needsSave = false;
        for (const pair of this.settings.tabBarCommands) {
          const pairWithOldProps = pair;
          if (pair.showOnFileTypes !== void 0 || pair.hideOnFileTypes !== void 0) {
            continue;
          }
          if (pairWithOldProps.mdOnly === true && !pair.showOnFileTypes) {
            pair.showOnFileTypes = "md,mdx";
            delete pairWithOldProps.mdOnly;
            needsSave = true;
          }
          if (pairWithOldProps.fileTypeFilter && !pair.showOnFileTypes && !pair.hideOnFileTypes) {
            const filter = pairWithOldProps.fileTypeFilter;
            const parts = filter.split(",").map((p) => p.trim()).filter((p) => p);
            const showTypes = [];
            const hideTypes = [];
            for (const part of parts) {
              if (part.startsWith("-")) {
                const ext = part.slice(1).replace(/^\./, "").toLowerCase();
                if (ext) hideTypes.push(ext);
              } else {
                const ext = part.replace(/^\./, "").toLowerCase();
                if (ext) showTypes.push(ext);
              }
            }
            if (showTypes.length > 0) {
              pair.showOnFileTypes = showTypes.join(",");
            }
            if (hideTypes.length > 0) {
              pair.hideOnFileTypes = hideTypes.join(",");
            }
            delete pairWithOldProps.fileTypeFilter;
            needsSave = true;
          }
        }
        if (needsSave) {
          await this.saveSettings();
        }
      }
      if (this.settings.propertyIconItems) {
        let needsSave = false;
        for (const item of this.settings.propertyIconItems) {
          if (item.id !== item.id.toLowerCase()) {
            item.id = item.id.toLowerCase();
            needsSave = true;
          }
        }
        if (needsSave) {
          await this.saveSettings();
        }
      }
    } catch (error) {
      console.error("[UI Tweaker] Failed to load settings:", error);
      this.settings = { ...DEFAULT_SETTINGS };
    }
  }
  async saveSettings() {
    await this.saveData(this.settings);
  }
  refresh() {
    var _a, _b;
    if (this.uiManager) {
      this.uiManager.updateSettings(this.settings);
    }
    (_a = this.explorerManager) == null ? void 0 : _a.applyNativeIconOverrides();
    this.setupHelpButtonReplacement();
    this.updateSyncButtonCSS();
    if (this.isMobile) {
      this.setupSyncButtonReplacement();
    } else {
      document.body.classList.remove("ui-tweaker-hide-sync-button");
      (_b = this.syncButtonReplacer) == null ? void 0 : _b.uninstall();
    }
  }
  setupHelpButtonReplacement() {
    var _a, _b;
    this.updateHelpButtonCSS();
    if (!((_a = this.settings.helpButtonReplacement) == null ? void 0 : _a.enabled)) {
      (_b = this.helpButtonReplacer) == null ? void 0 : _b.uninstall();
      this.helpButtonReplacer = void 0;
      return;
    }
    if (!this.helpButtonReplacer) {
      this.helpButtonReplacer = new ButtonReplacer(
        ".clickable-icon svg.help",
        this.settings.helpButtonReplacement.iconId || "settings-2",
        () => {
          var _a2;
          const commandId = (_a2 = this.settings.helpButtonReplacement) == null ? void 0 : _a2.commandId;
          if (commandId) {
            void (async () => {
              try {
                const commands = this.app.commands;
                if (commands == null ? void 0 : commands.executeCommandById) {
                  await commands.executeCommandById(commandId);
                } else {
                  throw new Error("Command execution not available");
                }
              } catch (e) {
                new import_obsidian19.Notice(`Failed to execute command: ${commandId}`);
              }
            })();
          }
        },
        {
          survivalObserver: true,
          parentSelector: ".workspace-drawer-vault-actions",
          uniqueId: "ui-tweaker-help-replacement",
          cssClass: "ui-tweaker-help-replacement",
          findButton: (parent) => {
            const selectors = [
              ".workspace-drawer-vault-actions .clickable-icon svg.help",
              ".workspace-sidedock-vault-profile .clickable-icon svg.help",
              ".workspace-drawer .clickable-icon svg.help",
              ".clickable-icon svg.help"
            ];
            for (const selector of selectors) {
              const svg = document.querySelector(selector);
              if (svg && svg.parentElement) return svg.parentElement;
            }
            return null;
          }
        }
      );
      this.helpButtonReplacer.install();
    } else {
      this.helpButtonReplacer.uninstall();
      this.helpButtonReplacer = void 0;
      this.setupHelpButtonReplacement();
    }
  }
  updateHelpButtonCSS() {
    var _a;
    const shouldHideHelpButton = this.settings.helpButton === "hide" || ((_a = this.settings.helpButtonReplacement) == null ? void 0 : _a.enabled);
    document.body.classList.toggle("ui-tweaker-hide-help-button", shouldHideHelpButton);
  }
  setupSyncButtonReplacement() {
    var _a, _b;
    this.updateSyncButtonCSS();
    if (!((_a = this.settings.syncButtonReplacement) == null ? void 0 : _a.enabled) || !this.isMobile) {
      (_b = this.syncButtonReplacer) == null ? void 0 : _b.uninstall();
      this.syncButtonReplacer = void 0;
      return;
    }
    if (!this.syncButtonReplacer) {
      this.syncButtonReplacer = new ButtonReplacer(
        ".sync-status-icon",
        this.settings.syncButtonReplacement.iconId || "wrench",
        () => {
          var _a2, _b2, _c, _d, _e;
          const commandId = (_a2 = this.settings.syncButtonReplacement) == null ? void 0 : _a2.commandId;
          if (commandId) {
            if (commandId === "open-settings" || commandId === "ui-tweaker:open-settings") {
              const settingApi = this.app.setting;
              if (settingApi) {
                (_b2 = settingApi.open) == null ? void 0 : _b2.call(settingApi);
                if (((_c = this.settingTab) == null ? void 0 : _c.id) && settingApi.openTabById) {
                  settingApi.openTabById(this.settingTab.id);
                }
              }
            } else {
              (_e = (_d = this.app.commands) == null ? void 0 : _d.executeCommandById) == null ? void 0 : _e.call(_d, commandId).catch((error) => {
                console.warn("[UI Tweaker] Error executing command:", error);
                new import_obsidian19.Notice(`Failed to execute command: ${commandId}`);
              });
            }
          }
        },
        {
          survivalObserver: true,
          parentSelector: ".workspace-drawer.mod-right",
          uniqueId: "ui-tweaker-sync-replacement",
          cssClass: "ui-tweaker-sync-replacement workspace-drawer-header-icon mod-raised",
          handleTouch: true,
          stripClasses: ["is-failed", "is-error", "is-warning", "mod-error", "mod-warning"],
          fallbackParentSelector: ".workspace-drawer.mod-right .workspace-drawer-header",
          fallbackInsertBehavior: "end",
          onAfterInstall: (custom, original) => {
            if (original) {
              setCssProps(original, { display: "none" });
              original.setAttribute("data-ui-tweaker-original-sync-hidden", "true");
            }
          },
          onBeforeUninstall: (custom) => {
            const originals = document.querySelectorAll("[data-ui-tweaker-original-sync-hidden]");
            originals.forEach((el) => {
              el.style.removeProperty("display");
              el.removeAttribute("data-ui-tweaker-original-sync-hidden");
            });
          },
          findButton: (parent) => {
            const drawerHeader = parent.querySelector(".workspace-drawer-header");
            if (!drawerHeader) return null;
            let syncButton = drawerHeader.querySelector(".sync-status-icon");
            if (!syncButton) {
              const clickableIcons = Array.from(drawerHeader.querySelectorAll(".clickable-icon"));
              for (const icon of clickableIcons) {
                if (icon.querySelector("svg.refresh-cw-off, svg.refresh-cw")) return icon;
              }
            }
            return syncButton;
          }
        }
      );
      this.syncButtonReplacer.install();
    } else {
      this.syncButtonReplacer.uninstall();
      this.syncButtonReplacer = void 0;
      this.setupSyncButtonReplacement();
    }
  }
  updateSyncButtonCSS() {
    var _a, _b;
    const shouldHide = ((_b = (_a = this.settings.syncButtonReplacement) == null ? void 0 : _a.enabled) != null ? _b : false) && this.isMobile;
    document.body.classList.toggle("ui-tweaker-hide-sync-button", shouldHide);
  }
  /**
   * Set up event-driven observers for toggle state changes
   * Wraps individual command callbacks to detect execution regardless of trigger method
   */
  setupToggleStateObservers() {
    const refreshToggleStates = () => {
      if (this.explorerManager) {
        this.explorerManager.refreshToggleStates();
      }
      if (this.tabBarManager) {
        this.tabBarManager.refreshToggleStates();
      }
    };
    const bodyObserver = new MutationObserver(refreshToggleStates);
    bodyObserver.observe(document.body, {
      attributes: true,
      attributeFilter: ["class"]
    });
    this.registerEvent(
      this.app.workspace.on("layout-change", refreshToggleStates)
    );
    const workspaceEl = document.querySelector(".workspace");
    if (workspaceEl) {
      const workspaceObserver = new MutationObserver(refreshToggleStates);
      workspaceObserver.observe(workspaceEl, {
        attributes: true,
        attributeFilter: ["class"]
      });
    }
  }
  /**
   * Wrap individual command callbacks to intercept execution
   * This catches commands triggered via hotkey, palette, or programmatically
   */
  setupToggleStateRefresh() {
    this.wrapToggleCommands();
  }
  /**
   * Wrap callbacks for all toggle commands
   * Call this when toggle commands are added/removed
   */
  wrapToggleCommands() {
    var _a, _b;
    const commandsObj = this.app.commands;
    if (!(commandsObj == null ? void 0 : commandsObj.commands)) return;
    const refreshToggleStates = () => {
      setTimeout(() => {
        if (this.explorerManager) {
          this.explorerManager.refreshToggleStates();
        }
        if (this.tabBarManager) {
          this.tabBarManager.refreshToggleStates();
        }
      }, 50);
    };
    const toggleCommandIds = /* @__PURE__ */ new Set();
    (_a = this.settings.explorerCommands) == null ? void 0 : _a.forEach((p) => {
      if (p.toggleIcon) toggleCommandIds.add(p.id);
    });
    (_b = this.settings.tabBarCommands) == null ? void 0 : _b.forEach((p) => {
      if (p.toggleIcon) toggleCommandIds.add(p.id);
    });
    for (const [id, wrapper] of this.wrappedCommands) {
      if (!toggleCommandIds.has(id)) {
        wrapper.restore();
        this.wrappedCommands.delete(id);
      }
    }
    for (const id of toggleCommandIds) {
      if (this.wrappedCommands.has(id)) continue;
      const command = commandsObj.commands[id];
      if (!command) continue;
      if (command.checkCallback) {
        const original = command.checkCallback;
        command.checkCallback = (checking) => {
          const result = original(checking);
          if (!checking) {
            recordCommandExecution(id);
            refreshToggleStates();
          }
          return result;
        };
        this.wrappedCommands.set(id, {
          restore: () => {
            command.checkCallback = original;
          }
        });
      } else if (command.callback) {
        const original = command.callback;
        command.callback = () => {
          const result = original();
          recordCommandExecution(id);
          refreshToggleStates();
          return result;
        };
        this.wrappedCommands.set(id, {
          restore: () => {
            command.callback = original;
          }
        });
      } else if (command.editorCheckCallback) {
        const original = command.editorCheckCallback;
        command.editorCheckCallback = (checking, editor, ctx) => {
          const result = original(checking, editor, ctx);
          if (!checking) {
            recordCommandExecution(id);
            refreshToggleStates();
          }
          return result;
        };
        this.wrappedCommands.set(id, {
          restore: () => {
            command.editorCheckCallback = original;
          }
        });
      } else if (command.editorCallback) {
        const original = command.editorCallback;
        command.editorCallback = (editor, ctx) => {
          const result = original(editor, ctx);
          recordCommandExecution(id);
          refreshToggleStates();
          return result;
        };
        this.wrappedCommands.set(id, {
          restore: () => {
            command.editorCallback = original;
          }
        });
      }
    }
  }
};
//# sourceMappingURL=data:application/json;base64,[encoded data, 654024 characters]
