(() => {
  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 __commonJS = (cb, mod) => function __require() {
    return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  };
  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
  ));

  // src/shared/version.js
  var require_version = __commonJS({
    "src/shared/version.js"(exports, module) {
      (function attachBuildIdentity(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaBuildIdentity = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createBuildIdentity() {
        "use strict";
        const EXTENSION_VERSION = "1.25.34";
        const injectedFingerprint = true ? "ad6e691b8aca11ed33afdee80003f6267e631e774c668aa45122b2917e7c7890" : "";
        const fingerprint = injectedFingerprint || `source:${EXTENSION_VERSION}`;
        return Object.freeze({ version: EXTENSION_VERSION, fingerprint });
      });
    }
  });

  // src/shared/browser-adapter.js
  var require_browser_adapter = __commonJS({
    "src/shared/browser-adapter.js"(exports, module) {
      (function attachBrowserAdapter(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaBrowserAdapter = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createBrowserAdapterModule() {
        "use strict";
        function detectBrowserName(userAgent = "") {
          return /\bEdg\//i.test(String(userAgent)) ? "edge" : "chrome";
        }
        function createBrowserAdapter({ root, userAgent } = {}) {
          const scope = root || (typeof globalThis === "object" ? globalThis : {});
          const raw = scope.browser || scope.chrome;
          if (!raw) throw new Error("A Chromium extension API is required");
          return Object.freeze({
            raw,
            runtime: raw.runtime,
            tabs: raw.tabs,
            storage: raw.storage,
            i18n: raw.i18n,
            name: detectBrowserName(userAgent ?? scope.navigator?.userAgent)
          });
        }
        return Object.freeze({ createBrowserAdapter, detectBrowserName });
      });
    }
  });

  // src/shared/i18n.js
  var require_i18n = __commonJS({
    "src/shared/i18n.js"(exports, module) {
      (function attachI18n(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaI18n = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createI18nModule() {
        "use strict";
        const LANGUAGE_STORAGE_KEY = "tfa_language";
        const MESSAGES = Object.freeze({
          zh: Object.freeze({
            "layout.split": "\u53CC\u680F\u603B\u89C8",
            "layout.browser": "\u771F\u5B9E\u9875\u7B7E",
            "layout.tasks": "\u4EFB\u52A1\u603B\u89C8",
            "pane.browser": "\u5F53\u524D\u6D4F\u89C8\u5668\u9875\u7B7E",
            "pane.tasks": "\u4EFB\u52A1\u5212\u5206\u603B\u89C8",
            "search.placeholder": "\u641C\u7D22\u6807\u9898\u3001\u7F51\u7AD9\u6216\u7F51\u5740",
            "filter.allWindows": "\u5168\u90E8\u7A97\u53E3",
            "filter.allDomains": "\u5168\u90E8\u9886\u57DF",
            "filter.allStatuses": "\u5168\u90E8\u72B6\u6001",
            "filter.all": "\u5168\u90E8",
            "locale.id": "zh-CN",
            "task.new": "\u65B0\u589E\u4EFB\u52A1",
            "task.inbox": "\u4E34\u65F6\u533A",
            "inbox.ignorePage": "\u5FFD\u7565\u6B64\u9875\u9762",
            "inbox.markShared": "\u6807\u8BB0\u4E3A\u5171\u4EAB\u5DE5\u5177 / \u591A\u4EFB\u52A1\u9875",
            "inbox.excludeSite": "\u4E0D\u8BB0\u5F55\u6B64\u7AD9\u70B9",
            "inbox.sharedBadge": "\u5171\u4EAB\u5DE5\u5177 / \u591A\u4EFB\u52A1\u9875",
            "toast.inboxPreferenceFailed": "\u4E34\u65F6\u533A\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
            "empty.tabs": "\u6CA1\u6709\u5339\u914D\u7684\u9875\u7B7E",
            "empty.tasks": "\u8FD8\u6CA1\u6709\u4EFB\u52A1",
            "workbench.layoutLabel": "\u4E3B\u89C6\u56FE\u5207\u6362",
            "workbench.layout.split": "\u53CC\u680F\u603B\u89C8",
            "workbench.layout.browser": "\u771F\u5B9E\u9875\u7B7E",
            "workbench.layout.tasks": "\u4EFB\u52A1\u603B\u89C8",
            "workbench.layout.recycle": "\u56DE\u6536\u7AD9",
            "workbench.searchPlaceholder": "\u641C\u7D22\u9875\u7B7E\u3001\u7F51\u5740\u6216\u4EFB\u52A1",
            "workbench.searchHint": "\u4EFB\u52A1\u6574\u7406\u4E0D\u4F1A\u91CD\u6392\u771F\u5B9E\u9875\u7B7E",
            "workbench.browserTitle": "\u5F53\u524D\u6D4F\u89C8\u5668\u9875\u7B7E",
            "workbench.taskTitle": "\u4EFB\u52A1\u5212\u5206\u603B\u89C8",
            "workbench.inboxTitle": "\u5F85\u5212\u5206\u7684\u9875\u7B7E",
            "workbench.inboxCandidates": "{count} \u4E2A\u5019\u9009",
            "workbench.inboxExpand": "\u5C55\u5F00\u5168\u90E8\u9875\u7B7E",
            "workbench.inboxCollapse": "\u6536\u8D77\u4E3A\u4E00\u884C",
            "inbox.observation.observing.label": "\u89C2\u5BDF\u4E2D",
            "inbox.observation.observing.reason": "\u7B49\u5F85\u66F4\u591A\u6D4F\u89C8\u884C\u4E3A",
            "inbox.observation.temporary_query.label": "\u4E34\u65F6\u67E5\u8BE2",
            "inbox.observation.temporary_query.reason": "\u53EF\u80FD\u662F\u4E00\u6B21\u77ED\u65F6\u67E5\u8BE2",
            "inbox.observation.possible_misclick.label": "\u7591\u4F3C\u8BEF\u70B9",
            "inbox.observation.possible_misclick.reason": "\u505C\u7559\u5F88\u77ED\uFF0C\u6682\u4E0D\u5F52\u7C7B",
            "inbox.observation.redirect_or_ad.label": "\u5E7F\u544A\u8DF3\u8F6C",
            "inbox.observation.redirect_or_ad.reason": "\u7591\u4F3C\u8DF3\u8F6C\u6216\u5E7F\u544A\u9875\u9762",
            "inbox.observation.intent_drift.label": "\u5A31\u4E50\u504F\u822A",
            "inbox.observation.intent_drift.reason": "\u53EF\u80FD\u504F\u79BB\u5F53\u524D\u6D4F\u89C8\u610F\u56FE",
            "workbench.statusFilter": "\u72B6\u6001\u7B5B\u9009",
            "workbench.domainFilter": "\u9886\u57DF\u7B5B\u9009",
            "workbench.taskSort": "\u4EFB\u52A1\u6392\u5E8F",
            "workbench.taskSort.manual": "\u624B\u52A8\u6392\u5E8F",
            "workbench.taskSort.recent": "\u6700\u8FD1\u66F4\u65B0",
            "workbench.taskSort.title": "\u540D\u79F0\u6392\u5E8F",
            "task.view.label": "\u4EFB\u52A1\u89C6\u56FE",
            "task.view.cards": "\u5361\u7247",
            "task.view.aggregate": "\u805A\u5408\u56FE",
            "task.view.fishbone": "\u9C7C\u9AA8\u56FE",
            "task.view.experimentalBadge": "\u5B9E\u9A8C\u89C6\u56FE",
            "task.view.experimentalHint": "\u57FA\u4E8E\u5F53\u524D\u771F\u5B9E\u4EFB\u52A1\u5173\u7CFB\u7684\u53EA\u8BFB\u57FA\u7840\u5C55\u793A\uFF0C\u5B8C\u6574\u5E03\u5C40\u4E0E\u6DF1\u5EA6\u4EA4\u4E92\u540E\u7EED\u5B8C\u5584\u3002",
            "task.view.empty": "\u6682\u65E0\u53EF\u89C6\u5316\u7684\u4EFB\u52A1\u6570\u636E",
            "task.view.emptyHint": "\u65B0\u5EFA\u6216\u5173\u8054\u4EFB\u52A1\u540E\uFF0C\u53EF\u8FD4\u56DE\u6B64\u89C6\u56FE\u67E5\u770B\u3002",
            "task.view.pageCount": "{count} \u4E2A\u5173\u8054\u9875\u9762",
            "task.view.noPages": "\u6682\u65E0\u5173\u8054\u9875\u9762",
            "task.view.aggregateAria": "\u4EFB\u52A1\u805A\u5408\u56FE",
            "task.view.fishboneAria": "\u4EFB\u52A1\u9C7C\u9AA8\u56FE",
            "workbench.allWindows": "\u5168\u90E8\u7A97\u53E3",
            "workbench.allStatuses": "\u5168\u90E8\u72B6\u6001",
            "workbench.allDomains": "\u5168\u90E8\u9886\u57DF",
            "workbench.window": "\u7A97\u53E3 {number}",
            "workbench.tabCount": "{count} \u4E2A\u9875\u7B7E",
            "workbench.untitledTabGroup": "\u672A\u547D\u540D\u6807\u7B7E\u7EC4",
            "workbench.ungroupedTabs": "\u672A\u5206\u7EC4\u9875\u7B7E",
            "workbench.collapseTabGroup": "\u6536\u8D77\u6807\u7B7E\u7EC4",
            "workbench.expandTabGroup": "\u5C55\u5F00\u6807\u7B7E\u7EC4",
            "workbench.tabGroupMore": "\u6807\u7B7E\u7EC4\u64CD\u4F5C",
            "workbench.activateGroupFirst": "\u5207\u6362\u5230\u9996\u4E2A\u9875\u7B7E",
            "workbench.editTabGroup": "\u4FEE\u6539\u540D\u79F0\u548C\u989C\u8272",
            "workbench.ungroupTabs": "\u79FB\u51FA\u6807\u7B7E\u7EC4",
            "workbench.closeTabGroup": "\u5173\u95ED\u6574\u4E2A\u6807\u7B7E\u7EC4",
            "workbench.ungroupTabGroup": "\u89E3\u7EC4",
            "workbench.closeAllTabGroup": "\u5168\u90E8\u5173\u95ED",
            "workbench.groupByDomain": "\u6309\u57DF\u540D\u5206\u7EC4",
            "workbench.ungroupAll": "\u5168\u90E8\u89E3\u7EC4",
            "privacy.title": "\u9690\u79C1\u4E0E\u6570\u636E",
            "privacy.description": "\u67E5\u770B\u672C\u5730\u884C\u4E3A\u8BB0\u5F55\u5E76\u7BA1\u7406\u4FDD\u7559\u6570\u636E",
            "settings.languageTitle": "\u754C\u9762\u8BED\u8A00",
            "settings.languageHint": "\u9ED8\u8BA4\u8DDF\u968F\u6D4F\u89C8\u5668\uFF0C\u4E5F\u53EF\u4EE5\u53EA\u4E3A TabFlow \u624B\u52A8\u5207\u6362\u3002",
            "settings.languageSystem": "\u8DDF\u968F\u6D4F\u89C8\u5668",
            "settings.languageChinese": "\u4E2D\u6587",
            "settings.languageEnglish": "English",
            "settings.languageSaveFailed": "\u8BED\u8A00\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
            "settings.title": "\u8BBE\u7F6E",
            "settings.navigation": "\u8BBE\u7F6E\u5BFC\u822A",
            "settings.activationTitle": "\u6C38\u4E45\u6FC0\u6D3B",
            "settings.activationDescription": "\u6FC0\u6D3B\u589E\u503C\u6743\u76CA\uFF0C\u514D\u8D39\u6838\u5FC3\u529F\u80FD\u59CB\u7EC8\u53EF\u7528",
            "settings.dockTitle": "\u7F51\u9875\u62D3\u5C55\u575E",
            "settings.dockDescription": "\u7BA1\u7406\u56FA\u5B9A\u7F51\u7AD9\u3001\u5916\u89C2\u4E0E\u4EA4\u4E92",
            "settings.close": "\u5173\u95ED\u8BBE\u7F6E",
            "privacy.localBehavior": "\u672C\u5730\u884C\u4E3A\u8BB0\u5F55",
            "privacy.localBehaviorHint": "\u53EA\u5728\u672C\u673A\u8BB0\u5F55\u6253\u5F00\u3001\u5207\u6362\u3001\u8DF3\u8F6C\u3001\u5173\u95ED\u7B49\u5FC5\u8981\u9875\u7B7E\u884C\u4E3A\uFF0C\u6700\u957F\u4FDD\u7559 30 \u5929\u3002\u6570\u636E\u4E0D\u4F1A\u4E0A\u4F20\uFF0C\u4E5F\u4E0D\u4F1A\u81EA\u52A8\u6539\u53D8\u4EFB\u52A1\u5173\u7CFB\u6216\u771F\u5B9E\u9875\u7B7E\u987A\u5E8F\u3002",
            "privacy.behaviorClearHint": "\u6E05\u9664\u884C\u4E3A\u8F68\u8FF9\u4E0D\u4F1A\u5220\u9664\u4EFB\u52A1\u3001\u4EFB\u52A1\u5173\u7CFB\u3001\u9875\u9762\u8D44\u6599\u6216\u5F53\u524D\u9875\u7B7E\u5B9E\u4F8B\u3002",
            "privacy.dataControls": "\u6570\u636E\u7BA1\u7406",
            "privacy.exportHint": "\u5B89\u5168\u5BFC\u51FA\u5305\u542B\u4EFB\u52A1\u3001\u9875\u9762\u3001\u4EFB\u52A1\u5173\u7CFB\u3001\u65B0\u9875\u5E38\u7528\u7F51\u7AD9\u548C\u7F51\u9875\u62D3\u5C55\u575E\uFF1B\u4E0D\u5305\u542B API \u5BC6\u94A5\u3001\u6FC0\u6D3B\u4FE1\u606F\u3001\u622A\u56FE\u3001Cookie\u3001\u884C\u4E3A\u539F\u59CB\u4E0A\u4E0B\u6587\u6216\u5B8C\u6574\u7F51\u5740\u53C2\u6570\u3002",
            "privacy.export": "\u5B89\u5168\u5BFC\u51FA",
            "privacy.clearBehavior": "\u6E05\u9664\u884C\u4E3A\u8F68\u8FF9",
            "privacy.clearAi": "\u6E05\u9664 AI \u6570\u636E",
            "privacy.clearAll": "\u6E05\u9664\u5168\u90E8\u672C\u5730\u6570\u636E",
            "privacy.clearing": "\u6B63\u5728\u6E05\u9664\u2026",
            "privacy.clearAiConfirm": "\u786E\u5B9A\u6E05\u9664\u672C\u673A AI \u8BBE\u7F6E\u3001API \u5BC6\u94A5\u548C\u8FD0\u884C\u72B6\u6001\u5417\uFF1F\u4EFB\u52A1\u548C\u4EFB\u52A1\u5173\u7CFB\u4E0D\u4F1A\u88AB\u5220\u9664\u3002",
            "privacy.clearBehaviorConfirm": "\u786E\u5B9A\u6E05\u9664\u672C\u673A\u6700\u8FD1 30 \u5929\u7684\u884C\u4E3A\u8F68\u8FF9\u5417\uFF1F\u4EFB\u52A1\u3001\u4EFB\u52A1\u5173\u7CFB\u3001\u9875\u9762\u8D44\u6599\u548C\u5F53\u524D\u9875\u7B7E\u4E0D\u4F1A\u88AB\u5220\u9664\u3002",
            "privacy.clearBehaviorSuccess": "\u5DF2\u6E05\u9664 {count} \u6761\u884C\u4E3A\u8BB0\u5F55\uFF1B\u4EFB\u52A1\u3001\u4EFB\u52A1\u5173\u7CFB\u548C\u5F53\u524D\u9875\u7B7E\u4FDD\u6301\u4E0D\u53D8\u3002",
            "privacy.clearBehaviorFailed": "\u6E05\u9664\u884C\u4E3A\u8F68\u8FF9\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
            "privacy.clearAllConfirm": "\u786E\u5B9A\u6E05\u9664\u5168\u90E8 TabFlow \u672C\u5730\u6570\u636E\u5417\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4EFB\u52A1\u3001\u4EFB\u52A1\u5173\u7CFB\u3001\u884C\u4E3A\u8BB0\u5F55\u548C AI \u5BC6\u94A5\uFF0C\u4E14\u65E0\u6CD5\u64A4\u9500\u3002",
            "privacy.clearAiSuccess": "\u5DF2\u6E05\u9664\u672C\u673A AI \u6570\u636E\uFF1B\u4EFB\u52A1\u548C\u4EFB\u52A1\u5173\u7CFB\u4FDD\u6301\u4E0D\u53D8\u3002",
            "privacy.clearAllSuccess": "\u5DF2\u6E05\u9664\u5168\u90E8 TabFlow \u672C\u5730\u6570\u636E\u3002",
            "privacy.exportSuccess": "\u5B89\u5168\u6570\u636E\u5DF2\u5BFC\u51FA\u3002",
            "privacy.actionFailed": "\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
            "privacy.exportFailed": "\u5BFC\u51FA\u6587\u4EF6\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
            "privacy.backup.title": "\u5907\u4EFD\u4E0E\u6062\u590D",
            "privacy.backup.hint": "\u9009\u62E9 TabFlow JSON \u5907\u4EFD\u540E\u4F1A\u5148\u663E\u793A\u5B89\u5168\u6458\u8981\uFF1B\u786E\u8BA4\u524D\u4E0D\u4F1A\u8986\u76D6\u4EFB\u4F55\u6570\u636E\u3002\u6587\u4EF6\u6700\u5927 5 MiB\u3002",
            "privacy.backup.reinstallWarning": "\u5347\u7EA7\u6216\u91CD\u65B0\u52A0\u8F7D\u4F1A\u4FDD\u7559\u672C\u5730\u6570\u636E\uFF1B\u5378\u8F7D\u6269\u5C55\u901A\u5E38\u4F1A\u5220\u9664\u672C\u5730\u6570\u636E\u3002\u5378\u8F7D\u524D\u8BF7\u5148\u5BFC\u51FA\u5B89\u5168\u5907\u4EFD\uFF0C\u91CD\u88C5\u540E\u518D\u4ECE\u5907\u4EFD\u6062\u590D\u3002",
            "privacy.backup.choose": "\u4ECE\u5907\u4EFD\u6062\u590D",
            "privacy.backup.reading": "\u6B63\u5728\u6821\u9A8C\u2026",
            "privacy.backup.previewTitle": "\u6062\u590D\u5185\u5BB9\u9884\u89C8",
            "privacy.backup.legacy": "\u65E7\u7248\u5907\u4EFD\uFF1A\u53EA\u4F1A\u8986\u76D6\u4EFB\u52A1\u3001\u9875\u9762\u548C\u4EFB\u52A1\u5173\u7CFB\uFF0C\u4E0D\u4F1A\u8986\u76D6\u65B0\u9875\u5E38\u7528\u7F51\u7AD9\u6216\u7F51\u9875\u62D3\u5C55\u575E\u3002",
            "privacy.backup.section.tasks": "\u4EFB\u52A1\u6570\u636E",
            "privacy.backup.section.newtab": "\u65B0\u9875\u5E38\u7528\u7F51\u7AD9",
            "privacy.backup.section.dock": "\u7F51\u9875\u62D3\u5C55\u575E",
            "privacy.backup.section.none": "\u65E0\u53EF\u6062\u590D\u6570\u636E",
            "privacy.backup.willOverwrite": "\u5C06\u8986\u76D6\uFF1A{sections}",
            "privacy.backup.count.tasks": "\u4EFB\u52A1",
            "privacy.backup.count.pages": "\u9875\u9762",
            "privacy.backup.count.relations": "\u4EFB\u52A1\u5173\u7CFB",
            "privacy.backup.count.categories": "\u65B0\u9875\u5206\u7C7B",
            "privacy.backup.count.sites": "\u5E38\u7528\u7F51\u7AD9",
            "privacy.backup.count.dockSites": "\u62D3\u5C55\u575E\u7F51\u7AD9",
            "privacy.backup.overwriteWarning": "\u6062\u590D\u4F1A\u8986\u76D6\u4E0A\u8FF0\u672C\u5730\u6570\u636E\uFF1B\u4E0D\u4F1A\u6062\u590D API \u5BC6\u94A5\u3001\u6FC0\u6D3B\u4FE1\u606F\u3001\u6D4F\u89C8\u8BB0\u5F55\u6216\u5F53\u524D\u771F\u5B9E\u9875\u7B7E\u3002",
            "privacy.backup.cancel": "\u53D6\u6D88",
            "privacy.backup.confirm": "\u8986\u76D6\u5E76\u6062\u590D",
            "privacy.backup.importing": "\u6B63\u5728\u6062\u590D\u2026",
            "privacy.backup.importSuccess": "\u6062\u590D\u5B8C\u6210\uFF0C\u4EFB\u52A1\u3001\u65B0\u9875\u548C\u7F51\u9875\u62D3\u5C55\u575E\u5DF2\u540C\u6B65\u3002",
            "privacy.backup.error.tooLarge": "\u5907\u4EFD\u6587\u4EF6\u4E0D\u80FD\u8D85\u8FC7 5 MiB\u3002",
            "privacy.backup.error.invalidJson": "\u6240\u9009\u6587\u4EF6\u4E0D\u662F\u6709\u6548\u7684 JSON \u5907\u4EFD\u3002",
            "privacy.backup.error.invalidFormat": "\u6240\u9009\u6587\u4EF6\u4E0D\u662F\u53D7\u652F\u6301\u7684 TabFlow \u5907\u4EFD\u3002",
            "privacy.backup.error.unsupportedVersion": "\u8BE5\u5907\u4EFD\u7248\u672C\u6682\u4E0D\u53D7\u652F\u6301\uFF0C\u8BF7\u5347\u7EA7 TabFlow \u540E\u91CD\u8BD5\u3002",
            "privacy.backup.error.sensitiveData": "\u4E3A\u4FDD\u62A4\u9690\u79C1\uFF0C\u8BE5\u6587\u4EF6\u5305\u542B\u4E0D\u5141\u8BB8\u6062\u590D\u7684\u654F\u611F\u6570\u636E\u3002",
            "privacy.backup.error.unknownField": "\u5907\u4EFD\u5305\u542B\u5F53\u524D\u7248\u672C\u4E0D\u652F\u6301\u7684\u6570\u636E\u5B57\u6BB5\u3002",
            "privacy.backup.error.invalidContent": "\u5907\u4EFD\u5185\u5BB9\u635F\u574F\u6216\u4E0D\u7B26\u5408\u5F53\u524D\u683C\u5F0F\u3002",
            "privacy.backup.error.duplicate": "\u5907\u4EFD\u4E2D\u5B58\u5728\u91CD\u590D\u8BB0\u5F55\uFF0C\u65E0\u6CD5\u5B89\u5168\u6062\u590D\u3002",
            "privacy.backup.error.brokenReference": "\u5907\u4EFD\u4E2D\u7684\u4EFB\u52A1\u5173\u7CFB\u5F15\u7528\u7F3A\u5931\uFF0C\u65E0\u6CD5\u5B89\u5168\u6062\u590D\u3002",
            "privacy.backup.error.primaryConflict": "\u5907\u4EFD\u4E2D\u540C\u4E00\u9875\u9762\u5B58\u5728\u591A\u4E2A\u4E3B\u8981\u4EFB\u52A1\uFF0C\u65E0\u6CD5\u5B89\u5168\u6062\u590D\u3002",
            "privacy.backup.error.sectionUnavailable": "\u5F53\u524D\u7248\u672C\u65E0\u6CD5\u6062\u590D\u8BE5\u6587\u4EF6\u5305\u542B\u7684\u90E8\u5206\u6570\u636E\uFF1B\u5C1A\u672A\u8FDB\u884C\u4EFB\u4F55\u66F4\u6539\u3002",
            "privacy.backup.error.confirmationRequired": "\u8BF7\u5148\u660E\u786E\u786E\u8BA4\u8986\u76D6\u672C\u5730\u6570\u636E\u3002",
            "privacy.backup.error.rolledBack": "\u6062\u590D\u5931\u8D25\uFF0C\u539F\u6709\u6570\u636E\u5DF2\u6062\u590D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
            "privacy.backup.error.partialRollback": "\u6062\u590D\u5931\u8D25\uFF0C\u90E8\u5206\u539F\u6709\u6570\u636E\u53EF\u80FD\u672A\u80FD\u8FD8\u539F\u3002\u8BF7\u505C\u6B62\u7F16\u8F91\u3001\u4FDD\u7559\u5907\u4EFD\u5E76\u91CD\u65B0\u52A0\u8F7D\u540E\u6838\u5BF9\u3002",
            "privacy.backup.error.inProgress": "\u53E6\u4E00\u9879\u6062\u590D\u6B63\u5728\u8FDB\u884C\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u91CD\u8BD5\u3002",
            "privacy.backup.error.previewRequired": "\u6062\u590D\u9884\u89C8\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5907\u4EFD\u6587\u4EF6\u5E76\u518D\u6B21\u786E\u8BA4\u3002",
            "privacy.backup.error.reconcileFailed": "\u6570\u636E\u5DF2\u5199\u5165\uFF0C\u4F46\u5F53\u524D\u9875\u7B7E\u72B6\u6001\u540C\u6B65\u5931\u8D25\u3002\u8BF7\u91CD\u65B0\u52A0\u8F7D\u6269\u5C55\u540E\u6838\u5BF9\u3002",
            "privacy.backup.error.unavailable": "\u5907\u4EFD\u6062\u590D\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
            "privacy.backup.error.failed": "\u6062\u590D\u5907\u4EFD\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
            "privacy.backup.error.readFailed": "\u65E0\u6CD5\u8BFB\u53D6\u6240\u9009\u6587\u4EF6\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",
            "workbench.taskPages": "{count} \u4E2A\u76F8\u5173\u9875\u9762",
            "workbench.globalCount": "{tabs} \u4E2A\u9875\u7B7E \xB7 {tasks} \u4E2A\u4EFB\u52A1",
            "workbench.localReady": "\u672C\u5730\u5DE5\u4F5C\u53F0\u5DF2\u5C31\u7EEA",
            "workbench.footerHint": "\u70B9\u51FB\u9875\u7B7E\u5207\u6362 \xB7 \u641C\u7D22\u540C\u6B65\u8FC7\u6EE4\u4E24\u680F",
            "workbench.unknownPage": "\u672A\u77E5\u9875\u9762",
            "workbench.sessionDwell": "\u505C\u7559 {time}",
            "workbench.pageOpenNow": "\u6D4F\u89C8\u5668\u4E2D\u5DF2\u6253\u5F00",
            "workbench.pageHistory": "\u5386\u53F2\u9875\u9762\uFF0C\u70B9\u51FB\u91CD\u65B0\u6253\u5F00",
            "workbench.previewImageAlt": "\u9875\u9762\u9884\u89C8",
            "workbench.previewLoading": "\u6B63\u5728\u52A0\u8F7D\u5B89\u5168\u9884\u89C8\u2026",
            "workbench.previewUnavailable": "\u6682\u65E0\u53EF\u7528\u9884\u89C8",
            "workbench.previewRestricted": "\u6D4F\u89C8\u5668\u9650\u5236\u9875\u9762\u65E0\u6CD5\u751F\u6210\u9884\u89C8",
            "workbench.previewActivateRequired": "\u5207\u6362\u5230\u6B64\u9875\u7B7E\u5E76\u7B49\u5F85\u52A0\u8F7D\u540E\uFF0C\u5C06\u81EA\u52A8\u751F\u6210\u9884\u89C8",
            "workbench.previewWaitingForLoad": "\u9875\u9762\u52A0\u8F7D\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u751F\u6210\u9884\u89C8",
            "workbench.openNow": "\u5F53\u524D\u5DF2\u6253\u5F00",
            "workbench.previewSwitchHint": "\u70B9\u51FB\u5361\u7247\u5207\u6362",
            "workbench.columns": "\u5217\u6570",
            "workbench.columnsAria": "\u6BCF\u884C\u9875\u7B7E\u6570\u91CF",
            "workbench.columnsValue": "{count} \u5217",
            "workbench.noTabs": "\u6CA1\u6709\u5339\u914D\u7684\u9875\u7B7E",
            "workbench.noTabsHint": "\u6362\u4E00\u4E2A\u5173\u952E\u8BCD\u6216\u7A97\u53E3\u8BD5\u8BD5",
            "workbench.noTasks": "\u6CA1\u6709\u5339\u914D\u7684\u4EFB\u52A1",
            "workbench.noTasksHint": "\u8C03\u6574\u641C\u7D22\u3001\u9886\u57DF\u6216\u72B6\u6001\u7B5B\u9009",
            "workbench.emptyTask": "\u4EFB\u52A1\u4E2D\u8FD8\u6CA1\u6709\u9875\u9762",
            "workbench.emptyTaskHint": "\u540E\u7EED\u53EF\u4ECE\u771F\u5B9E\u9875\u7B7E\u62D6\u5165",
            "workbench.recycleTitle": "\u56DE\u6536\u7AD9",
            "workbench.resizePanes": "\u8C03\u6574\u53CC\u680F\u5BBD\u5EA6",
            "workbench.collapseBrowserPane": "\u6536\u8D77\u771F\u5B9E\u9875\u7B7E\u680F",
            "workbench.collapseTaskPane": "\u6536\u8D77\u4EFB\u52A1\u603B\u89C8\u680F",
            "workbench.restoreSplitPane": "\u6062\u590D\u53CC\u680F\u603B\u89C8",
            "workbench.recycleHint": "\u6309\u5173\u95ED\u65F6\u95F4\u6392\u5217\uFF0C\u53EF\u6062\u590D\u9875\u7B7E\u3001\u9875\u7B7E\u7EC4\u548C\u4EFB\u52A1",
            "recycle.restoreAll": "\u6062\u590D\u5168\u90E8",
            "recycle.recently": "\u521A\u521A",
            "recycle.minutesAgo": "{count} \u5206\u949F\u524D",
            "recycle.today": "\u4ECA\u5929",
            "recycle.group": "\u9875\u7B7E\u7EC4",
            "recycle.task": "\u4EFB\u52A1\u7EC4",
            "recycle.closedTab": "\u5DF2\u5173\u95ED\u9875\u7B7E",
            "recycle.restore": "\u6062\u590D",
            "recycle.delete": "\u5220\u9664",
            "recycle.deletePermanently": "\u6C38\u4E45\u5220\u9664",
            "workbench.recycleRestoreAll": "\u6062\u590D\u5168\u90E8",
            "workbench.recycleEmpty": "\u56DE\u6536\u7AD9\u4E3A\u7A7A",
            "workbench.recycleEmptyHint": "\u5173\u95ED\u7684\u9875\u7B7E\u3001\u9875\u7B7E\u7EC4\u548C\u89E3\u6563\u7684\u4EFB\u52A1\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC",
            "workbench.recycleTask": "\u4EFB\u52A1\u7EC4",
            "workbench.recycleTab": "\u9875\u7B7E",
            "workbench.recycleGroup": "\u9875\u7B7E\u7EC4",
            "workbench.recycleRestore": "\u6062\u590D",
            "workbench.recycleDelete": "\u6C38\u4E45\u5220\u9664",
            "common.close": "\u5173\u95ED",
            "common.theme": "\u5207\u6362\u76AE\u80A4",
            "common.settings": "\u8BBE\u7F6E",
            "theme.title": "\u4E3B\u9898\u5916\u89C2",
            "theme.system": "\u8DDF\u968F\u7CFB\u7EDF",
            "theme.light": "\u6D45\u8272",
            "theme.dark": "\u6DF1\u8272",
            "theme.changed": "\u5DF2\u5207\u6362\u4E3A{theme}",
            "overlay.sticky": "\u5DF2\u56FA\u5B9A",
            "overlay.title": "\u9875\u7B7E\u5DE5\u4F5C\u53F0",
            "overlay.subtitle": "\u641C\u7D22\u3001\u6574\u7406\u3001\u5206\u7EC4\u3001\u6062\u590D\u4E0E\u9884\u89C8\u90FD\u96C6\u4E2D\u5728\u8FD9\u91CC",
            "overlay.membership": "\u4F1A\u5458\u72B6\u6001",
            "overlay.activated": "\u5DF2\u6C38\u4E45\u6FC0\u6D3B",
            "overlay.close": "\u5173\u95ED\u6D6E\u5C42 (Esc)",
            "overlay.searchPlaceholder": "\u641C\u7D22\u9875\u7B7E\u6807\u9898\u3001\u57DF\u540D\u6216\u7F51\u5740",
            "overlay.selectedNone": "\u5DF2\u9009 0",
            "overlay.action.newTitle": "\u65B0\u5EFA\u9875\u7B7E\uFF08\u70ED\u95E8\u4E66\u7B7E\uFF09",
            "overlay.action.new": "\u65B0\u5EFA",
            "overlay.action.groupDomainsTitle": "\u6309\u4E3B\u57DF\u540D\u4E00\u952E\u5206\u7EC4\u6240\u6709\u9875\u7B7E",
            "overlay.action.groupDomains": "\u57DF\u540D\u5206\u7EC4",
            "overlay.action.ungroupAllTitle": "\u89E3\u6563\u6240\u6709\u5206\u7EC4",
            "overlay.action.ungroupAll": "\u89E3\u7EC4",
            "overlay.action.recycleTitle": "\u67E5\u770B\u56DE\u6536\u7AD9",
            "overlay.action.recycle": "\u56DE\u6536\u7AD9",
            "overlay.action.undoTitle": "\u5173\u95ED\u56DE\u64A4\uFF08\u6062\u590D\u6700\u8FD1\u4E00\u4E2A\uFF09",
            "overlay.action.undo": "\u56DE\u64A4",
            "overlay.footer.escapeClose": "\u5173\u95ED",
            "overlay.footer.holdOpen": "\u6309\u4F4F\u5FEB\u6377\u952E\u5524\u8D77",
            "overlay.footer.stickyBefore": "\u8D85\u8FC7",
            "overlay.footer.stickyAfter": "\u79D2\u677E\u5F00\u4FDD\u6301",
            "overlay.footer.holdDuration": "\u6309\u4F4F\u65F6\u957F",
            "overlay.footer.hints": "\u70B9\u51FB\u5207\u6362 \xB7 \u60AC\u505C\u9884\u89C8 \xB7 \u62D6\u52A8\u6392\u5E8F \xB7 \u53F3\u952E\u591A\u9009",
            "overlay.layout.aria": "\u9875\u7B7E\u5E03\u5C40\u8BBE\u7F6E",
            "overlay.layout.perRow": "\u6BCF\u884C",
            "overlay.layout.perRowAria": "\u6BCF\u884C\u9875\u7B7E\u6570\u91CF",
            "overlay.layout.columns": "{count}\u5217",
            "overlay.layout.viewAria": "\u9875\u7B7E\u89C6\u56FE",
            "overlay.layout.hover": "\u60AC\u6D6E",
            "overlay.layout.card": "\u5361\u7247",
            "overlay.layout.hoverPreview": "\u60AC\u505C\u9884\u89C8",
            "overlay.selection.groupTitle": "\u5C06\u9009\u4E2D\u9875\u7B7E\u5F52\u5165\u65B0\u5206\u7EC4",
            "overlay.selection.group": "\u5206\u7EC4\u9009\u4E2D",
            "overlay.selection.closeTitle": "\u6279\u91CF\u5173\u95ED\u9009\u4E2D",
            "overlay.selection.close": "\u6279\u91CF\u5173\u95ED",
            "overlay.selection.clearTitle": "\u53D6\u6D88\u9009\u62E9",
            "overlay.selection.clear": "\u53D6\u6D88",
            "overlay.loading": "\u52A0\u8F7D\u4E2D\u2026",
            "overlay.count.recycle": "\u56DE\u6536\u7AD9 {count} \u9879",
            "overlay.count.tabs": "{count} \u4E2A\u6807\u7B7E",
            "overlay.count.windows": "{count} \u4E2A\u7A97\u53E3",
            "overlay.count.selected": "\u5DF2\u9009 {selected} / {total}",
            "dock.label": "\u7F51\u9875\u62D3\u5C55\u575E",
            "dock.expand": "\u5C55\u5F00\u7F51\u9875\u62D3\u5C55\u575E",
            "dock.addSite": "\u65B0\u589E\u7F51\u7AD9",
            "dock.search": "\u7F51\u9875\u641C\u7D22",
            "dock.settings": "\u7F51\u9875\u62D3\u5C55\u575E\u8BBE\u7F6E",
            "dock.settingsShort": "\u62D3\u5C55\u575E\u8BBE\u7F6E",
            "dock.settings.empty": "\u6682\u65E0\u56FA\u5B9A\u7F51\u7AD9",
            "dock.settings.fixedSites": "\u56FA\u5B9A\u7F51\u7AD9",
            "dock.settings.iconSize": "\u56FE\u6807\u5927\u5C0F",
            "dock.settings.magnification": "\u60AC\u505C\u653E\u5927",
            "dock.settings.influenceRadius": "\u5F71\u54CD\u8303\u56F4",
            "dock.settings.response": "\u54CD\u5E94\u901F\u5EA6",
            "dock.settings.damping": "\u963B\u5C3C",
            "dock.settings.hideDelay": "\u9690\u85CF\u5EF6\u8FDF",
            "dock.settings.tileSize": "\u56FE\u6807\u5E95\u677F\u5927\u5C0F",
            "dock.settings.trayPadding": "\u6258\u76D8\u7559\u767D",
            "dock.settings.tileOpacity": "\u5E95\u677F\u4E0D\u900F\u660E\u5EA6",
            "dock.settings.tileColor": "\u56FE\u6807\u5E95\u677F\u989C\u8272",
            "dock.settings.enabled": "\u542F\u7528\u7F51\u9875\u62D3\u5C55\u575E",
            "dock.settings.enabledHint": "\u5728\u6240\u6709\u7F51\u9875\u5E95\u90E8\u663E\u793A\u5E38\u7528\u7F51\u7AD9",
            "dock.settings.autoHide": "\u81EA\u52A8\u9690\u85CF",
            "dock.settings.autoHideHint": "\u9F20\u6807\u79BB\u5F00\u540E\u81EA\u52A8\u6536\u8D77\u62D3\u5C55\u575E",
            "dock.settings.appearance": "\u5916\u89C2",
            "dock.settings.motion": "\u52A8\u6548",
            "dock.settings.preview": "\u9884\u89C8",
            "dock.settings.previewAria": "\u7F51\u9875\u62D3\u5C55\u575E\u9884\u89C8",
            "dock.settings.reset": "\u6062\u590D\u9ED8\u8BA4",
            "dock.settings.siteName": "\u7F51\u7AD9\u540D\u79F0",
            "dock.settings.siteUrl": "\u7F51\u7AD9\u5730\u5740",
            "dock.settings.addSite": "\u6DFB\u52A0\u7F51\u7AD9",
            "dock.settings.drag": "\u62D6\u52A8\u6392\u5E8F",
            "dock.settings.save": "\u4FDD\u5B58",
            "dock.settings.delete": "\u5220\u9664",
            "dock.settings.platformNote": "\u63D0\u793A\uFF1A\u90E8\u5206\u7F51\u7AD9\u4F1A\u9650\u5236\u8BFB\u53D6\u56FE\u6807\uFF0CTabFlow \u4F1A\u81EA\u52A8\u4F7F\u7528\u5B89\u5168\u66FF\u4EE3\u56FE\u6807\u3002",
            "dock.settings.saveHint": "\u4FEE\u6539\u4F1A\u5B9E\u65F6\u9884\u89C8\uFF0C\u70B9\u51FB\u5B8C\u6210\u540E\u5173\u95ED\u8BBE\u7F6E\u3002",
            "dock.settings.done": "\u5B8C\u6210",
            "dock.settings.updated": "\u7F51\u7AD9\u5DF2\u66F4\u65B0",
            "dock.settings.added": "\u7F51\u7AD9\u5DF2\u6DFB\u52A0",
            "dock.settings.saveFailed": "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.settings.addFailed": "\u6DFB\u52A0\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.settings.saveDirtyFirst": "\u8BF7\u5148\u4FDD\u5B58\u5F53\u524D\u7F16\u8F91\u9879",
            "dock.recent": "\u6700\u8FD1\u5173\u95ED",
            "dock.recentSites": "\u6700\u8FD1\u5173\u95ED\u7684\u7F51\u7AD9",
            "dock.recentLoading": "\u6B63\u5728\u8BFB\u53D6\u6700\u8FD1\u5173\u95ED\u2026",
            "dock.recentEmpty": "\u6682\u65E0\u53EF\u6062\u590D\u7684\u7F51\u7AD9",
            "dock.recentUnavailable": "\u6700\u8FD1\u5173\u95ED\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6",
            "dock.recentRestoreAria": "\u6062\u590D {title}",
            "dock.recentRestoreFailed": "\u6062\u590D\u7F51\u7AD9\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "dock.recentSyncFailed": "\u7F51\u7AD9\u5DF2\u6253\u5F00\uFF0C\u4F46\u6700\u8FD1\u5173\u95ED\u5217\u8868\u540C\u6B65\u5931\u8D25",
            "dock.recentRestored": "\u5DF2\u6062\u590D\u7F51\u7AD9",
            "dock.menu.background": "\u5728\u540E\u53F0\u65B0\u9875\u6253\u5F00",
            "dock.menu.edit": "\u7F16\u8F91",
            "dock.menu.delete": "\u5220\u9664",
            "dock.openBackgroundFailed": "\u540E\u53F0\u6253\u5F00\u7F51\u9875\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "dock.openFailed": "\u6253\u5F00\u7F51\u9875\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "dock.deleteFailed": "\u5220\u9664\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.deleted": "\u7F51\u9875\u5DF2\u5220\u9664",
            "dock.orderSaved": "\u7F51\u9875\u987A\u5E8F\u5DF2\u4FDD\u5B58",
            "dock.orderSaveFailed": "\u6392\u5E8F\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.pinFailed": "\u56FA\u5B9A\u72B6\u6001\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.pinned": "\u5DF2\u56FA\u5B9A\u5230\u7F51\u9875\u62D3\u5C55\u575E",
            "dock.unpinned": "\u5DF2\u53D6\u6D88\u56FA\u5B9A",
            "dock.extensionUpdated": "\u6269\u5C55\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u540E\u91CD\u8BD5",
            "dock.duplicate": "\u8BE5\u7F51\u7AD9\u5DF2\u7ECF\u5728\u7F51\u9875\u62D3\u5C55\u575E\u4E2D",
            "activation.locale": "zh-CN",
            "activation.localRecord": "\u672C\u673A\u8BB0\u5F55",
            "activation.loadFailed": "\u8BFB\u53D6\u6FC0\u6D3B\u72B6\u6001\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "activation.purchaseGuide": "\u95F2\u9C7C\u8D2D\u4E70\u5F15\u5BFC\u56FE",
            "activation.purchaseActiveHint": "\u6FC0\u6D3B\u540E\u9ED8\u8BA4\u6298\u53E0\uFF0C\u4ECD\u53EF\u91CD\u65B0\u5C55\u5F00",
            "activation.purchaseHint": "\u626B\u7801\u8D2D\u4E70\u6C38\u4E45\u6FC0\u6D3B\u7801",
            "activation.expandImage": "\u5C55\u5F00\u56FE\u7247",
            "activation.purchaseAria": "\u8D2D\u4E70\u6FC0\u6D3B\u7801",
            "activation.zoomAria": "\u653E\u5927\u67E5\u770B\u95F2\u9C7C\u8D2D\u4E70\u5F15\u5BFC\u56FE",
            "activation.imageAlt": "\u95F2\u9C7C\u5E97\u94FA\u8D2D\u4E70\u5F15\u5BFC\u53CA\u4E8C\u7EF4\u7801",
            "activation.purchaseEyebrow": "\u8D2D\u4E70\u6307\u5F15",
            "activation.noCode": "\u8FD8\u6CA1\u6709\u6FC0\u6D3B\u7801\uFF1F",
            "activation.purchaseCopy": "\u4FDD\u5B58\u6216\u653E\u5927\u56FE\u7247\u540E\uFF0C\u4F7F\u7528\u95F2\u9C7C\u626B\u4E00\u626B\u8FDB\u5165\u5E97\u94FA\u8D2D\u4E70\u3002\u8D2D\u4E70\u5B8C\u6210\u540E\u4F1A\u6536\u5230\u6C38\u4E45\u6FC0\u6D3B\u7801\u3002",
            "activation.zoom": "\u653E\u5927\u67E5\u770B",
            "activation.collapseImage": "\u6536\u8D77\u56FE\u7247",
            "activation.memberStatus": "\u4F1A\u5458\u72B6\u6001",
            "activation.active": "\u5DF2\u6C38\u4E45\u6FC0\u6D3B",
            "activation.unlocked": "\u589E\u503C\u529F\u80FD\u5DF2\u89E3\u9501",
            "activation.used": "\u8BE5\u6FC0\u6D3B\u7801\u5DF2\u4F7F\u7528\u5E76\u4F5C\u5E9F",
            "activation.activatedAt": "\u6FC0\u6D3B\u65F6\u95F4\uFF1A{time}",
            "activation.deactivate": "\u6CE8\u9500\u6FC0\u6D3B",
            "activation.invalid": "\u6FC0\u6D3B\u7801\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u65B0\u8F93\u5165",
            "activation.eyebrow": "\u6C38\u4E45\u6FC0\u6D3B",
            "activation.inputTitle": "\u8F93\u5165\u8D2D\u4E70\u540E\u6536\u5230\u7684\u6FC0\u6D3B\u7801",
            "activation.copy": "\u65E0\u9700\u767B\u5F55\uFF0C\u8054\u7F51\u540E\u5373\u53EF\u9A8C\u8BC1\u3002\u672C\u673A\u5C06\u6C38\u4E45\u4FDD\u5B58\u6FC0\u6D3B\u72B6\u6001\uFF0C\u91CD\u88C5\u540E\u53EF\u518D\u6B21\u8F93\u5165\u539F\u6FC0\u6D3B\u7801\u6062\u590D\u3002",
            "activation.code": "\u6FC0\u6D3B\u7801",
            "activation.verifying": "\u6B63\u5728\u9A8C\u8BC1\u2026",
            "activation.submit": "\u9A8C\u8BC1\u5E76\u6FC0\u6D3B",
            "activation.progress": "\u6B63\u5728\u8FDE\u63A5\u5E76\u9A8C\u8BC1\u6FC0\u6D3B\u7801\uFF0C\u8BF7\u7A0D\u5019",
            "activation.offline": "\u7F51\u7EDC\u4E0D\u53EF\u7528\uFF0C\u8BF7\u8FDE\u63A5\u7F51\u7EDC\u540E\u91CD\u8BD5",
            "activation.failed": "\u6FC0\u6D3B\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "activation.previewAria": "\u8D2D\u4E70\u5F15\u5BFC\u56FE\u7247\u9884\u89C8",
            "activation.previewClose": "\u5173\u95ED\u8D2D\u4E70\u5F15\u5BFC\u56FE\u7247",
            "activation.deactivateClose": "\u5173\u95ED\u6CE8\u9500\u786E\u8BA4",
            "activation.deactivateTitle": "\u786E\u8BA4\u6CE8\u9500\u6FC0\u6D3B\uFF1F",
            "activation.deactivateCopy": "\u6CE8\u9500\u540E\u4F1A\u5458\u6807\u8BC6\u53CA\u5168\u90E8\u589E\u503C\u6743\u76CA\u5C06\u7ACB\u5373\u5931\u6548\u3002\u4F60\u53EF\u4EE5\u7A0D\u540E\u4F7F\u7528\u540C\u4E00\u6FC0\u6D3B\u7801\u91CD\u65B0\u6FC0\u6D3B\u3002",
            "activation.cancel": "\u53D6\u6D88",
            "activation.confirmDeactivate": "\u786E\u8BA4\u6CE8\u9500",
            "activation.deactivating": "\u6B63\u5728\u6CE8\u9500\u2026",
            "activation.deactivated": "\u5DF2\u6CE8\u9500\u6FC0\u6D3B",
            "activation.deactivateFailed": "\u6CE8\u9500\u6FC0\u6D3B\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.add.catalogQuick": "\u5FEB\u6377\u9009\u62E9\u5E38\u7528\u7F51\u7AD9",
            "dock.add.siteCount": "{count} \u4E2A",
            "dock.add.catalogSearchPlaceholder": "\u641C\u7D22\u7F51\u7AD9\u6216\u5206\u7C7B",
            "dock.add.catalogCategories": "\u5E38\u7528\u7F51\u7AD9\u5206\u7C7B",
            "dock.add.editTitle": "\u7F16\u8F91\u7F51\u7AD9",
            "dock.add.addTitle": "\u65B0\u589E\u7F51\u7AD9",
            "dock.add.editDescription": "\u4FEE\u6539\u7F51\u7AD9\u6807\u9898\u3001\u7F51\u5740\u548C\u56FE\u6807",
            "dock.add.addDescription": "\u4FDD\u5B58\u5F53\u524D\u9875\u9762\uFF0C\u6216\u6DFB\u52A0\u4EFB\u610F\u5E38\u7528\u7F51\u7AD9",
            "dock.add.close": "\u5173\u95ED\u65B0\u589E\u7F51\u7AD9\u5F39\u7A97",
            "dock.add.modeLabel": "\u65B0\u589E\u65B9\u5F0F",
            "dock.add.mode.current": "\u4FDD\u5B58\u5F53\u524D\u7F51\u9875",
            "dock.add.mode.custom": "\u81EA\u5B9A\u4E49\u65B0\u589E",
            "dock.add.mode.catalog": "\u9009\u62E9\u5E38\u7528\u7F51\u7AD9",
            "dock.add.mode.bookmarks": "\u4ECE\u4E66\u7B7E\u5BFC\u5165",
            "dock.add.bookmarksHeading": "\u9009\u62E9 Chrome \u4E66\u7B7E",
            "dock.add.bookmarkCount": "{count} \u4E2A",
            "dock.add.bookmarkSelected": "\u5DF2\u9009 {count} \u4E2A",
            "dock.add.bookmarkSearchPlaceholder": "\u641C\u7D22\u6807\u9898\u3001\u7F51\u5740\u6216\u6587\u4EF6\u5939",
            "dock.add.bookmarksLoading": "\u6B63\u5728\u8BFB\u53D6 Chrome \u4E66\u7B7E\u2026",
            "dock.add.bookmarksList": "Chrome \u4E66\u7B7E\u5217\u8868",
            "dock.add.bookmarksNoMatch": "\u6CA1\u6709\u5339\u914D\u7684\u4E66\u7B7E",
            "dock.add.bookmarksEmpty": "\u6682\u65E0\u53EF\u5BFC\u5165\u7684\u7F51\u9875\u4E66\u7B7E",
            "dock.add.bookmarksLoadFailed": "\u8BFB\u53D6\u4E66\u7B7E\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.add.previewAria": "\u56FE\u6807\u5B9E\u65F6\u9884\u89C8",
            "dock.add.previewCaption": "\u5B9E\u65F6\u9884\u89C8",
            "dock.add.previewTitle": "\u7F51\u7AD9\u6807\u9898",
            "dock.add.previewHint": "\u81EA\u52A8\u56FE\u6807\u4E0D\u53EF\u7528\u65F6\uFF0C\u4F1A\u4F9D\u6B21\u964D\u7EA7\u5230\u6B21\u6E05\u56FE\u6807\u4E0E\u6587\u5B57\u3002",
            "dock.add.cancel": "\u53D6\u6D88",
            "dock.add.save": "\u4FDD\u5B58\u5230\u62D3\u5C55\u575E",
            "dock.add.import": "\u5BFC\u5165\u5230\u62D3\u5C55\u575E",
            "dock.add.saving": "\u6B63\u5728\u4FDD\u5B58\u2026",
            "dock.add.currentPage": "\u5F53\u524D\u7F51\u9875",
            "dock.add.untitledBookmark": "\u672A\u547D\u540D\u4E66\u7B7E",
            "dock.add.otherBookmarks": "\u5176\u4ED6\u4E66\u7B7E",
            "dock.add.selectBookmark": "\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u4E66\u7B7E",
            "dock.add.allDuplicates": "\u6240\u9009\u7684 {count} \u4E2A\u7F51\u7AD9\u5747\u5DF2\u5728\u7F51\u9875\u62D3\u5C55\u575E\u4E2D",
            "dock.add.importFailed": "\u5BFC\u5165\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.add.importPartial": "\u5DF2\u5BFC\u5165 {count} \u4E2A\uFF0C\u968F\u540E\u5931\u8D25\uFF1A{reason}",
            "dock.add.imported": "\u5DF2\u5BFC\u5165 {count} \u4E2A\u4E66\u7B7E{suffix}",
            "dock.add.skipped": "\uFF0C\u8DF3\u8FC7 {count} \u4E2A\u5DF2\u56FA\u5B9A\u7F51\u7AD9",
            "dock.add.titleRequired": "\u8BF7\u8F93\u5165\u7F51\u7AD9\u6807\u9898",
            "dock.add.urlInvalid": "\u7F51\u9875\u7F51\u5740\u65E0\u6548",
            "dock.add.textIconInvalid": "\u6587\u5B57\u56FE\u6807\u4EC5\u652F\u6301 1\uFF5E10 \u4E2A\u4E2D\u82F1\u6587\u5B57\u6BCD",
            "dock.add.saveFailed": "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
            "dock.add.saveFailedWithReason": "\u4FDD\u5B58\u5931\u8D25\uFF1A{reason}",
            "dock.add.imageRequired": "\u8BF7\u5148\u9009\u62E9\u4E00\u5F20\u672C\u5730\u56FE\u7247",
            "dock.add.updated": "\u7F51\u9875\u5DF2\u66F4\u65B0",
            "dock.add.added": "\u7F51\u9875\u5DF2\u6DFB\u52A0",
            "dock.add.imageReadingFailed": "\u8BFB\u53D6\u56FE\u7247\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "dock.add.imageUnrecognized": "\u65E0\u6CD5\u8BC6\u522B\u8FD9\u5F20\u56FE\u7247",
            "dock.add.imageTypeInvalid": "\u4EC5\u652F\u6301 PNG\u3001JPEG\u3001WebP \u6216 SVG \u56FE\u7247",
            "dock.add.imageTooLarge": "\u56FE\u7247\u4E0D\u80FD\u8D85\u8FC7 512KB",
            "dock.add.imageSizeInvalid": "\u56FE\u7247\u5C3A\u5BF8\u65E0\u6548",
            "dock.add.imageUnavailable": "\u5F53\u524D\u9875\u9762\u65E0\u6CD5\u5904\u7406\u56FE\u7247",
            "dock.add.imageCompressedTooLarge": "\u56FE\u7247\u538B\u7F29\u540E\u4ECD\u7136\u8FC7\u5927\uFF0C\u8BF7\u6362\u4E00\u5F20\u66F4\u7B80\u6D01\u7684\u56FE\u7247",
            "dock.add.imageProcessing": "\u6B63\u5728\u5904\u7406\u56FE\u7247\u2026",
            "dock.add.imageUploadHint": "PNG / JPEG / WebP / SVG\uFF0C\u4E0D\u8D85\u8FC7 512KB",
            "dock.add.imageProcessFailed": "\u56FE\u7247\u5904\u7406\u5931\u8D25",
            "dock.search.engineAria": "\u4F7F\u7528 {engine} \u641C\u7D22",
            "dock.search.source.common": "\u5E38\u7528",
            "dock.search.source.fixed": "\u56FA\u5B9A",
            "dock.search.source.tab": "\u9875\u7B7E",
            "dock.search.source.bookmark": "\u4E66\u7B7E",
            "dock.search.source.history": "\u5386\u53F2",
            "dock.search.source.web": "\u7F51\u9875",
            "dock.search.source.unknown": "\u5176\u4ED6",
            "dock.search.recents": "\u6700\u8FD1\u641C\u7D22",
            "dock.search.resultCount": "{count} \u6761",
            "dock.search.noRecents": "\u6682\u65E0\u6700\u8FD1\u641C\u7D22\uFF0C\u8F93\u5165\u5173\u952E\u8BCD\u5F00\u59CB\u641C\u7D22",
            "dock.search.results": "\u76F8\u5173\u7ED3\u679C",
            "dock.search.sources": "\u9875\u7B7E \xB7 \u4E66\u7B7E \xB7 \u6D4F\u89C8\u5386\u53F2",
            "dock.search.emptyPermission": "\u672A\u627E\u5230\u5339\u914D\u7684\u53EF\u7528\u7ED3\u679C\uFF1B\u6388\u6743\u540E\u5C06\u81EA\u52A8\u8865\u5145\u5BF9\u5E94\u7ED3\u679C\u3002",
            "dock.search.empty": "\u6CA1\u6709\u5339\u914D\u7ED3\u679C\uFF1B\u6309 Enter \u4F7F\u7528\u5F53\u524D\u641C\u7D22\u5F15\u64CE\u641C\u7D22",
            "dock.search.openPageFailed": "\u6253\u5F00\u641C\u7D22\u9875\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "dock.search.openResultFailed": "\u6253\u5F00\u641C\u7D22\u7ED3\u679C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "dock.search.title": "\u7F51\u9875\u641C\u7D22",
            "dock.search.description": "\u5FEB\u901F\u641C\u7D22\u5F53\u524D\u9875\u7B7E\u3001\u4E66\u7B7E\u4E0E\u6D4F\u89C8\u5386\u53F2",
            "dock.search.close": "\u5173\u95ED\u7F51\u9875\u641C\u7D22",
            "dock.search.placeholder": "\u641C\u7D22\u7F51\u9875\u3001\u9875\u7B7E\u6216\u4E66\u7B7E",
            "dock.search.clear": "\u6E05\u7A7A\u641C\u7D22\u5185\u5BB9",
            "dock.search.chooseEngine": "\u9009\u62E9\u641C\u7D22\u5F15\u64CE",
            "siteEditor.category": "\u5206\u7C7B",
            "siteEditor.title": "\u7F51\u7AD9\u6807\u9898",
            "siteEditor.url": "\u7F51\u9875\u5730\u5740",
            "siteEditor.icon": "\u7F51\u7AD9\u56FE\u6807",
            "siteEditor.iconSource": "\u56FE\u6807\u6765\u6E90",
            "siteEditor.iconAuto": "\u81EA\u52A8\u83B7\u53D6",
            "siteEditor.iconText": "\u6587\u5B57\u56FE\u6807",
            "siteEditor.iconUpload": "\u672C\u5730\u4E0A\u4F20",
            "siteEditor.iconTextLabel": "\u56FE\u6807\u6587\u5B57",
            "siteEditor.iconTextPlaceholder": "\u6700\u591A 10 \u4E2A\u5B57\u7B26",
            "siteEditor.iconColor": "\u6587\u5B57\u56FE\u6807\u989C\u8272",
            "siteEditor.uploadChoose": "\u9009\u62E9\u672C\u5730\u56FE\u7247",
            "siteEditor.uploadHint": "PNG / JPEG / WebP / SVG\uFF0C\u4E0D\u8D85\u8FC7 512 KB",
            "tabList.untitled": "\uFF08\u65E0\u6807\u9898\uFF09",
            "tabList.unnamedGroup": "\u672A\u547D\u540D\u5206\u7EC4",
            "tabList.dockUnpin": "\u4ECE\u7F51\u9875\u62D3\u5C55\u575E\u53D6\u6D88\u56FA\u5B9A",
            "tabList.dockPin": "\u56FA\u5B9A\u5230\u7F51\u9875\u62D3\u5C55\u575E",
            "tabList.previewAlt": "{title} \u9884\u89C8",
            "tabList.previewLoading": "\u6B63\u5728\u52A0\u8F7D\u9884\u89C8\u2026",
            "tabList.pinned": "\u56FA\u5B9A",
            "tabList.close": "\u5173\u95ED\u9875\u7B7E",
            "tabList.switch": "\u5207\u6362",
            "tabList.duplicate": "\u590D\u5236",
            "tabList.select": "\u9009\u62E9",
            "tabList.unselect": "\u53D6\u6D88\u9009\u62E9",
            "tabList.unpin": "\u53D6\u6D88\u56FA\u5B9A",
            "tabList.pin": "\u56FA\u5B9A",
            "tabList.removeGroup": "\u79FB\u51FA\u5206\u7EC4",
            "tabList.addGroup": "\u52A0\u5165\u5206\u7EC4",
            "tabList.currentWindow": "\u5F53\u524D\u7A97\u53E3",
            "tabList.active": "\u5F53\u524D\u6807\u7B7E",
            "tabList.window": "\u7A97\u53E3 {number}{state}",
            "tabList.window.minimized": " [\u6700\u5C0F\u5316]",
            "tabList.window.maximized": " [\u6700\u5927\u5316]",
            "tabList.window.fullscreen": " [\u5168\u5C4F]",
            "tabList.editGroup": "\u70B9\u51FB\u7F16\u8F91\u5206\u7EC4",
            "tabList.edit": "\u7F16\u8F91",
            "tabList.dissolveGroup": "\u89E3\u6563\u5206\u7EC4",
            "tabList.group": "\u5206\u7EC4",
            "tabList.tab": "\u9875\u7B7E",
            "tabList.tabCount": "{count} \u4E2A\u9875\u7B7E",
            "tabList.restore": "\u6062\u590D",
            "tabList.delete": "\u5220\u9664",
            "tabList.groupNamePlaceholder": "\u5206\u7EC4\u540D\u79F0\uFF08\u53EF\u9009\uFF09",
            "tabList.cancel": "\u53D6\u6D88",
            "tabList.searchEmpty": '\u672A\u627E\u5230\u4E0E "{query}" \u76F8\u5173\u7684\u6807\u7B7E',
            "tabList.searchHint": "\u8BD5\u8BD5\u641C\u7D22\u57DF\u540D\u3001\u9875\u9762\u6807\u9898\u6216\u5206\u7EC4\u540D\u79F0",
            "tabList.empty": "\u6682\u65F6\u8FD8\u6CA1\u6709\u53EF\u7BA1\u7406\u7684\u9875\u7B7E",
            "tabList.emptyHint": "\u6253\u5F00\u66F4\u591A\u9875\u9762\uFF0C\u6216\u7A0D\u540E\u518D\u8BD5",
            "tabList.pinnedSection": "\u5DF2\u56FA\u5B9A ({count})",
            "tabList.ungroupedSection": "\u672A\u5206\u7EC4 ({count})",
            "tabList.expandMore": "\u5C55\u5F00\u5176\u4F59 {count} \u4E2A\u6807\u7B7E",
            "tabList.collapse": "\u6536\u8D77",
            "tabList.recycle": "\u56DE\u6536\u7AD9 ({count})",
            "tabList.clear": "\u6E05\u7A7A",
            "tabList.back": "\u8FD4\u56DE\u9875\u7B7E",
            "tabList.recycleEmpty": "\u56DE\u6536\u7AD9\u4E3A\u7A7A",
            "tabList.recycleHint": "\u5173\u95ED\u7684\u9875\u7B7E\u548C\u5206\u7EC4\u4F1A\u6682\u5B58\u5728\u8FD9\u91CC\uFF0C\u53EF\u968F\u65F6\u6062\u590D",
            "tabList.selected": "\u5DF2\u9009 {count}",
            "permission.bookmarks.required": "\u9700\u8981\u4E66\u7B7E\u6743\u9650\u624D\u80FD\u4ECE\u4E66\u7B7E\u5BFC\u5165\uFF1B\u53EF\u7A0D\u540E\u91CD\u8BD5\u3002",
            "permission.bookmarks.allow": "\u5141\u8BB8\u8BFB\u53D6\u4E66\u7B7E",
            "permission.bookmarks.denied": "\u672A\u83B7\u5F97\u4E66\u7B7E\u6743\u9650\uFF1B\u672A\u5BFC\u5165\u4EFB\u4F55\u4E66\u7B7E\uFF0C\u53EF\u7A0D\u540E\u91CD\u8BD5\u3002",
            "permission.bookmarks.unsupported": "\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u6309\u9700\u7533\u8BF7\u4E66\u7B7E\u6743\u9650\u3002",
            "permission.history.required": "\u9700\u8981\u5386\u53F2\u8BB0\u5F55\u6743\u9650\u624D\u80FD\u663E\u793A\u5386\u53F2\u7ED3\u679C\uFF1B\u5F53\u524D\u9875\u7B7E\u641C\u7D22\u4ECD\u53EF\u7528\u3002",
            "permission.history.allow": "\u5141\u8BB8\u8BFB\u53D6\u6D4F\u89C8\u5668\u5386\u53F2",
            "permission.history.denied": "\u672A\u83B7\u5F97\u5386\u53F2\u8BB0\u5F55\u6743\u9650\uFF1B\u4ECD\u53EF\u641C\u7D22\u5F53\u524D\u9875\u7B7E\uFF0C\u53EF\u7A0D\u540E\u91CD\u8BD5\u3002",
            "permission.history.unsupported": "\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u6309\u9700\u7533\u8BF7\u5386\u53F2\u8BB0\u5F55\u6743\u9650\u3002",
            "ai.settings.nav": "AI \u667A\u80FD\u6574\u7406",
            "ai.adjustment.summary": "\u672C\u8F6E AI \u8C03\u6574 {count} \u9879",
            "ai.adjustment.view": "\u67E5\u770B",
            "ai.adjustment.hide": "\u6536\u8D77",
            "ai.adjustment.undo": "\u64A4\u9500",
            "ai.adjustment.undoing": "\u6B63\u5728\u64A4\u9500",
            "ai.adjustment.undone": "\u5DF2\u64A4\u9500",
            "ai.adjustment.close": "\u5173\u95ED\u8BE6\u60C5",
            "ai.adjustment.panelTitle": "AI \u8C03\u6574\u8BE6\u60C5",
            "ai.adjustment.before": "\u8C03\u6574\u524D",
            "ai.adjustment.after": "\u8C03\u6574\u540E",
            "ai.adjustment.reason": "\u539F\u56E0",
            "ai.adjustment.create_ai_task": "\u521B\u5EFA\u4EFB\u52A1",
            "ai.adjustment.rename_ai_task": "\u4EFB\u52A1\u6539\u540D",
            "ai.adjustment.assign_ai_relation": "\u9875\u9762\u5F52\u7C7B",
            "ai.adjustment.reorder_ai_tasks": "\u4EFB\u52A1\u6392\u5E8F",
            "ai.adjustment.conflict": "\u65E0\u6CD5\u64A4\u9500\uFF1A\u4F60\u5DF2\u5728 AI \u8C03\u6574\u540E\u624B\u52A8\u4FEE\u6539\u76F8\u5173\u5185\u5BB9\u3002",
            "ai.adjustment.failed": "\u64A4\u9500\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
            "ai.adjustment.empty": "\u6CA1\u6709\u53EF\u663E\u793A\u7684 AI \u8C03\u6574\u3002",
            "ai.settings.title": "AI \u667A\u80FD\u6574\u7406",
            "ai.settings.description": "\u914D\u7F6E\u865A\u62DF\u4EFB\u52A1\u6574\u7406\u3001\u6A21\u578B\u6E20\u9053\u548C\u672C\u673A\u5BC6\u94A5",
            "ai.settings.scopeTitle": "AI \u53EA\u6574\u7406\u865A\u62DF\u4EFB\u52A1",
            "ai.settings.scope": "AI \u53EF\u4EE5\u81EA\u52A8\u4FEE\u6539\u53F3\u4FA7\u865A\u62DF\u4EFB\u52A1\u5173\u7CFB\u548C AI \u7BA1\u7406\u7684\u4EFB\u52A1\uFF0C\u4F46\u7EDD\u4E0D\u6253\u5F00\u3001\u5173\u95ED\u3001\u79FB\u52A8\u3001\u5206\u7EC4\u6216\u91CD\u6392\u771F\u5B9E\u9875\u7B7E\u3002",
            "ai.settings.enabled": "\u542F\u7528 AI \u667A\u80FD\u6574\u7406",
            "ai.settings.enabledHint": "\u5173\u95ED\u65F6\u4E0D\u4F1A\u4EA7\u751F\u4E91\u7AEF\u8BF7\u6C42\uFF0C\u672C\u5730\u5EFA\u8BAE\u4ECD\u53EF\u4F7F\u7528",
            "ai.settings.autoOrganize": "\u5141\u8BB8\u9AD8\u7F6E\u4FE1\u7ED3\u679C\u81EA\u52A8\u6574\u7406",
            "ai.settings.autoOrganizeHint": "\u53EA\u5904\u7406\u901A\u8FC7\u672C\u5730\u5B89\u5168\u95E8\u69DB\u7684\u9AD8\u7F6E\u4FE1\u865A\u62DF\u4EFB\u52A1\u53D8\u5316",
            "ai.settings.channelTitle": "\u6A21\u578B\u6E20\u9053",
            "ai.settings.channelHint": "OpenAI \u517C\u5BB9\u63A5\u53E3\uFF1B\u5730\u5740\u548C\u6A21\u578B\u53EF\u4EE5\u4FEE\u6539",
            "ai.settings.provider": "OpenAI \u517C\u5BB9",
            "ai.settings.baseUrl": "API \u5730\u5740",
            "ai.settings.model": "\u6A21\u578B",
            "ai.settings.apiKey": "API Key",
            "ai.settings.keyPreserved": "\u5DF2\u4FDD\u5B58\u5BC6\u94A5\uFF1B\u7559\u7A7A\u5C06\u7EE7\u7EED\u4F7F\u7528",
            "ai.settings.keyPlaceholder": "\u8F93\u5165 API Key",
            "ai.settings.showKey": "\u663E\u793A\u5BC6\u94A5",
            "ai.settings.hideKey": "\u9690\u85CF\u5BC6\u94A5",
            "ai.settings.clearKey": "\u6E05\u9664\u5BC6\u94A5",
            "ai.settings.localKey": "\u5BC6\u94A5\u4EC5\u4FDD\u5B58\u5728\u672C\u673A\uFF0C\u4E0D\u540C\u6B65\u3001\u4E0D\u5BFC\u51FA\uFF0C\u4E5F\u4E0D\u4F1A\u51FA\u73B0\u5728\u65E5\u5FD7\u6216\u63D0\u793A\u6D88\u606F\u4E2D\u3002",
            "ai.settings.previewTitle": "\u67E5\u770B\u53D1\u9001\u5B57\u6BB5\u9884\u89C8",
            "ai.settings.previewHint": "\u5F00\u542F AI \u540E\uFF0C\u4EC5\u53D1\u9001\u672C\u5730\u7B5B\u9009\u51FA\u7684\u6700\u5C0F\u5019\u9009\u4FE1\u606F\u3002",
            "ai.settings.previewPage": "\u5F53\u524D\u9875\u9762",
            "ai.settings.previewPageFields": "\u8131\u654F\u6807\u9898\u3001\u6CE8\u518C\u57DF\u540D\u3001\u8DEF\u5F84\u7C7B\u578B",
            "ai.settings.previewTasks": "\u5019\u9009\u4EFB\u52A1",
            "ai.settings.previewTaskFields": "\u4EFB\u52A1\u540D\u79F0\u3001\u9886\u57DF\u3001\u5C11\u91CF\u8131\u654F\u6838\u5FC3\u9875\u6807\u9898",
            "ai.settings.previewSignals": "\u672C\u5730\u4FE1\u53F7",
            "ai.settings.previewSignalFields": "\u805A\u5408\u540E\u7684\u8BC1\u636E\u4EE3\u7801\u3001\u98CE\u9669\u4EE3\u7801\u548C\u6B21\u6570",
            "ai.settings.previewNever": "\u4E0D\u4F1A\u53D1\u9001\u5B8C\u6574 URL\u3001\u67E5\u8BE2\u53C2\u6570\u3001\u9875\u9762\u6B63\u6587\u3001\u8F93\u5165\u5185\u5BB9\u3001Cookie\u3001\u622A\u56FE\u3001\u539F\u59CB\u884C\u4E3A\u8F68\u8FF9\u6216 API Key\u3002",
            "ai.settings.actionHint": "\u4FEE\u6539\u540E\u5148\u6D4B\u8BD5\u8FDE\u63A5\uFF0C\u518D\u4FDD\u5B58\u8BBE\u7F6E",
            "ai.settings.testConnection": "\u6D4B\u8BD5\u8FDE\u63A5",
            "ai.settings.save": "\u4FDD\u5B58 AI \u8BBE\u7F6E",
            "ai.settings.loading": "\u6B63\u5728\u8BFB\u53D6\u672C\u673A\u8BBE\u7F6E\u2026",
            "ai.settings.saving": "\u6B63\u5728\u4FDD\u5B58\u672C\u673A\u8BBE\u7F6E\u2026",
            "ai.settings.testing": "\u6B63\u5728\u6D4B\u8BD5\u8FDE\u63A5\u2026",
            "ai.settings.saved": "AI \u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u5728\u672C\u673A\u3002",
            "ai.settings.savedPermissionPending": "\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\uFF1B\u8BE5\u5730\u5740\u6743\u9650\u5C1A\u672A\u6388\u6743\uFF0C\u8FDE\u63A5\u6D4B\u8BD5\u524D\u53EF\u518D\u6B21\u5141\u8BB8\u3002",
            "ai.settings.testSuccess": "\u8FDE\u63A5\u6210\u529F\uFF0C\u53EF\u4EE5\u4F7F\u7528\u5F53\u524D\u6E20\u9053\u3002",
            "ai.settings.keyWillClear": "\u4FDD\u5B58\u540E\u5C06\u6E05\u9664\u672C\u673A\u5BC6\u94A5\u3002",
            "ai.settings.error.permission": "\u6CA1\u6709\u83B7\u5F97\u8BE5\u5730\u5740\u7684\u8BBF\u95EE\u6743\u9650\uFF1B\u53EF\u7A0D\u540E\u91CD\u8BD5\u3002",
            "ai.settings.error.unauthorized": "\u5BC6\u94A5\u88AB\u6E20\u9053\u62D2\u7EDD\uFF0C\u8BF7\u68C0\u67E5\u6216\u66F4\u6362\u5BC6\u94A5\u3002",
            "ai.settings.error.paymentRequired": "\u6E20\u9053\u4F59\u989D\u6216\u914D\u989D\u4E0D\u8DB3\uFF0C\u8BF7\u68C0\u67E5\u6E20\u9053\u8D26\u6237\u3002",
            "ai.settings.error.forbidden": "\u6E20\u9053\u62D2\u7EDD\u8BBF\u95EE\u5F53\u524D\u63A5\u53E3\u6216\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5\u8D26\u6237\u548C\u6A21\u578B\u6743\u9650\u3002",
            "ai.settings.error.quotaOrAccess": "\u6E20\u9053\u4F59\u989D\u4E0D\u8DB3\u6216\u6A21\u578B\u6743\u9650\u672A\u5F00\u901A\uFF0C\u8BF7\u68C0\u67E5\u6E20\u9053\u8D26\u6237\u3002",
            "ai.settings.error.upstreamReason": "\u6E20\u9053\u539F\u56E0\uFF1A",
            "ai.settings.error.badRequest": "\u6E20\u9053\u4E0D\u63A5\u53D7\u5F53\u524D\u6A21\u578B\u6216\u8BF7\u6C42\u53C2\u6570\uFF0C\u8BF7\u6838\u5BF9\u6A21\u578B\u540D\u79F0\u3002",
            "ai.settings.error.notFound": "API \u5730\u5740\u6216\u6A21\u578B\u63A5\u53E3\u4E0D\u53EF\u7528\uFF0C\u8BF7\u68C0\u67E5\u5730\u5740\u548C\u6A21\u578B\u540D\u79F0\u3002",
            "ai.settings.error.rateLimit": "\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
            "ai.settings.error.server": "\u6E20\u9053\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
            "ai.settings.error.timeout": "\u8FDE\u63A5\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u5730\u5740\u6216\u7F51\u7EDC\u3002",
            "ai.settings.error.network": "\u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u5730\u5740\u548C\u7F51\u7EDC\u3002",
            "ai.settings.error.baseUrl": "API \u5730\u5740\u5FC5\u987B\u662F\u6709\u6548\u7684 HTTPS \u5730\u5740\u3002",
            "ai.settings.error.invalidSettings": "AI \u6E20\u9053\u8BBE\u7F6E\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u5730\u5740\u3001\u6A21\u578B\u548C\u5BC6\u94A5\u3002",
            "ai.settings.error.invalidResponse": "\u6E20\u9053\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BFB\u53D6\u6216\u4E0D\u7B26\u5408\u63A5\u53E3\u683C\u5F0F\u7684\u54CD\u5E94\u3002",
            "ai.settings.error.provider": "\u6E20\u9053\u62D2\u7EDD\u4E86\u8BF7\u6C42\uFF0C\u4F46\u6CA1\u6709\u8FD4\u56DE\u53EF\u8BC6\u522B\u7684\u9519\u8BEF\u7C7B\u578B\u3002",
            "ai.settings.error.keyRequired": "\u8BF7\u586B\u5199 API Key\uFF0C\u6216\u4FDD\u7559\u5DF2\u4FDD\u5B58\u7684\u5BC6\u94A5\u3002",
            "ai.settings.error.model": "\u8BF7\u586B\u5199\u6A21\u578B\u540D\u79F0\u3002",
            "ai.settings.error.load": "\u8BFB\u53D6 AI \u8BBE\u7F6E\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
            "ai.settings.error.save": "\u4FDD\u5B58 AI \u8BBE\u7F6E\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
            "ai.settings.error.test": "\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u8BBE\u7F6E\u540E\u91CD\u8BD5\u3002",
            "task.newPrompt": "\u8F93\u5165\u4EFB\u52A1\u540D\u79F0",
            "task.renameHint": "\u70B9\u51FB\u53EF\u4FEE\u6539\u6807\u9898",
            "task.renameAria": "\u4FEE\u6539\u4EFB\u52A1\u6807\u9898\uFF1A{title}",
            "task.expandPages": "\u5C55\u5F00\u5168\u90E8\u9875\u7B7E",
            "task.collapsePages": "\u6536\u8D77\u4E3A\u4E00\u884C",
            "task.undoLastChange": "\u64A4\u9500\u4E0A\u4E00\u6B21\u4EFB\u52A1\u4FEE\u6539",
            "task.dragToReorder": "\u62D6\u52A8\u8C03\u6574\u4EFB\u52A1\u987A\u5E8F",
            "task.dragDisabledByFilter": "\u5207\u6362\u4E3A\u624B\u52A8\u6392\u5E8F\u5E76\u6E05\u9664\u7B5B\u9009\u540E\u53EF\u62D6\u52A8",
            "task.moveUp": "\u4E0A\u79FB\u4EFB\u52A1",
            "task.moveDown": "\u4E0B\u79FB\u4EFB\u52A1",
            "task.openAll": "\u6253\u5F00\u5168\u90E8",
            "task.closeAll": "\u5173\u95ED\u5168\u90E8",
            "task.more": "\u66F4\u591A",
            "task.dissolve": "\u89E3\u6563\u4EFB\u52A1",
            "task.removePage": "\u79FB\u51FA\u4EFB\u52A1",
            "task.source.manual": "\u624B\u52A8\u5206\u7C7B",
            "task.source.smart": "\u667A\u80FD\u5206\u7C7B",
            "suggestion.source.local": "\u672C\u5730\u5EFA\u8BAE",
            "suggestion.source.ai": "AI \u5EFA\u8BAE",
            "suggestion.confidence.high": "\u628A\u63E1\u8F83\u9AD8",
            "suggestion.confidence.medium": "\u628A\u63E1\u4E2D\u7B49",
            "suggestion.reason.opener_link": "\u7531\u8BE5\u4EFB\u52A1\u4E2D\u7684\u9875\u9762\u6253\u5F00",
            "suggestion.reason.stable_object": "\u4E0E\u8BE5\u4EFB\u52A1\u4F7F\u7528\u540C\u4E00\u5DE5\u4F5C\u5BF9\u8C61",
            "suggestion.reason.qualified_return": "\u66FE\u591A\u6B21\u5728\u8BE5\u9875\u9762\u4E0E\u4EFB\u52A1\u9875\u9762\u95F4\u5207\u6362",
            "suggestion.reason.task_snapshot_restore": "\u4E0E\u8BE5\u4EFB\u52A1\u73B0\u573A\u4E00\u540C\u6062\u590D",
            "suggestion.reason.native_group_restore": "\u4E0E\u8BE5\u4EFB\u52A1\u9875\u9762\u4ECE\u540C\u4E00\u6807\u7B7E\u7EC4\u6062\u590D",
            "suggestion.reason.title_overlap": "\u9875\u9762\u6807\u9898\u4E0E\u8BE5\u4EFB\u52A1\u76F8\u5173",
            "suggestion.reason.same_native_group": "\u4E0E\u8BE5\u4EFB\u52A1\u9875\u9762\u4F4D\u4E8E\u540C\u4E00\u6807\u7B7E\u7EC4",
            "suggestion.reason.same_window": "\u4E0E\u8BE5\u4EFB\u52A1\u9875\u9762\u4F4D\u4E8E\u540C\u4E00\u7A97\u53E3",
            "suggestion.reason.same_domain": "\u4E0E\u8BE5\u4EFB\u52A1\u9875\u9762\u6765\u81EA\u540C\u4E00\u7F51\u7AD9",
            "suggestion.reason.risk_suppressed": "\u5B58\u5728\u4E0D\u786E\u5B9A\u56E0\u7D20\uFF0C\u5DF2\u964D\u4F4E\u628A\u63E1",
            "suggestion.reason.ambiguous": "\u53E6\u6709\u76F8\u8FD1\u5019\u9009\uFF0C\u8BF7\u9009\u62E9",
            "suggestion.action.addToTask": "\u52A0\u5165\u4EFB\u52A1",
            "suggestion.action.alsoLink": "\u540C\u65F6\u5173\u8054",
            "suggestion.action.reject": "\u62D2\u7EDD",
            "suggestion.action.undo": "\u64A4\u9500",
            "suggestion.batch.enter": "\u6279\u91CF\u5904\u7406",
            "suggestion.batch.select": "\u9009\u62E9\u6B64\u5EFA\u8BAE",
            "suggestion.batch.selectAll": "\u5168\u9009\u5F53\u524D\u5EFA\u8BAE",
            "suggestion.batch.count": "\u5DF2\u9009 {count} \u6761",
            "suggestion.batch.accept": "\u6279\u91CF\u52A0\u5165\u4EFB\u52A1",
            "suggestion.batch.reject": "\u6279\u91CF\u62D2\u7EDD",
            "suggestion.batch.cancel": "\u53D6\u6D88\u6279\u91CF\u5904\u7406",
            "suggestion.batch.running": "\u6B63\u5728\u5904\u7406 {count} \u6761\u5EFA\u8BAE",
            "suggestion.batch.limit": "\u4E00\u6B21\u6700\u591A\u9009\u62E9 {count} \u6761\u5EFA\u8BAE",
            "suggestion.label.addToTask": "\u5EFA\u8BAE\u52A0\u5165\u300C{task}\u300D",
            "suggestion.label.chooseTask": "\u9009\u62E9\u6700\u7B26\u5408\u5F53\u524D\u610F\u56FE\u7684\u4EFB\u52A1",
            "suggestion.label.choosePrimary": "\u9009\u62E9\u8FD9\u4E2A\u9875\u9762\u7684\u4E3B\u8981\u4EFB\u52A1",
            "suggestion.label.multiAssociate": "\u53EF\u7EE7\u7EED\u540C\u65F6\u5173\u8054\u4EE5\u4E0B\u4EFB\u52A1",
            "suggestion.label.relatedPage": "\u9875\u9762\u201C{page}\u201D\u8FD8\u6709\u5173\u8054\u4EFB\u52A1\u5019\u9009",
            "suggestion.notice.rejected": "\u5DF2\u62D2\u7EDD\u5EFA\u8BAE",
            "suggestion.notice.accepted": "\u5DF2\u52A0\u5165\u4EFB\u52A1",
            "suggestion.state.loading": "\u6B63\u5728\u5206\u6790",
            "suggestion.aria.chooseTask": "\u9009\u62E9\u4EFB\u52A1\uFF1A{task}",
            "suggestion.aria.undoAccepted": "\u64A4\u9500\u667A\u80FD\u5F52\u7C7B\uFF1A{task}",
            "suggestion.error.expired": "\u5EFA\u8BAE\u5DF2\u8FC7\u671F",
            "suggestion.error.conflict": "\u64CD\u4F5C\u51B2\u7A81",
            "suggestion.error.failed": "\u5EFA\u8BAE\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "suggestion.why": "\u4E3A\u4EC0\u4E48\u8FD9\u6837\u5206",
            "toast.suggestionAccepted": "\u5DF2\u52A0\u5165\u4EFB\u52A1",
            "toast.suggestionRejected": "\u5DF2\u62D2\u7EDD\u5EFA\u8BAE",
            "toast.suggestionUndone": "\u5DF2\u64A4\u9500\u5EFA\u8BAE\u64CD\u4F5C",
            "toast.suggestionBatchSuccess": "\u5DF2\u6210\u529F\u5904\u7406 {count} \u6761\u5EFA\u8BAE",
            "toast.suggestionBatchPartial": "\u6210\u529F {succeeded} \u6761\uFF0C\u5931\u8D25 {failed} \u6761",
            "task.pageMoveUp": "\u4E0A\u79FB\u9875\u9762",
            "task.pageMoveDown": "\u4E0B\u79FB\u9875\u9762",
            "task.chooseNewPrimary": "\u9009\u62E9\u65B0\u7684\u4E3B\u8981\u4EFB\u52A1",
            "task.relation.primary": "\u4E3B\u8981\u4EFB\u52A1",
            "task.relation.primaryHint": "\u6B64\u9875\u9762\u7684\u4E3B\u8981\u4EFB\u52A1",
            "task.relation.assign": "\u52A0\u5165\u4EFB\u52A1\u2026",
            "task.relation.move": "\u79FB\u52A8\u5230\u4EFB\u52A1\u2026",
            "task.relation.share": "\u540C\u65F6\u5173\u8054\u4EFB\u52A1\u2026",
            "task.relation.makePrimary": "\u8BBE\u4E3A\u4E3B\u8981\u4EFB\u52A1",
            "task.relation.assignHint": "\u9009\u62E9\u9875\u9762\u7684\u4E3B\u8981\u4EFB\u52A1\u3002",
            "task.relation.moveHint": "\u76EE\u6807\u5C06\u6210\u4E3A\u4E3B\u8981\u4EFB\u52A1\uFF1B\u5F53\u524D\u4EFB\u52A1\u5173\u7CFB\u4F1A\u79FB\u9664\uFF0C\u771F\u5B9E\u9875\u7B7E\u4E0D\u53D7\u5F71\u54CD\u3002",
            "task.relation.shareHint": "\u4FDD\u7559\u5F53\u524D\u4E3B\u8981\u4EFB\u52A1\uFF0C\u5E76\u65B0\u589E\u4E00\u4E2A\u5173\u8054\u4EFB\u52A1\u3002",
            "task.relation.dropChoice": "\u9009\u62E9\u5982\u4F55\u52A0\u5165\u201C{task}\u201D",
            "task.relation.moveHere": "\u79FB\u52A8\u5230\u6B64\u4EFB\u52A1",
            "task.relation.shareHere": "\u540C\u65F6\u5173\u8054\u6B64\u4EFB\u52A1",
            "common.back": "\u8FD4\u56DE",
            "task.confirmDissolve": "\u786E\u5B9A\u89E3\u6563\u8FD9\u4E2A\u4EFB\u52A1\u5417\uFF1F\u771F\u5B9E\u9875\u7B7E\u4E0D\u4F1A\u5173\u95ED\uFF0C\u4EFB\u52A1\u7EC4\u53EF\u4EE5\u4ECE\u56DE\u6536\u7AD9\u6062\u590D\u3002",
            "task.confirmDeleteTrash": "\u786E\u5B9A\u6C38\u4E45\u5220\u9664\u8FD9\u4E2A\u56DE\u6536\u9879\u5417\uFF1F\u6B64\u64CD\u4F5C\u65E0\u6CD5\u64A4\u9500\u3002",
            "toast.taskAssigned": "\u5DF2\u624B\u52A8\u52A0\u5165\u4EFB\u52A1",
            "toast.taskRelationMoved": "\u5DF2\u79FB\u52A8\u4EFB\u52A1\u5173\u7CFB\uFF0C\u771F\u5B9E\u9875\u7B7E\u672A\u79FB\u52A8",
            "toast.taskRelationShared": "\u5DF2\u540C\u65F6\u5173\u8054\u4EFB\u52A1",
            "toast.taskPrimaryChanged": "\u4E3B\u8981\u4EFB\u52A1\u5DF2\u66F4\u65B0",
            "toast.taskRemoved": "\u5DF2\u4ECE\u4EFB\u52A1\u79FB\u51FA\uFF0C\u771F\u5B9E\u9875\u7B7E\u4E0D\u4F1A\u5173\u95ED",
            "toast.taskStatusChanged": "\u4EFB\u52A1\u72B6\u6001\u5DF2\u66F4\u65B0",
            "toast.taskDomainChanged": "\u4EFB\u52A1\u9886\u57DF\u5DF2\u66F4\u65B0",
            "toast.taskReordered": "\u4EFB\u52A1\u987A\u5E8F\u5DF2\u66F4\u65B0",
            "toast.taskPagesReordered": "\u4EFB\u52A1\u9875\u9762\u987A\u5E8F\u5DF2\u66F4\u65B0",
            "toast.taskCreated": "\u4EFB\u52A1\u5DF2\u521B\u5EFA",
            "toast.taskRenamed": "\u4EFB\u52A1\u5DF2\u66F4\u65B0",
            "toast.taskMissing": "\u8FD9\u4E2A\u4EFB\u52A1\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5173\u95ED\u5F39\u7A97\u540E\u91CD\u8BD5",
            "toast.taskDissolved": "\u4EFB\u52A1\u5DF2\u89E3\u6563\uFF0C\u53EF\u4ECE\u56DE\u6536\u7AD9\u6062\u590D\uFF1B\u771F\u5B9E\u9875\u7B7E\u4E0D\u4F1A\u5173\u95ED",
            "toast.taskRestored": "\u4EFB\u52A1\u7EC4\u5DF2\u6062\u590D",
            "toast.trashRestored": "\u56DE\u6536\u9879\u5DF2\u6062\u590D",
            "toast.trashRestoreAll": "\u56DE\u6536\u7AD9\u5185\u5BB9\u5DF2\u6062\u590D",
            "toast.trashDeleted": "\u56DE\u6536\u9879\u5DF2\u6C38\u4E45\u5220\u9664",
            "toast.trashLoadFailed": "\u56DE\u6536\u7AD9\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "toast.trashActionFailed": "\u56DE\u6536\u7AD9\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "toast.taskOpened": "\u5DF2\u6253\u5F00\u4EFB\u52A1\u9875\u9762",
            "toast.taskAlreadyOpen": "\u4EFB\u52A1\u9875\u9762\u5747\u5DF2\u6253\u5F00",
            "toast.taskNoOpenTabs": "\u5F53\u524D\u6CA1\u6709\u53EF\u5173\u95ED\u7684\u4EFB\u52A1\u9875\u7B7E",
            "toast.taskTabsClosed": "\u5DF2\u5173\u95ED\u4EFB\u52A1\u4E2D\u7684\u771F\u5B9E\u9875\u7B7E",
            "toast.taskChangeFailed": "\u4EFB\u52A1\u4FEE\u6539\u5931\u8D25",
            "toast.taskChangeUndone": "\u5DF2\u64A4\u9500\u4E0A\u4E00\u6B21\u4EFB\u52A1\u4FEE\u6539",
            "toast.taskOperationPending": "\u64CD\u4F5C\u7ED3\u679C\u5C1A\u672A\u5B8C\u5168\u540C\u6B65\uFF0C\u8BF7\u7A0D\u540E\u91CD\u65B0\u6253\u5F00\u6D6E\u5C42\u68C0\u67E5",
            "toast.taskTrashCleanupPending": "\u4EFB\u52A1\u5DF2\u6062\u590D\uFF0C\u4F46\u56DE\u6536\u8BB0\u5F55\u4ECD\u5728\u6E05\u7406",
            "toast.tabPinned": "\u5DF2\u56FA\u5B9A\u8BE5\u9875\u7B7E",
            "toast.tabUnpinned": "\u5DF2\u53D6\u6D88\u56FA\u5B9A",
            "toast.tabCommandFailed": "\u9875\u7B7E\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "toast.tabNotOpen": "\u8FD9\u4E2A\u4EFB\u52A1\u9875\u9762\u5F53\u524D\u672A\u6253\u5F00",
            "toast.taskOpenFailed": "\u6253\u5F00\u4EFB\u52A1\u9875\u9762\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "toast.taskCloseFailed": "\u5173\u95ED\u4EFB\u52A1\u9875\u7B7E\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            "toast.layoutSyncFailed": "\u5E03\u5C40\u8BBE\u7F6E\u6682\u65F6\u65E0\u6CD5\u540C\u6B65",
            "tab.activate": "\u5207\u6362\u5230 {title}",
            "tab.close": "\u5173\u95ED\u9875\u7B7E",
            "tab.pinned": "\u5DF2\u56FA\u5B9A",
            "tab.dockFixed": "\u5DF2\u56FA\u5B9A\u5230\u62D3\u5C55\u575E",
            "tab.more": "\u66F4\u591A\u64CD\u4F5C",
            "tab.removeFromDock": "\u4ECE\u7F51\u9875\u62D3\u5C55\u575E\u53D6\u6D88\u56FA\u5B9A",
            "tab.addToDock": "\u56FA\u5B9A\u5230\u7F51\u9875\u62D3\u5C55\u575E",
            "task.untitled": "\u672A\u547D\u540D\u4EFB\u52A1",
            "task.status.active": "\u8FDB\u884C\u4E2D",
            "task.status.paused": "\u5DF2\u6682\u505C",
            "task.status.done": "\u5DF2\u5B8C\u6210",
            "task.status.pending": "\u5F85\u5212\u5206",
            "domain.work": "\u5DE5\u4F5C",
            "domain.study": "\u5B66\u4E60",
            "domain.life": "\u751F\u6D3B",
            "domain.interest": "\u5174\u8DA3",
            "domain.admin": "\u4E8B\u52A1",
            "domain.other": "\u5176\u4ED6",
            "guidance.eyebrow": "\u4E3B\u52A8\u63D0\u9192",
            "guidance.close": "\u5173\u95ED\u63D0\u9192",
            "guidance.muteToday": "\u4ECA\u65E5\u4E0D\u518D\u63D0\u9192",
            "guidance.openWorkbench": "\u6309\u4F4FAlt\u952E\u6216\u70B9\u51FB\u6253\u5F00",
            "guidance.frequent.title": "\u9875\u7B7E\u5207\u5F97\u6709\u70B9\u5FEB\uFF1F\u7528 TabFlow \u4E00\u773C\u627E\u5230\u3002",
            "guidance.frequent.message": "\u7528 TabFlow \u4E00\u773C\u627E\u5230\u6B63\u5728\u5207\u6362\u7684\u9875\u9762\u3002",
            "guidance.frequent.action": "\u6309\u4F4FAlt\u952E\u6216\u70B9\u51FB\u6253\u5F00",
            "guidance.startup.title": "\u7EE7\u7EED\u4E0A\u6B21\u7684\u6D4F\u89C8\u73B0\u573A\uFF0CTabFlow \u5DF2\u5C31\u7EEA\u3002",
            "guidance.startup.message": "\u7EE7\u7EED\u4E0A\u6B21\u7684\u6D4F\u89C8\u73B0\u573A\uFF0CTabFlow \u5DF2\u5C31\u7EEA\u3002",
            "guidance.startup.action": "\u6309\u4F4FAlt\u952E\u6216\u70B9\u51FB\u6253\u5F00",
            "guidance.20.title": "\u9875\u7B7E\u591A\u8D77\u6765\u4E86\uFF0C\u7528\u4EFB\u52A1\u89C6\u56FE\u4F1A\u66F4\u6E05\u695A\u3002",
            "guidance.20.message": "\u9875\u7B7E\u591A\u8D77\u6765\u4E86\uFF0C\u7528\u4EFB\u52A1\u89C6\u56FE\u4F1A\u66F4\u6E05\u695A\u3002",
            "guidance.20.action": "\u6309\u4F4FAlt\u952E\u6216\u70B9\u51FB\u6253\u5F00",
            "guidance.30.title": "\u9875\u7B7E\u680F\u6709\u70B9\u6324\uFF0CTabFlow \u5E2E\u4F60\u5FEB\u901F\u5B9A\u4F4D\u3002",
            "guidance.30.message": "\u9875\u7B7E\u680F\u6709\u70B9\u6324\uFF0CTabFlow \u5E2E\u4F60\u5FEB\u901F\u5B9A\u4F4D\u3002",
            "guidance.30.action": "\u6309\u4F4FAlt\u952E\u6216\u70B9\u51FB\u6253\u5F00",
            taskDialogCreateTitle: "\u65B0\u589E\u4EFB\u52A1",
            taskDialogRenameTitle: "\u4FEE\u6539\u4EFB\u52A1",
            taskDialogTitleLabel: "\u4EFB\u52A1\u540D\u79F0",
            taskDialogTitlePlaceholder: "\u8F93\u5165\u4EFB\u52A1\u540D\u79F0",
            taskDialogDomainLabel: "\u9009\u62E9\u9886\u57DF",
            taskDialogCreate: "\u521B\u5EFA\u4EFB\u52A1",
            taskDialogSave: "\u4FDD\u5B58\u4FEE\u6539",
            taskDialogSaving: "\u4FDD\u5B58\u4E2D\u2026",
            taskDialogRequired: "\u8BF7\u8F93\u5165\u4EFB\u52A1\u540D\u79F0",
            taskDialogSubmitFailed: "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
            taskDomain_work: "\u5DE5\u4F5C",
            taskDomain_study: "\u5B66\u4E60",
            taskDomain_life: "\u751F\u6D3B",
            taskDomain_interest: "\u5174\u8DA3",
            taskDomain_admin: "\u4E8B\u52A1",
            taskDomain_other: "\u5176\u4ED6",
            commonCancel: "\u53D6\u6D88"
          }),
          en: Object.freeze({
            "layout.split": "Split overview",
            "layout.browser": "Browser tabs",
            "layout.tasks": "Task overview",
            "pane.browser": "Current browser tabs",
            "pane.tasks": "Task overview",
            "search.placeholder": "Search title, site, or URL",
            "filter.allWindows": "All windows",
            "filter.allDomains": "All domains",
            "filter.allStatuses": "All statuses",
            "filter.all": "All",
            "locale.id": "en-US",
            "task.new": "New task",
            "task.inbox": "Inbox",
            "inbox.ignorePage": "Ignore this page",
            "inbox.markShared": "Mark as shared / multi-task",
            "inbox.excludeSite": "Do not record this site",
            "inbox.sharedBadge": "Shared / multi-task",
            "toast.inboxPreferenceFailed": "Could not save the inbox preference. Please try again.",
            "empty.tabs": "No matching tabs",
            "empty.tasks": "No tasks yet",
            "workbench.layoutLabel": "Main view",
            "workbench.layout.split": "Split overview",
            "workbench.layout.browser": "Browser tabs",
            "workbench.layout.tasks": "Task overview",
            "workbench.layout.recycle": "Recycle bin",
            "workbench.searchPlaceholder": "Search tabs, URLs, or tasks",
            "workbench.searchHint": "Task organization never reorders real tabs",
            "workbench.browserTitle": "Current browser tabs",
            "workbench.taskTitle": "Task overview",
            "workbench.inboxTitle": "Unassigned tabs",
            "workbench.inboxCandidates": "{count} candidates",
            "workbench.inboxExpand": "Show all tabs",
            "workbench.inboxCollapse": "Collapse to one row",
            "inbox.observation.observing.label": "Observing",
            "inbox.observation.observing.reason": "Waiting for more browsing activity",
            "inbox.observation.temporary_query.label": "Quick lookup",
            "inbox.observation.temporary_query.reason": "May be a short one-off lookup",
            "inbox.observation.possible_misclick.label": "Possible misclick",
            "inbox.observation.possible_misclick.reason": "Very short visit; not classified yet",
            "inbox.observation.redirect_or_ad.label": "Ad redirect",
            "inbox.observation.redirect_or_ad.reason": "May be a redirect or advertising page",
            "inbox.observation.intent_drift.label": "Intent drift",
            "inbox.observation.intent_drift.reason": "May have drifted from the current intent",
            "workbench.statusFilter": "Filter by status",
            "workbench.domainFilter": "Filter by domain",
            "workbench.taskSort": "Sort tasks",
            "workbench.taskSort.manual": "Manual order",
            "workbench.taskSort.recent": "Recently updated",
            "workbench.taskSort.title": "Name",
            "task.view.label": "Task view",
            "task.view.cards": "Cards",
            "task.view.aggregate": "Aggregate",
            "task.view.fishbone": "Fishbone",
            "task.view.experimentalBadge": "Experimental",
            "task.view.experimentalHint": "Read-only basic view based on current task relations. Full layout and interactions will be improved later.",
            "task.view.empty": "No task data to visualize",
            "task.view.emptyHint": "Create or match tasks, then return to this view.",
            "task.view.pageCount": "{count} related pages",
            "task.view.noPages": "No related pages",
            "task.view.aggregateAria": "Task aggregation view",
            "task.view.fishboneAria": "Task fishbone view",
            "workbench.allWindows": "All windows",
            "workbench.allStatuses": "All statuses",
            "workbench.allDomains": "All domains",
            "workbench.window": "Window {number}",
            "workbench.tabCount": "{count} tabs",
            "workbench.untitledTabGroup": "Untitled tab group",
            "workbench.ungroupedTabs": "Ungrouped tabs",
            "workbench.collapseTabGroup": "Collapse tab group",
            "workbench.expandTabGroup": "Expand tab group",
            "workbench.tabGroupMore": "Tab group actions",
            "workbench.activateGroupFirst": "Switch to first tab",
            "workbench.editTabGroup": "Edit name and color",
            "workbench.ungroupTabs": "Remove from group",
            "workbench.closeTabGroup": "Close tab group",
            "workbench.ungroupTabGroup": "Ungroup",
            "workbench.closeAllTabGroup": "Close all",
            "workbench.groupByDomain": "Group by domain",
            "workbench.ungroupAll": "Ungroup all",
            "privacy.title": "Privacy & data",
            "privacy.description": "Review local activity records and manage retained data",
            "settings.languageTitle": "Interface language",
            "settings.languageHint": "Follow the browser by default, or choose a language just for TabFlow.",
            "settings.languageSystem": "Follow browser",
            "settings.languageChinese": "\u4E2D\u6587",
            "settings.languageEnglish": "English",
            "settings.languageSaveFailed": "Could not save the language setting. Try again.",
            "settings.title": "Settings",
            "settings.navigation": "Settings navigation",
            "settings.activationTitle": "Permanent activation",
            "settings.activationDescription": "Unlock premium features while the core experience stays free",
            "settings.dockTitle": "Web Dock",
            "settings.dockDescription": "Manage pinned sites, appearance, and interactions",
            "settings.close": "Close settings",
            "privacy.localBehavior": "Local activity records",
            "privacy.localBehaviorHint": "Necessary tab activity stays on this device for up to 30 days and never changes tasks or real tab order automatically.",
            "privacy.behaviorClearHint": "Clearing activity history does not delete tasks, task relationships, page records, or current tab instances.",
            "privacy.dataControls": "Data controls",
            "privacy.exportHint": "Safe export includes tasks, pages, relationships, New Tab sites, and the Web Dock. It excludes API keys, activation data, screenshots, cookies, raw activity context, and full URL parameters.",
            "privacy.export": "Safe export",
            "privacy.clearBehavior": "Clear activity history",
            "privacy.clearAi": "Clear AI data",
            "privacy.clearAll": "Clear all local data",
            "privacy.clearing": "Clearing\u2026",
            "privacy.clearAiConfirm": "Clear local AI settings, API key, and runtime state? Tasks and task relationships will be kept.",
            "privacy.clearBehaviorConfirm": "Clear up to 30 days of local activity history? Tasks, relationships, page records, and current tabs will be kept.",
            "privacy.clearBehaviorSuccess": "Cleared {count} activity records. Tasks, relationships, and current tabs were kept.",
            "privacy.clearBehaviorFailed": "Could not clear activity history. Please try again.",
            "privacy.clearAllConfirm": "Clear all local TabFlow data? This deletes tasks, relationships, activity history, and the AI key and cannot be undone.",
            "privacy.clearAiSuccess": "Local AI data cleared. Tasks and task relationships were kept.",
            "privacy.clearAllSuccess": "All local TabFlow data cleared.",
            "privacy.exportSuccess": "Safe data exported.",
            "privacy.actionFailed": "Action failed. Please try again.",
            "privacy.exportFailed": "Could not export the file. Please try again.",
            "privacy.backup.title": "Backup & restore",
            "privacy.backup.hint": "Choose a TabFlow JSON backup to review a safe summary first. Nothing is overwritten before confirmation. Maximum 5 MiB.",
            "privacy.backup.reinstallWarning": "Upgrades and extension reloads preserve local data, but uninstalling normally deletes it. Export a safe backup before uninstalling, then restore it after reinstalling.",
            "privacy.backup.choose": "Restore from backup",
            "privacy.backup.reading": "Checking\u2026",
            "privacy.backup.previewTitle": "Restore preview",
            "privacy.backup.legacy": "Legacy backup: only tasks, pages, and relationships will be replaced. New Tab sites and the Web Dock stay unchanged.",
            "privacy.backup.section.tasks": "task data",
            "privacy.backup.section.newtab": "New Tab sites",
            "privacy.backup.section.dock": "Web Dock",
            "privacy.backup.section.none": "nothing restorable",
            "privacy.backup.willOverwrite": "Will replace: {sections}",
            "privacy.backup.count.tasks": "Tasks",
            "privacy.backup.count.pages": "Pages",
            "privacy.backup.count.relations": "Relationships",
            "privacy.backup.count.categories": "New Tab categories",
            "privacy.backup.count.sites": "Saved sites",
            "privacy.backup.count.dockSites": "Web Dock sites",
            "privacy.backup.overwriteWarning": "Restore replaces the local data above. It never restores API keys, activation data, browser history, or current real tabs.",
            "privacy.backup.cancel": "Cancel",
            "privacy.backup.confirm": "Replace and restore",
            "privacy.backup.importing": "Restoring\u2026",
            "privacy.backup.importSuccess": "Restore complete. Tasks, New Tab sites, and the Web Dock are synchronized.",
            "privacy.backup.error.tooLarge": "The backup file must be 5 MiB or smaller.",
            "privacy.backup.error.invalidJson": "The selected file is not valid JSON.",
            "privacy.backup.error.invalidFormat": "The selected file is not a supported TabFlow backup.",
            "privacy.backup.error.unsupportedVersion": "This backup version is not supported yet. Update TabFlow and try again.",
            "privacy.backup.error.sensitiveData": "For privacy, this file contains sensitive data that cannot be restored.",
            "privacy.backup.error.unknownField": "The backup contains fields this version does not support.",
            "privacy.backup.error.invalidContent": "The backup is damaged or does not match the current format.",
            "privacy.backup.error.duplicate": "The backup contains duplicate records and cannot be restored safely.",
            "privacy.backup.error.brokenReference": "A task relationship points to missing data.",
            "privacy.backup.error.primaryConflict": "A page has more than one primary task in this backup.",
            "privacy.backup.error.sectionUnavailable": "This version cannot restore one of the included sections. No changes were made.",
            "privacy.backup.error.confirmationRequired": "Confirm that local data may be replaced first.",
            "privacy.backup.error.rolledBack": "Restore failed and the previous data was restored. Try again later.",
            "privacy.backup.error.partialRollback": "Restore failed and some previous data may not have been restored. Stop editing, keep the backup, reload, and verify the data.",
            "privacy.backup.error.inProgress": "Another restore is in progress. Wait for it to finish and try again.",
            "privacy.backup.error.previewRequired": "The restore preview expired. Select the backup file again and reconfirm.",
            "privacy.backup.error.reconcileFailed": "Data was written, but current-tab synchronization failed. Reload the extension and verify the data.",
            "privacy.backup.error.unavailable": "Backup and restore is temporarily unavailable. Try again later.",
            "privacy.backup.error.failed": "Could not restore the backup. Try again later.",
            "privacy.backup.error.readFailed": "Could not read the selected file. Choose it again.",
            "workbench.taskPages": "{count} related pages",
            "workbench.globalCount": "{tabs} tabs \xB7 {tasks} tasks",
            "workbench.localReady": "Local workspace ready",
            "workbench.footerHint": "Click a tab to switch \xB7 Search filters both panes",
            "workbench.unknownPage": "Unknown page",
            "workbench.sessionDwell": "Dwell {time}",
            "workbench.pageOpenNow": "Open in browser",
            "workbench.pageHistory": "History page; click to reopen",
            "workbench.previewImageAlt": "Page preview",
            "workbench.previewLoading": "Loading secure preview\u2026",
            "workbench.previewUnavailable": "Preview unavailable",
            "workbench.previewRestricted": "Browser-restricted pages cannot be previewed",
            "workbench.previewActivateRequired": "Switch to this tab and wait for it to load to generate a preview",
            "workbench.previewWaitingForLoad": "A preview will be generated after the page finishes loading",
            "workbench.openNow": "Open now",
            "workbench.previewSwitchHint": "Click card to switch",
            "workbench.columns": "Columns",
            "workbench.columnsAria": "Tabs per row",
            "workbench.columnsValue": "{count} columns",
            "workbench.noTabs": "No matching tabs",
            "workbench.noTabsHint": "Try another keyword or window",
            "workbench.noTasks": "No matching tasks",
            "workbench.noTasksHint": "Adjust search, domain, or status",
            "workbench.emptyTask": "No pages in this task yet",
            "workbench.emptyTaskHint": "You can add tabs in a later step",
            "workbench.recycleTitle": "Recycle bin",
            "workbench.resizePanes": "Resize panes",
            "workbench.collapseBrowserPane": "Collapse browser tabs pane",
            "workbench.collapseTaskPane": "Collapse task pane",
            "workbench.restoreSplitPane": "Restore split overview",
            "workbench.recycleHint": "Sorted by closing time; restore tabs, tab groups, or tasks",
            "recycle.restoreAll": "Restore all",
            "recycle.recently": "Just now",
            "recycle.minutesAgo": "{count} min ago",
            "recycle.today": "Today",
            "recycle.group": "Tab group",
            "recycle.task": "Task group",
            "recycle.closedTab": "Closed tab",
            "recycle.restore": "Restore",
            "recycle.delete": "Delete",
            "recycle.deletePermanently": "Delete permanently",
            "workbench.recycleRestoreAll": "Restore all",
            "workbench.recycleEmpty": "Recycle bin is empty",
            "workbench.recycleEmptyHint": "Closed tabs, tab groups, and dissolved tasks appear here",
            "workbench.recycleTask": "Task group",
            "workbench.recycleTab": "Tab",
            "workbench.recycleGroup": "Tab group",
            "workbench.recycleRestore": "Restore",
            "workbench.recycleDelete": "Delete permanently",
            "common.close": "Close",
            "common.theme": "Toggle theme",
            "common.settings": "Settings",
            "theme.title": "Theme",
            "theme.system": "Use system",
            "theme.light": "Light",
            "theme.dark": "Dark",
            "theme.changed": "Theme changed to {theme}",
            "overlay.sticky": "Pinned open",
            "overlay.title": "Tab workspace",
            "overlay.subtitle": "Search, organize, group, restore, and preview in one place",
            "overlay.membership": "Membership status",
            "overlay.activated": "Permanently activated",
            "overlay.close": "Close overlay (Esc)",
            "overlay.searchPlaceholder": "Search tab title, domain, or URL",
            "overlay.selectedNone": "0 selected",
            "overlay.action.newTitle": "Open a new tab from popular bookmarks",
            "overlay.action.new": "New",
            "overlay.action.groupDomainsTitle": "Group all tabs by primary domain",
            "overlay.action.groupDomains": "Group domains",
            "overlay.action.ungroupAllTitle": "Remove every tab group",
            "overlay.action.ungroupAll": "Ungroup",
            "overlay.action.recycleTitle": "View recycle bin",
            "overlay.action.recycle": "Recycle bin",
            "overlay.action.undoTitle": "Undo close and restore the latest item",
            "overlay.action.undo": "Undo",
            "overlay.footer.escapeClose": "Close",
            "overlay.footer.holdOpen": "Hold the shortcut to open",
            "overlay.footer.stickyBefore": "Hold longer than",
            "overlay.footer.stickyAfter": "seconds and release to keep open",
            "overlay.footer.holdDuration": "Hold duration",
            "overlay.footer.hints": "Click to switch \xB7 Hover to preview \xB7 Drag to reorder \xB7 Right-click to select",
            "overlay.layout.aria": "Tab layout settings",
            "overlay.layout.perRow": "Per row",
            "overlay.layout.perRowAria": "Tabs per row",
            "overlay.layout.columns": "{count} columns",
            "overlay.layout.viewAria": "Tab view",
            "overlay.layout.hover": "Compact",
            "overlay.layout.card": "Cards",
            "overlay.layout.hoverPreview": "Hover preview",
            "overlay.selection.groupTitle": "Put selected tabs in a new group",
            "overlay.selection.group": "Group selected",
            "overlay.selection.closeTitle": "Close selected tabs",
            "overlay.selection.close": "Close selected",
            "overlay.selection.clearTitle": "Clear selection",
            "overlay.selection.clear": "Cancel",
            "overlay.loading": "Loading\u2026",
            "overlay.count.recycle": "Recycle bin \xB7 {count} items",
            "overlay.count.tabs": "{count} tabs",
            "overlay.count.windows": "{count} windows",
            "overlay.count.selected": "{selected} selected / {total}",
            "dock.label": "Web Dock",
            "dock.expand": "Expand Web Dock",
            "dock.addSite": "Add site",
            "dock.search": "Web search",
            "dock.settings": "Web Dock settings",
            "dock.settingsShort": "Dock settings",
            "dock.settings.empty": "No pinned sites yet",
            "dock.settings.fixedSites": "Pinned sites",
            "dock.settings.iconSize": "Icon size",
            "dock.settings.magnification": "Hover magnification",
            "dock.settings.influenceRadius": "Influence radius",
            "dock.settings.response": "Response",
            "dock.settings.damping": "Damping",
            "dock.settings.hideDelay": "Hide delay",
            "dock.settings.tileSize": "Icon tile size",
            "dock.settings.trayPadding": "Tray padding",
            "dock.settings.tileOpacity": "Tile opacity",
            "dock.settings.tileColor": "Icon tile color",
            "dock.settings.enabled": "Enable Web Dock",
            "dock.settings.enabledHint": "Show favorite sites at the bottom of every webpage",
            "dock.settings.autoHide": "Auto-hide",
            "dock.settings.autoHideHint": "Collapse the Dock after the pointer leaves",
            "dock.settings.appearance": "Appearance",
            "dock.settings.motion": "Motion",
            "dock.settings.preview": "Preview",
            "dock.settings.previewAria": "Web Dock preview",
            "dock.settings.reset": "Reset defaults",
            "dock.settings.siteName": "Site name",
            "dock.settings.siteUrl": "Site address",
            "dock.settings.addSite": "Add site",
            "dock.settings.drag": "Drag to reorder",
            "dock.settings.save": "Save",
            "dock.settings.delete": "Delete",
            "dock.settings.platformNote": "Note: Some sites restrict icon access. TabFlow automatically uses a safe fallback.",
            "dock.settings.saveHint": "Changes preview live. Select Done to close settings.",
            "dock.settings.done": "Done",
            "dock.settings.updated": "Site updated",
            "dock.settings.added": "Site added",
            "dock.settings.saveFailed": "Could not save. Try again.",
            "dock.settings.addFailed": "Could not add the site. Try again.",
            "dock.settings.saveDirtyFirst": "Save the current edit first",
            "dock.recent": "Recently closed",
            "dock.recentSites": "Recently closed sites",
            "dock.recentLoading": "Loading recently closed sites\u2026",
            "dock.recentEmpty": "No sites available to restore",
            "dock.recentUnavailable": "Recently closed sites are temporarily unavailable",
            "dock.recentRestoreAria": "Restore {title}",
            "dock.recentRestoreFailed": "Could not restore the site. Try again.",
            "dock.recentSyncFailed": "The site opened, but the recently closed list could not sync.",
            "dock.recentRestored": "Site restored",
            "dock.menu.background": "Open in new background tab",
            "dock.menu.edit": "Edit",
            "dock.menu.delete": "Delete",
            "dock.openBackgroundFailed": "Could not open the site in the background. Try again.",
            "dock.openFailed": "Could not open the site. Try again.",
            "dock.deleteFailed": "Could not delete the site. Try again.",
            "dock.deleted": "Site deleted",
            "dock.orderSaved": "Site order saved",
            "dock.orderSaveFailed": "Could not save the order. Try again.",
            "dock.pinFailed": "Could not update the pinned state. Try again.",
            "dock.pinned": "Pinned to Web Dock",
            "dock.unpinned": "Unpinned",
            "dock.extensionUpdated": "The extension was updated. Refresh this page and try again.",
            "dock.duplicate": "This site is already in Web Dock",
            "activation.locale": "en-US",
            "activation.localRecord": "Local record",
            "activation.loadFailed": "Could not load activation status. Try again.",
            "activation.purchaseGuide": "Xianyu purchase guide",
            "activation.purchaseActiveHint": "Collapsed after activation; you can expand it anytime",
            "activation.purchaseHint": "Scan to purchase a permanent activation code",
            "activation.expandImage": "Show image",
            "activation.purchaseAria": "Purchase an activation code",
            "activation.zoomAria": "Enlarge the Xianyu purchase guide",
            "activation.imageAlt": "Xianyu shop purchase guide and QR code",
            "activation.purchaseEyebrow": "Purchase guide",
            "activation.noCode": "Need an activation code?",
            "activation.purchaseCopy": "Save or enlarge the image, then scan it with Xianyu to open the shop. You will receive a permanent activation code after purchase.",
            "activation.zoom": "Enlarge",
            "activation.collapseImage": "Hide image",
            "activation.memberStatus": "Membership status",
            "activation.active": "Permanently activated",
            "activation.unlocked": "Premium features are unlocked",
            "activation.used": "This activation code has been used and retired",
            "activation.activatedAt": "Activated: {time}",
            "activation.deactivate": "Deactivate",
            "activation.invalid": "The activation code is invalid. Check it and try again.",
            "activation.eyebrow": "Permanent activation",
            "activation.inputTitle": "Enter the activation code received after purchase",
            "activation.copy": "No account is required. Verification runs online and activation is saved permanently on this device. Re-enter the same code after reinstalling to restore access.",
            "activation.code": "Activation code",
            "activation.verifying": "Verifying\u2026",
            "activation.submit": "Verify and activate",
            "activation.progress": "Connecting and verifying your activation code",
            "activation.offline": "You are offline. Connect to the internet and try again.",
            "activation.failed": "Activation failed. Try again later.",
            "activation.previewAria": "Purchase guide image preview",
            "activation.previewClose": "Close purchase guide image",
            "activation.deactivateClose": "Close deactivation confirmation",
            "activation.deactivateTitle": "Deactivate this device?",
            "activation.deactivateCopy": "Your membership badge and premium benefits will stop immediately. You can reactivate later with the same code.",
            "activation.cancel": "Cancel",
            "activation.confirmDeactivate": "Deactivate",
            "activation.deactivating": "Deactivating\u2026",
            "activation.deactivated": "Activation removed",
            "activation.deactivateFailed": "Could not deactivate. Try again later.",
            "dock.add.catalogQuick": "Choose a common site",
            "dock.add.siteCount": "{count} sites",
            "dock.add.catalogSearchPlaceholder": "Search sites or categories",
            "dock.add.catalogCategories": "Common site categories",
            "dock.add.editTitle": "Edit site",
            "dock.add.addTitle": "Add site",
            "dock.add.editDescription": "Update the site title, address, and icon",
            "dock.add.addDescription": "Save this page or add any commonly used site",
            "dock.add.close": "Close add-site dialog",
            "dock.add.modeLabel": "Add method",
            "dock.add.mode.current": "Save current page",
            "dock.add.mode.custom": "Add manually",
            "dock.add.mode.catalog": "Choose common site",
            "dock.add.mode.bookmarks": "Import bookmarks",
            "dock.add.bookmarksHeading": "Choose Chrome bookmarks",
            "dock.add.bookmarkCount": "{count} bookmarks",
            "dock.add.bookmarkSelected": "{count} selected",
            "dock.add.bookmarkSearchPlaceholder": "Search title, address, or folder",
            "dock.add.bookmarksLoading": "Loading Chrome bookmarks\u2026",
            "dock.add.bookmarksList": "Chrome bookmark list",
            "dock.add.bookmarksNoMatch": "No matching bookmarks",
            "dock.add.bookmarksEmpty": "No web bookmarks available to import",
            "dock.add.bookmarksLoadFailed": "Could not load bookmarks. Try again.",
            "dock.add.previewAria": "Live icon preview",
            "dock.add.previewCaption": "Live preview",
            "dock.add.previewTitle": "Site title",
            "dock.add.previewHint": "If the best automatic icon is unavailable, TabFlow falls back to another icon and then text.",
            "dock.add.cancel": "Cancel",
            "dock.add.save": "Save to Dock",
            "dock.add.import": "Import to Dock",
            "dock.add.saving": "Saving\u2026",
            "dock.add.currentPage": "Current page",
            "dock.add.untitledBookmark": "Untitled bookmark",
            "dock.add.otherBookmarks": "Other bookmarks",
            "dock.add.selectBookmark": "Select at least one bookmark",
            "dock.add.allDuplicates": "All {count} selected sites are already in Web Dock",
            "dock.add.importFailed": "Import failed. Try again.",
            "dock.add.importPartial": "Imported {count}, then failed: {reason}",
            "dock.add.imported": "Imported {count} bookmarks{suffix}",
            "dock.add.skipped": "; skipped {count} already-pinned sites",
            "dock.add.titleRequired": "Enter a site title",
            "dock.add.urlInvalid": "Enter a valid web address",
            "dock.add.textIconInvalid": "A text icon must contain 1\u201310 letters",
            "dock.add.saveFailed": "Could not save the site. Try again.",
            "dock.add.saveFailedWithReason": "Could not save: {reason}",
            "dock.add.imageRequired": "Choose a local image first",
            "dock.add.updated": "Site updated",
            "dock.add.added": "Site added",
            "dock.add.imageReadingFailed": "Could not read the image. Try again.",
            "dock.add.imageUnrecognized": "This image could not be recognized",
            "dock.add.imageTypeInvalid": "Use a PNG, JPEG, WebP, or SVG image",
            "dock.add.imageTooLarge": "The image must be no larger than 512 KB",
            "dock.add.imageSizeInvalid": "The image dimensions are invalid",
            "dock.add.imageUnavailable": "This page cannot process the image",
            "dock.add.imageCompressedTooLarge": "The compressed image is still too large. Choose a simpler image.",
            "dock.add.imageProcessing": "Processing image\u2026",
            "dock.add.imageUploadHint": "PNG / JPEG / WebP / SVG, up to 512 KB",
            "dock.add.imageProcessFailed": "Could not process the image",
            "dock.search.engineAria": "Search with {engine}",
            "dock.search.source.common": "Favorite",
            "dock.search.source.fixed": "Pinned",
            "dock.search.source.tab": "Tab",
            "dock.search.source.bookmark": "Bookmark",
            "dock.search.source.history": "History",
            "dock.search.source.web": "Web",
            "dock.search.source.unknown": "Other",
            "dock.search.recents": "Recent searches",
            "dock.search.resultCount": "{count} items",
            "dock.search.noRecents": "No recent searches. Type a query to begin.",
            "dock.search.results": "Related results",
            "dock.search.sources": "Tabs \xB7 Bookmarks \xB7 History",
            "dock.search.emptyPermission": "No available matches. Allow access to include more results.",
            "dock.search.empty": "No matches. Press Enter to search with the selected engine.",
            "dock.search.openPageFailed": "Could not open the search page. Try again.",
            "dock.search.openResultFailed": "Could not open the search result. Try again.",
            "dock.search.title": "Web search",
            "dock.search.description": "Quickly search current tabs, bookmarks, and browsing history",
            "dock.search.close": "Close web search",
            "dock.search.placeholder": "Search web pages, tabs, or bookmarks",
            "dock.search.clear": "Clear search",
            "dock.search.chooseEngine": "Choose search engine",
            "siteEditor.category": "Category",
            "siteEditor.title": "Site title",
            "siteEditor.url": "Web address",
            "siteEditor.icon": "Site icon",
            "siteEditor.iconSource": "Icon source",
            "siteEditor.iconAuto": "Fetch automatically",
            "siteEditor.iconText": "Text icon",
            "siteEditor.iconUpload": "Local upload",
            "siteEditor.iconTextLabel": "Icon text",
            "siteEditor.iconTextPlaceholder": "Up to 10 letters",
            "siteEditor.iconColor": "Text icon color",
            "siteEditor.uploadChoose": "Choose a local image",
            "siteEditor.uploadHint": "PNG / JPEG / WebP / SVG, up to 512 KB",
            "tabList.untitled": "(Untitled)",
            "tabList.unnamedGroup": "Untitled group",
            "tabList.dockUnpin": "Unpin from Web Dock",
            "tabList.dockPin": "Pin to Web Dock",
            "tabList.previewAlt": "{title} preview",
            "tabList.previewLoading": "Loading preview\u2026",
            "tabList.pinned": "Pinned",
            "tabList.close": "Close tab",
            "tabList.switch": "Switch",
            "tabList.duplicate": "Duplicate",
            "tabList.select": "Select",
            "tabList.unselect": "Unselect",
            "tabList.unpin": "Unpin",
            "tabList.pin": "Pin",
            "tabList.removeGroup": "Remove from group",
            "tabList.addGroup": "Add to group",
            "tabList.currentWindow": "Current window",
            "tabList.active": "Current tab",
            "tabList.window": "Window {number}{state}",
            "tabList.window.minimized": " [minimized]",
            "tabList.window.maximized": " [maximized]",
            "tabList.window.fullscreen": " [full screen]",
            "tabList.editGroup": "Edit group",
            "tabList.edit": "Edit",
            "tabList.dissolveGroup": "Dissolve group",
            "tabList.group": "Group",
            "tabList.tab": "Tab",
            "tabList.tabCount": "{count} tabs",
            "tabList.restore": "Restore",
            "tabList.delete": "Delete",
            "tabList.groupNamePlaceholder": "Group name (optional)",
            "tabList.cancel": "Cancel",
            "tabList.searchEmpty": "No tabs match \u201C{query}\u201D",
            "tabList.searchHint": "Try a domain, page title, or group name",
            "tabList.empty": "No manageable tabs yet",
            "tabList.emptyHint": "Open more pages or try again later",
            "tabList.pinnedSection": "Pinned ({count})",
            "tabList.ungroupedSection": "Ungrouped ({count})",
            "tabList.expandMore": "Show {count} more tabs",
            "tabList.collapse": "Collapse",
            "tabList.recycle": "Recycle bin ({count})",
            "tabList.clear": "Clear",
            "tabList.back": "Back to tabs",
            "tabList.recycleEmpty": "Recycle bin is empty",
            "tabList.recycleHint": "Closed tabs and groups stay here until restored or deleted",
            "tabList.selected": "{count} selected",
            "permission.bookmarks.required": "Bookmark access is required to import bookmarks. You can try again later.",
            "permission.bookmarks.allow": "Allow bookmarks",
            "permission.bookmarks.denied": "Bookmark access was not granted. Nothing was imported, and you can try again later.",
            "permission.bookmarks.unsupported": "This browser does not support requesting bookmark access on demand.",
            "permission.history.required": "History access is required to show history results. Current-tab search still works.",
            "permission.history.allow": "Allow browser history",
            "permission.history.denied": "History access was not granted. Current-tab search still works, and you can try again later.",
            "permission.history.unsupported": "This browser does not support requesting history access on demand.",
            "ai.settings.nav": "AI organization",
            "ai.adjustment.summary": "AI adjusted {count} items",
            "ai.adjustment.view": "View",
            "ai.adjustment.hide": "Hide",
            "ai.adjustment.undo": "Undo",
            "ai.adjustment.undoing": "Undoing",
            "ai.adjustment.undone": "Undone",
            "ai.adjustment.close": "Close details",
            "ai.adjustment.panelTitle": "AI adjustment details",
            "ai.adjustment.before": "Before",
            "ai.adjustment.after": "After",
            "ai.adjustment.reason": "Why",
            "ai.adjustment.create_ai_task": "Created task",
            "ai.adjustment.rename_ai_task": "Renamed task",
            "ai.adjustment.assign_ai_relation": "Assigned page",
            "ai.adjustment.reorder_ai_tasks": "Reordered tasks",
            "ai.adjustment.conflict": "Cannot undo because you changed related items after the AI adjustment.",
            "ai.adjustment.failed": "Undo failed. Please try again.",
            "ai.adjustment.empty": "No AI adjustments to show.",
            "ai.settings.title": "AI organization",
            "ai.settings.description": "Configure virtual task organization, model access, and your local key",
            "ai.settings.scopeTitle": "AI only organizes virtual tasks",
            "ai.settings.scope": "AI may update virtual task relationships and AI-managed tasks, but it never opens, closes, moves, groups, or reorders real tabs.",
            "ai.settings.enabled": "Enable AI organization",
            "ai.settings.enabledHint": "When off, no cloud requests are made and local suggestions still work",
            "ai.settings.autoOrganize": "Auto-apply high-confidence changes",
            "ai.settings.autoOrganizeHint": "Only virtual task changes that pass local safety checks are applied",
            "ai.settings.channelTitle": "Model provider",
            "ai.settings.channelHint": "OpenAI-compatible API; the address and model are editable",
            "ai.settings.provider": "OpenAI compatible",
            "ai.settings.baseUrl": "API address",
            "ai.settings.model": "Model",
            "ai.settings.apiKey": "API Key",
            "ai.settings.keyPreserved": "A key is saved; leave blank to keep using it",
            "ai.settings.keyPlaceholder": "Enter API Key",
            "ai.settings.showKey": "Show key",
            "ai.settings.hideKey": "Hide key",
            "ai.settings.clearKey": "Clear key",
            "ai.settings.localKey": "The key stays on this device. It is not synced, exported, logged, or shown in notifications.",
            "ai.settings.previewTitle": "Preview fields sent to AI",
            "ai.settings.previewHint": "Only a locally filtered, minimal candidate set is sent when AI is enabled.",
            "ai.settings.previewPage": "Current page",
            "ai.settings.previewPageFields": "Redacted title, registered domain, and path type",
            "ai.settings.previewTasks": "Candidate tasks",
            "ai.settings.previewTaskFields": "Task name, domain, and a few redacted core-page titles",
            "ai.settings.previewSignals": "Local signals",
            "ai.settings.previewSignalFields": "Aggregated evidence codes, risk codes, and counts",
            "ai.settings.previewNever": "Full URLs, query parameters, page content, typed input, cookies, screenshots, raw behavior events, and the API Key are never sent.",
            "ai.settings.actionHint": "Test the connection before saving changes",
            "ai.settings.testConnection": "Test connection",
            "ai.settings.save": "Save AI settings",
            "ai.settings.loading": "Loading local settings\u2026",
            "ai.settings.saving": "Saving local settings\u2026",
            "ai.settings.testing": "Testing connection\u2026",
            "ai.settings.saved": "AI settings saved on this device.",
            "ai.settings.savedPermissionPending": "Settings saved; allow access to this address before testing the connection.",
            "ai.settings.testSuccess": "Connection successful. This provider is ready.",
            "ai.settings.keyWillClear": "The local key will be cleared when you save.",
            "ai.settings.error.permission": "Access to this address was not granted. You can try again later.",
            "ai.settings.error.unauthorized": "The provider rejected this key. Check or replace the key.",
            "ai.settings.error.paymentRequired": "The provider account has insufficient credit or quota.",
            "ai.settings.error.forbidden": "The provider denied access to this endpoint or model. Check account and model access.",
            "ai.settings.error.quotaOrAccess": "The provider account needs credit or access to this model.",
            "ai.settings.error.upstreamReason": "Provider reason: ",
            "ai.settings.error.badRequest": "The provider rejected the model or request parameters. Check the model name.",
            "ai.settings.error.notFound": "The API address or model endpoint is unavailable. Check the address and model name.",
            "ai.settings.error.rateLimit": "Too many requests. Try again later.",
            "ai.settings.error.server": "The provider is temporarily unavailable. Try again later.",
            "ai.settings.error.timeout": "Connection timed out. Check the address or network.",
            "ai.settings.error.network": "Could not connect. Check the address and network.",
            "ai.settings.error.baseUrl": "The API address must be a valid HTTPS address.",
            "ai.settings.error.invalidSettings": "The AI provider settings are invalid. Check the address, model, and key.",
            "ai.settings.error.invalidResponse": "The provider returned an unreadable response or one that does not match the expected API format.",
            "ai.settings.error.provider": "The provider rejected the request without a recognizable error type.",
            "ai.settings.error.keyRequired": "Enter an API Key or keep the saved key.",
            "ai.settings.error.model": "Enter a model name.",
            "ai.settings.error.load": "Could not load AI settings. Try again.",
            "ai.settings.error.save": "Could not save AI settings. Try again.",
            "ai.settings.error.test": "Connection test failed. Check the settings and try again.",
            "task.newPrompt": "Enter a task name",
            "task.renameHint": "Click to edit title",
            "task.renameAria": "Edit task title: {title}",
            "task.expandPages": "Show all tabs",
            "task.collapsePages": "Collapse to one row",
            "task.undoLastChange": "Undo last task change",
            "task.dragToReorder": "Drag to reorder tasks",
            "task.dragDisabledByFilter": "Use manual order and clear filters to drag",
            "task.moveUp": "Move task up",
            "task.moveDown": "Move task down",
            "task.openAll": "Open all",
            "task.closeAll": "Close all",
            "task.more": "More",
            "task.dissolve": "Dissolve task",
            "task.removePage": "Remove from task",
            "task.source.manual": "Manual classification",
            "task.source.smart": "Smart classification",
            "suggestion.source.local": "Local suggestion",
            "suggestion.source.ai": "AI suggestion",
            "suggestion.confidence.high": "High confidence",
            "suggestion.confidence.medium": "Medium confidence",
            "suggestion.reason.opener_link": "Opened from a page in this task",
            "suggestion.reason.stable_object": "Uses the same work item as this task",
            "suggestion.reason.qualified_return": "Frequently switched between this page and the task",
            "suggestion.reason.task_snapshot_restore": "Restored with this task",
            "suggestion.reason.native_group_restore": "Restored with task pages from the same tab group",
            "suggestion.reason.title_overlap": "Title matches this task",
            "suggestion.reason.same_native_group": "In the same tab group as task pages",
            "suggestion.reason.same_window": "In the same window as task pages",
            "suggestion.reason.same_domain": "Uses the same site as task pages",
            "suggestion.reason.risk_suppressed": "Confidence lowered due to uncertainty",
            "suggestion.reason.ambiguous": "Other close matches are available",
            "suggestion.action.addToTask": "Add to task",
            "suggestion.action.alsoLink": "Also link",
            "suggestion.action.reject": "Reject",
            "suggestion.action.undo": "Undo",
            "suggestion.batch.enter": "Batch process",
            "suggestion.batch.select": "Select this suggestion",
            "suggestion.batch.selectAll": "Select current suggestions",
            "suggestion.batch.count": "{count} selected",
            "suggestion.batch.accept": "Add selected to tasks",
            "suggestion.batch.reject": "Reject selected",
            "suggestion.batch.cancel": "Cancel batch processing",
            "suggestion.batch.running": "Processing {count} suggestions",
            "suggestion.batch.limit": "Select up to {count} suggestions at once",
            "suggestion.label.addToTask": "Add to \u201C{task}\u201D",
            "suggestion.label.chooseTask": "Choose the task that best matches your intent",
            "suggestion.label.choosePrimary": "Choose the primary task for this page",
            "suggestion.label.multiAssociate": "This page may also belong to these tasks",
            "suggestion.label.relatedPage": "\u201C{page}\u201D has additional task candidates",
            "suggestion.notice.rejected": "Suggestion rejected",
            "suggestion.notice.accepted": "Added to task",
            "suggestion.state.loading": "Analyzing",
            "suggestion.aria.chooseTask": "Choose task: {task}",
            "suggestion.aria.undoAccepted": "Undo smart classification: {task}",
            "suggestion.error.expired": "Suggestion expired",
            "suggestion.error.conflict": "Something changed. Try again.",
            "suggestion.error.failed": "Suggestion action failed. Try again.",
            "suggestion.why": "Why this suggestion",
            "toast.suggestionAccepted": "Added to task",
            "toast.suggestionRejected": "Suggestion rejected",
            "toast.suggestionUndone": "Suggestion action undone",
            "toast.suggestionBatchSuccess": "Processed {count} suggestions",
            "toast.suggestionBatchPartial": "{succeeded} succeeded, {failed} failed",
            "task.pageMoveUp": "Move page up",
            "task.pageMoveDown": "Move page down",
            "task.chooseNewPrimary": "Choose a new primary task",
            "task.relation.primary": "Primary task",
            "task.relation.primaryHint": "The primary task for this page",
            "task.relation.assign": "Add to task\u2026",
            "task.relation.move": "Move to task\u2026",
            "task.relation.share": "Also link to task\u2026",
            "task.relation.makePrimary": "Make primary task",
            "task.relation.assignHint": "Choose the primary task for this page.",
            "task.relation.moveHint": "The target becomes primary and the current task link is removed. The real tab stays where it is.",
            "task.relation.shareHint": "Keep the current primary task and add another task link.",
            "task.relation.dropChoice": "Choose how to add to \u201C{task}\u201D",
            "task.relation.moveHere": "Move to this task",
            "task.relation.shareHere": "Also link to this task",
            "common.back": "Back",
            "task.confirmDissolve": "Dissolve this task? Real tabs will stay open, and the task group can be restored from the recycle bin.",
            "task.confirmDeleteTrash": "Delete this recycled item permanently? This cannot be undone.",
            "toast.taskAssigned": "Added to task manually",
            "toast.taskRelationMoved": "Task link moved; the real tab stayed in place",
            "toast.taskRelationShared": "Page linked to another task",
            "toast.taskPrimaryChanged": "Primary task updated",
            "toast.taskRemoved": "Removed from task without closing the real tab",
            "toast.taskStatusChanged": "Task status updated",
            "toast.taskDomainChanged": "Task domain updated",
            "toast.taskReordered": "Task order updated",
            "toast.taskPagesReordered": "Task page order updated",
            "toast.taskCreated": "Task created",
            "toast.taskRenamed": "Task updated",
            "toast.taskMissing": "This task no longer exists. Close the dialog and try again.",
            "toast.taskDissolved": "Task dissolved and recoverable; real tabs remain open",
            "toast.taskRestored": "Task group restored",
            "toast.trashRestored": "Recycled item restored",
            "toast.trashRestoreAll": "Recycle bin restored",
            "toast.trashDeleted": "Recycled item permanently deleted",
            "toast.trashLoadFailed": "Could not load the recycle bin. Please try again.",
            "toast.trashActionFailed": "Recycle bin action failed. Please try again.",
            "toast.taskOpened": "Task pages opened",
            "toast.taskAlreadyOpen": "All task pages are already open",
            "toast.taskNoOpenTabs": "No open task tabs to close",
            "toast.taskTabsClosed": "Open task tabs closed",
            "toast.taskChangeFailed": "Task update failed",
            "toast.taskChangeUndone": "Last task change undone",
            "toast.taskOperationPending": "The operation is still syncing. Reopen the panel shortly to verify.",
            "toast.taskTrashCleanupPending": "The task was restored, but its trash record is still being cleaned up.",
            "toast.tabPinned": "Tab pinned",
            "toast.tabUnpinned": "Tab unpinned",
            "toast.tabCommandFailed": "Tab action failed. Please try again.",
            "toast.tabNotOpen": "This task page is not currently open",
            "toast.taskOpenFailed": "Could not open task pages. Please try again.",
            "toast.taskCloseFailed": "Could not close task tabs. Please try again.",
            "toast.layoutSyncFailed": "Layout settings could not be synchronized",
            "tab.activate": "Switch to {title}",
            "tab.close": "Close tab",
            "tab.pinned": "Pinned",
            "tab.dockFixed": "Pinned to Web Dock",
            "tab.more": "More actions",
            "tab.removeFromDock": "Unpin from Web Dock",
            "tab.addToDock": "Pin to Web Dock",
            "task.untitled": "Untitled task",
            "task.status.active": "Active",
            "task.status.paused": "Paused",
            "task.status.done": "Done",
            "task.status.pending": "Inbox",
            "domain.work": "Work",
            "domain.study": "Study",
            "domain.life": "Life",
            "domain.interest": "Interests",
            "domain.admin": "Admin",
            "domain.other": "Other",
            "guidance.eyebrow": "Proactive reminder",
            "guidance.close": "Dismiss reminder",
            "guidance.muteToday": "Not again today",
            "guidance.openWorkbench": "Hold Alt or click to open",
            "guidance.frequent.title": "Switching fast? Find the right tab at a glance.",
            "guidance.frequent.message": "Find the pages you are switching between at a glance.",
            "guidance.frequent.action": "Hold Alt or click to open",
            "guidance.startup.title": "Pick up where you left off. TabFlow is ready.",
            "guidance.startup.message": "Pick up where you left off. TabFlow is ready.",
            "guidance.startup.action": "Hold Alt or click to open",
            "guidance.20.title": "More tabs open? A task view keeps them clear.",
            "guidance.20.message": "More tabs open? A task view keeps them clear.",
            "guidance.20.action": "Hold Alt or click to open",
            "guidance.30.title": "Tab bar getting crowded? TabFlow finds pages fast.",
            "guidance.30.message": "Tab bar getting crowded? TabFlow finds pages fast.",
            "guidance.30.action": "Hold Alt or click to open",
            taskDialogCreateTitle: "New task",
            taskDialogRenameTitle: "Edit task",
            taskDialogTitleLabel: "Task name",
            taskDialogTitlePlaceholder: "Enter a task name",
            taskDialogDomainLabel: "Choose a domain",
            taskDialogCreate: "Create task",
            taskDialogSave: "Save changes",
            taskDialogSaving: "Saving\u2026",
            taskDialogRequired: "Enter a task name",
            taskDialogSubmitFailed: "Could not save. Try again.",
            taskDomain_work: "Work",
            taskDomain_study: "Study",
            taskDomain_life: "Life",
            taskDomain_interest: "Interests",
            taskDomain_admin: "Admin",
            taskDomain_other: "Other",
            commonCancel: "Cancel"
          })
        });
        function normalizeLanguage(value) {
          const language = String(value || "").trim().toLowerCase();
          return language.startsWith("zh") ? "zh" : "en";
        }
        function resolveLanguage({ manual, browserLanguage, navigatorLanguage } = {}) {
          if (manual === "zh" || manual === "zh-CN") return "zh";
          if (manual === "en") return "en";
          return normalizeLanguage(browserLanguage || navigatorLanguage || "en");
        }
        function createTranslator(language, messages = MESSAGES) {
          const locale = normalizeLanguage(language);
          return function translate(key, fallback = key) {
            const safeFallback = typeof fallback === "string" ? fallback : key;
            return messages[locale]?.[key] ?? messages.en?.[key] ?? safeFallback;
          };
        }
        return Object.freeze({ LANGUAGE_STORAGE_KEY, MESSAGES, normalizeLanguage, resolveLanguage, createTranslator });
      });
    }
  });

  // src/shared/v2-native-tab-group-model.js
  var require_v2_native_tab_group_model = __commonJS({
    "src/shared/v2-native-tab-group-model.js"(exports, module) {
      (function attachV2NativeTabGroupModel(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2NativeTabGroupModel = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2NativeTabGroupModel() {
        "use strict";
        const TAB_GROUP_ID_NONE = -1;
        const GROUP_COLORS = Object.freeze(["grey", "blue", "red", "yellow", "green", "pink", "purple", "cyan", "orange"]);
        const COLOR_SET = new Set(GROUP_COLORS);
        const CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/g;
        function integer(value, fallback = null) {
          const numeric = Number(value);
          return Number.isInteger(numeric) ? numeric : fallback;
        }
        function safeGroupTitle(value) {
          return String(value == null ? "" : value).replace(CONTROL_CHARACTERS, " ").replace(/\s+/g, " ").trim().slice(0, 80);
        }
        function safeGroupColor(value) {
          const color = String(value || "").trim().toLowerCase();
          return COLOR_SET.has(color) ? color : "grey";
        }
        function normalizeGroupMetadata(value = {}) {
          const id = integer(value.id);
          if (id == null || id < 0) return null;
          return Object.freeze({
            id,
            windowId: integer(value.windowId),
            title: safeGroupTitle(value.title),
            color: safeGroupColor(value.color),
            collapsed: value.collapsed === true
          });
        }
        function normalizeTab(value = {}) {
          const id = integer(value.id), windowId = integer(value.windowId), index = integer(value.index);
          if (id == null || windowId == null || index == null || index < 0) return null;
          const groupId = Math.max(TAB_GROUP_ID_NONE, integer(value.groupId, TAB_GROUP_ID_NONE));
          return Object.freeze({ ...value, id, windowId, index, groupId });
        }
        function metadataById(groups) {
          const result = /* @__PURE__ */ new Map();
          (Array.isArray(groups) ? groups : []).forEach((value) => {
            const group = normalizeGroupMetadata(value);
            if (group) result.set(group.id, group);
          });
          return result;
        }
        function groupSection(windowId, groupId, tabs, metadata, segment) {
          const native = groupId !== TAB_GROUP_ID_NONE;
          const group = native && metadata?.windowId !== null && metadata?.windowId !== windowId ? null : metadata;
          return Object.freeze({
            id: native ? `group:${groupId}` : `ungrouped:${windowId}:${segment}`,
            groupId,
            native,
            title: native ? group?.title || "" : "",
            color: native ? group?.color || "grey" : "grey",
            collapsed: native && group?.collapsed === true,
            firstIndex: tabs[0]?.index ?? -1,
            tabs: Object.freeze([...tabs])
          });
        }
        function buildNativeTabGroupModel(tabs, groups = []) {
          const metadata = metadataById(groups);
          const windows = /* @__PURE__ */ new Map();
          const seenTabs = /* @__PURE__ */ new Set();
          (Array.isArray(tabs) ? tabs : []).forEach((value) => {
            const tab = normalizeTab(value);
            if (!tab || seenTabs.has(tab.id)) return;
            seenTabs.add(tab.id);
            if (tab.groupId >= 0 && !metadata.has(tab.groupId)) {
              metadata.set(tab.groupId, normalizeGroupMetadata({
                id: tab.groupId,
                windowId: tab.windowId,
                title: tab._groupTitle,
                color: tab._groupColor,
                collapsed: tab._groupCollapsed
              }));
            }
            if (!windows.has(tab.windowId)) windows.set(tab.windowId, []);
            windows.get(tab.windowId).push(tab);
          });
          return Object.freeze({
            windows: Object.freeze([...windows.entries()].map(([windowId, windowTabs]) => {
              const orderedTabs = windowTabs.sort((left, right) => left.index - right.index || left.id - right.id);
              const sections = [];
              orderedTabs.forEach((tab) => {
                const previous = sections.at(-1);
                if (previous && previous.groupId === tab.groupId) previous.tabs.push(tab);
                else sections.push({ groupId: tab.groupId, tabs: [tab] });
              });
              const normalizedGroups = sections.map((section, segment) => groupSection(
                windowId,
                section.groupId,
                section.tabs,
                metadata.get(section.groupId),
                segment
              ));
              return Object.freeze({
                windowId,
                firstIndex: orderedTabs[0]?.index ?? -1,
                tabs: Object.freeze([...orderedTabs]),
                groups: Object.freeze(normalizedGroups)
              });
            }))
          });
        }
        function tabIds(group) {
          return (Array.isArray(group?.tabs) ? group.tabs : []).map((tab) => integer(tab?.id)).filter((id) => id != null);
        }
        function createGroupOperationIntent(action, group, value = {}) {
          const groupId = integer(group?.groupId, TAB_GROUP_ID_NONE);
          const ids = tabIds(group);
          if (action === "activate-first") return ids.length ? Object.freeze({ type: "tab.activate", groupId, tabId: ids[0] }) : null;
          if (action === "close-group") return ids.length ? Object.freeze({ type: "tabs.close", groupId, tabIds: Object.freeze(ids) }) : null;
          if (action === "ungroup" || action === "move-out-group") return groupId >= 0 && ids.length ? Object.freeze({ type: "tabs.ungroup", groupId, tabIds: Object.freeze(ids) }) : null;
          if (!["update-group", "rename-group", "recolor-group"].includes(action) || groupId < 0) return null;
          if (action === "rename-group" && (value == null || typeof value !== "object")) value = { title: value };
          if (action === "recolor-group" && (value == null || typeof value !== "object")) value = { color: value };
          const patch = {};
          if (action !== "recolor-group" && Object.hasOwn(value, "title")) patch.title = safeGroupTitle(value.title);
          if (action !== "rename-group" && Object.hasOwn(value, "color")) patch.color = safeGroupColor(value.color);
          return Object.keys(patch).length ? Object.freeze({ type: "group.update", groupId, patch: Object.freeze(patch) }) : null;
        }
        function createWindowOperationIntent(action, windowId) {
          const id = integer(windowId);
          if (id == null) return null;
          if (action === "group-by-domain") return Object.freeze({ type: "window.group-by-domain", windowId: id });
          if (action === "ungroup-all") return Object.freeze({ type: "window.ungroup-all", windowId: id });
          return null;
        }
        return Object.freeze({
          TAB_GROUP_ID_NONE,
          GROUP_COLORS,
          safeGroupTitle,
          safeGroupColor,
          normalizeGroupMetadata,
          normalizeTab,
          buildNativeTabGroupModel,
          createGroupOperationIntent,
          createWindowOperationIntent
        });
      });
    }
  });

  // src/shared/v2-tab-awareness-logic.js
  var require_v2_tab_awareness_logic = __commonJS({
    "src/shared/v2-tab-awareness-logic.js"(exports, module) {
      (function attachV2TabAwarenessLogic(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2TabAwarenessLogic = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2TabAwarenessLogic() {
        "use strict";
        function normalizedUrl(value) {
          try {
            const url = new URL(String(value || ""));
            url.hash = "";
            return url.href;
          } catch (_error) {
            return String(value || "").trim();
          }
        }
        function hash(value, seed) {
          let result = seed >>> 0;
          for (const character of String(value || "")) {
            result ^= character.codePointAt(0);
            result = Math.imul(result, 16777619);
          }
          return (result >>> 0).toString(36);
        }
        function pageLinkKey(url) {
          const value = normalizedUrl(url);
          return value ? `page-${hash(value, 2166136261)}-${hash(value, 2246822519)}` : "";
        }
        function formatSessionDwell(milliseconds, language = "zh") {
          const minutes = Math.floor(Math.max(0, Number(milliseconds) || 0) / 6e4);
          if (language === "en") {
            if (minutes < 1) return "<1 min";
            if (minutes < 60) return `${minutes} min`;
            const hours2 = Math.floor(minutes / 60), remainder2 = minutes % 60;
            return remainder2 ? `${hours2}h ${remainder2}m` : `${hours2}h`;
          }
          if (minutes < 1) return "<1 \u5206\u949F";
          if (minutes < 60) return `${minutes} \u5206\u949F`;
          const hours = Math.floor(minutes / 60), remainder = minutes % 60;
          return remainder ? `${hours} \u5C0F\u65F6 ${remainder} \u5206\u949F` : `${hours} \u5C0F\u65F6`;
        }
        function createSessionDwellTracker({ now = Date.now } = {}) {
          const records = /* @__PURE__ */ new Map();
          function sync(tabs) {
            const timestamp = now(), activeKeys = /* @__PURE__ */ new Set();
            (Array.isArray(tabs) ? tabs : []).forEach((tab) => {
              if (!tab?.active) return;
              const key = pageLinkKey(tab.url);
              if (!key) return;
              activeKeys.add(key);
              const record = records.get(key) || { totalMs: 0, activeSince: null };
              if (record.activeSince == null) record.activeSince = timestamp;
              records.set(key, record);
            });
            records.forEach((record, key) => {
              if (record.activeSince == null || activeKeys.has(key)) return;
              record.totalMs += Math.max(0, timestamp - record.activeSince);
              record.activeSince = null;
            });
          }
          function read(key) {
            const record = records.get(String(key || ""));
            return Object.freeze({ tracked: Boolean(record), totalMs: record?.totalMs || 0, activeSince: record?.activeSince ?? null });
          }
          return Object.freeze({ sync, read, clear: () => records.clear() });
        }
        return Object.freeze({ normalizedUrl, pageLinkKey, formatSessionDwell, createSessionDwellTracker });
      });
    }
  });

  // src/shared/v2-workbench-logic.js
  var require_v2_workbench_logic = __commonJS({
    "src/shared/v2-workbench-logic.js"(exports, module) {
      (function attachV2WorkbenchLogic(rootScope, factory) {
        const nativeGroupModel = typeof module === "object" && module.exports ? require_v2_native_tab_group_model() : rootScope.TfaV2NativeTabGroupModel;
        const api = factory(nativeGroupModel);
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchLogic = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchLogic(nativeGroupModel) {
        "use strict";
        const LAYOUTS = /* @__PURE__ */ new Set(["split", "browser", "tasks", "recycle"]);
        const TRASH_TYPES = /* @__PURE__ */ new Set(["tab", "group", "task"]);
        const DEFAULT_SPLIT_RATIO = 0.5;
        const MIN_BROWSER_PANE_WIDTH = 320;
        const MIN_TASK_PANE_WIDTH = 380;
        const SPLIT_DIVIDER_WIDTH = 7;
        const TASK_DOMAINS = Object.freeze(["work", "study", "life", "interest", "admin", "other"]);
        const TASK_STATUSES = Object.freeze(["active", "paused", "done"]);
        const TASK_STATUS_SET = new Set(TASK_STATUSES);
        const TASK_SORT_MODES = Object.freeze(["manual", "recent", "title"]);
        const TASK_SORT_SET = new Set(TASK_SORT_MODES);
        function text(value) {
          return String(value == null ? "" : value).trim().toLowerCase();
        }
        function hostOf(url) {
          try {
            return new URL(url).hostname.replace(/^www\./, "");
          } catch (_error) {
            return "";
          }
        }
        function normalizeFilter(value, fallback = "all") {
          const normalized = String(value == null ? "" : value).trim();
          return normalized || fallback;
        }
        function normalizeLayout(value) {
          return LAYOUTS.has(value) ? value : "split";
        }
        function normalizeTaskStatus(value) {
          const status = String(value || "active");
          return TASK_STATUS_SET.has(status) ? status : "active";
        }
        function normalizeStatusFilter(value) {
          const filter = normalizeFilter(value);
          return filter === "all" || TASK_STATUS_SET.has(filter) ? filter : "all";
        }
        function normalizeTaskSort(value) {
          const mode = String(value || "manual");
          return TASK_SORT_SET.has(mode) ? mode : "manual";
        }
        function sortTasks(tasks, mode = "manual") {
          const normalized = normalizeTaskSort(mode);
          return (Array.isArray(tasks) ? tasks : []).map((task, index) => ({ task, index })).sort((left, right) => {
            if (normalized === "recent") {
              const updatedAt = (value) => typeof value === "number" ? value : Date.parse(value) || 0;
              const difference = updatedAt(right.task.updatedAt) - updatedAt(left.task.updatedAt);
              if (difference) return difference;
            } else if (normalized === "title") {
              const difference = String(left.task.title || left.task.name || "").localeCompare(String(right.task.title || right.task.name || ""), void 0, { numeric: true, sensitivity: "base" });
              if (difference) return difference;
            } else {
              const difference = (Number(left.task.sortOrder) || 0) - (Number(right.task.sortOrder) || 0);
              if (difference) return difference;
            }
            return left.index - right.index;
          }).map(({ task }) => task);
        }
        function splitRatioBounds(workspaceWidth, options = {}) {
          const width = Number(workspaceWidth);
          const dividerWidth = Math.max(0, Number(options.dividerWidth) || SPLIT_DIVIDER_WIDTH);
          const available = Math.max(0, width - dividerWidth);
          const browserMinimum = Math.max(0, Number(options.browserMinimum) || MIN_BROWSER_PANE_WIDTH);
          const taskMinimum = Math.max(0, Number(options.taskMinimum) || MIN_TASK_PANE_WIDTH);
          if (!Number.isFinite(width) || available <= 0 || available < browserMinimum + taskMinimum) {
            const fallback = browserMinimum / Math.max(1, browserMinimum + taskMinimum);
            return { min: fallback, max: fallback, available };
          }
          return {
            min: browserMinimum / available,
            max: 1 - taskMinimum / available,
            available
          };
        }
        function clampSplitRatio(value, workspaceWidth, options = {}) {
          const bounds = splitRatioBounds(workspaceWidth, options);
          const numeric = Number(value);
          const ratio = Number.isFinite(numeric) ? numeric : DEFAULT_SPLIT_RATIO;
          return Math.min(bounds.max, Math.max(bounds.min, ratio));
        }
        function tabMatchesQuery(tab, query) {
          const needle = text(query);
          if (!needle) return true;
          return [tab && tab.title, tab && tab.url, hostOf(tab && tab.url)].some((value) => text(value).includes(needle));
        }
        function filterTabs(tabs, filters = {}) {
          const windowFilter = normalizeFilter(filters.windowFilter);
          return (Array.isArray(tabs) ? tabs : []).filter((tab) => {
            const sameWindow = windowFilter === "all" || String(tab.windowId) === windowFilter;
            return sameWindow && tabMatchesQuery(tab, filters.query);
          });
        }
        function filterInboxPages(pages, filters = {}) {
          return (Array.isArray(pages) ? pages : []).filter((page) => tabMatchesQuery(page, filters.query));
        }
        function taskPages(task, tabsById) {
          const embedded = Array.isArray(task.tabs) ? task.tabs : Array.isArray(task.pages) ? task.pages : [];
          if (embedded.length) return embedded;
          return (Array.isArray(task.pageIds) ? task.pageIds : []).map((id) => tabsById.get(String(id))).filter(Boolean);
        }
        const taskPageId = (page) => String(page?.pageId ?? page?.id ?? "");
        function taskPageIds(task) {
          const ids = (Array.isArray(task?.pages) ? task.pages : Array.isArray(task?.tabs) ? task.tabs : []).map(taskPageId);
          return ids.every(Boolean) && new Set(ids).size === ids.length ? ids : [];
        }
        function reorderTaskPageIds(task, sourcePageId, targetPageId, after = false) {
          const original = taskPageIds(task), source = String(sourcePageId || ""), target = targetPageId == null ? "" : String(targetPageId);
          if (!source || !original.includes(source) || target && !original.includes(target)) return null;
          if (source === target) return original;
          const ordered = original.filter((id) => id !== source), index = target ? ordered.indexOf(target) + (after ? 1 : 0) : ordered.length;
          ordered.splice(Math.max(0, index), 0, source);
          return ordered;
        }
        function moveTaskPageIds(task, pageId, offset) {
          const ordered = taskPageIds(task), from = ordered.indexOf(String(pageId)), to = from + Math.sign(Number(offset) || 0);
          if (from < 0 || to < 0 || to >= ordered.length || from === to) return ordered;
          [ordered[from], ordered[to]] = [ordered[to], ordered[from]];
          return ordered;
        }
        function taskMatchesQuery(task, pages, query) {
          const needle = text(query);
          if (!needle) return true;
          return [task.title, task.name, task.domain, task.domainId, ...pages.flatMap((page) => [page.title, page.url, hostOf(page.url)])].some((value) => text(value).includes(needle));
        }
        function filterTasks(tasks, tabs, filters = {}) {
          const domainFilter = normalizeFilter(filters.domainFilter);
          const statusFilter = normalizeStatusFilter(filters.statusFilter);
          const tabsById = new Map((Array.isArray(tabs) ? tabs : []).map((tab) => [String(tab.id), tab]));
          return (Array.isArray(tasks) ? tasks : []).reduce((result, task) => {
            const domain = String(task.domainId || task.domain || "other");
            const status = normalizeTaskStatus(task.status);
            const pages = taskPages(task, tabsById);
            if (domainFilter !== "all" && domain !== domainFilter) return result;
            if (statusFilter !== "all" && status !== statusFilter) return result;
            if (!taskMatchesQuery(task, pages, filters.query)) return result;
            result.push({ ...task, domainId: domain, status, pages });
            return result;
          }, []);
        }
        function normalizeTrashItems(items, tabs) {
          const tabsById = new Map((Array.isArray(tabs) ? tabs : []).map((tab) => [String(tab.id), tab]));
          return (Array.isArray(items) ? items : []).reduce((result, item, index) => {
            if (!item || !TRASH_TYPES.has(item.type)) return result;
            const record = item.type === "tab" ? item.page || item.tab || item.record || item : item.task || item.group || item.record || item;
            const embeddedPages = Array.isArray(record.pages) ? record.pages : Array.isArray(record.tabs) ? record.tabs : [];
            const pages = embeddedPages.length ? embeddedPages : (Array.isArray(record.pageIds) ? record.pageIds : []).map((id) => tabsById.get(String(id))).filter(Boolean);
            result.push({
              id: String(item.id == null ? `${item.type}-${index}` : item.id),
              type: item.type,
              source: item,
              record,
              title: String(record.title || record.name || record.url || ""),
              meta: String(record.meta || record.subtitle || hostOf(record.url) || record.url || ""),
              domainId: String(record.domainId || record.domain || "other"),
              status: String(record.status || "pending"),
              color: String(record.color || ""),
              closedAt: String(item.closedAt || item.deletedAt || ""),
              label: String(item.label || ""),
              pages
            });
            return result;
          }, []);
        }
        function filterTrashItems(items, tabs, filters = {}) {
          const needle = text(filters.query);
          const normalized = normalizeTrashItems(items, tabs);
          if (!needle) return normalized;
          return normalized.filter((item) => [
            item.title,
            item.meta,
            item.domainId,
            item.status,
            ...item.pages.flatMap((page) => [page.title, page.url, hostOf(page.url)])
          ].some((value) => text(value).includes(needle)));
        }
        function windowOptions(tabs) {
          return [...new Set((Array.isArray(tabs) ? tabs : []).map((tab) => String(tab.windowId)))].sort((left, right) => Number(left) - Number(right));
        }
        function domainOptions() {
          return [...TASK_DOMAINS];
        }
        function groupTabsByWindow(tabs) {
          const groups = /* @__PURE__ */ new Map();
          (Array.isArray(tabs) ? tabs : []).forEach((tab) => {
            const key = String(tab.windowId);
            if (!groups.has(key)) groups.set(key, []);
            groups.get(key).push(tab);
          });
          return [...groups.entries()].map(([windowId, items]) => ({
            windowId,
            tabs: [...items].sort((left, right) => Number(left.index || 0) - Number(right.index || 0))
          }));
        }
        function buildWorkbenchModel(input = {}) {
          const filters = {
            query: String(input.query || ""),
            windowFilter: normalizeFilter(input.windowFilter),
            domainFilter: normalizeFilter(input.domainFilter),
            statusFilter: normalizeStatusFilter(input.statusFilter),
            taskSort: normalizeTaskSort(input.taskSort)
          };
          const tabs = Array.isArray(input.tabs) ? input.tabs : [];
          const tasks = Array.isArray(input.tasks) ? input.tasks : [];
          const inboxPages = Array.isArray(input.inboxPages) ? input.inboxPages : [];
          const trashItems = Array.isArray(input.trashItems) ? input.trashItems : [];
          const visibleTabs = filterTabs(tabs, filters);
          const visibleTasks = sortTasks(filterTasks(tasks, tabs, filters), filters.taskSort);
          const visibleInboxPages = filterInboxPages(inboxPages, filters);
          const visibleTrashItems = normalizeTrashItems(trashItems, tabs);
          return {
            layout: normalizeLayout(input.layout),
            filters,
            tabCount: tabs.length,
            taskCount: tasks.length,
            trashCount: trashItems.length,
            visibleTabCount: visibleTabs.length,
            visibleTaskCount: visibleTasks.length,
            inboxCount: inboxPages.length,
            visibleInboxCount: visibleInboxPages.length,
            windows: windowOptions(tabs),
            domains: domainOptions(tasks),
            tabGroups: groupTabsByWindow(visibleTabs),
            nativeTabWindows: nativeGroupModel.buildNativeTabGroupModel(visibleTabs, input.nativeTabGroups).windows,
            tasks: visibleTasks,
            inboxPages: visibleInboxPages,
            trashItems: visibleTrashItems
          };
        }
        return Object.freeze({
          TASK_DOMAINS,
          TASK_STATUSES,
          TASK_SORT_MODES,
          hostOf,
          normalizeLayout,
          normalizeTaskStatus,
          normalizeTaskSort,
          splitRatioBounds,
          clampSplitRatio,
          tabMatchesQuery,
          filterTabs,
          filterInboxPages,
          taskPageId,
          taskPageIds,
          reorderTaskPageIds,
          moveTaskPageIds,
          filterTasks,
          sortTasks,
          normalizeTrashItems,
          filterTrashItems,
          windowOptions,
          domainOptions,
          groupTabsByWindow,
          buildWorkbenchModel
        });
      });
    }
  });

  // src/shared/v2-suggestion-view-logic.js
  var require_v2_suggestion_view_logic = __commonJS({
    "src/shared/v2-suggestion-view-logic.js"(exports, module) {
      (function attachV2SuggestionViewLogic(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2SuggestionViewLogic = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2SuggestionViewLogic() {
        "use strict";
        const MEDIUM_CONFIDENCE = 0.28;
        const HIGH_CONFIDENCE = 0.6;
        const MAX_AMBIGUOUS_CANDIDATES = 3;
        const MAX_REASON_KEYS = 2;
        const EVIDENCE_PRIORITY = Object.freeze([
          "opener_link",
          "stable_object",
          "qualified_return",
          "task_snapshot_restore",
          "native_group_restore",
          "title_overlap",
          "same_native_group",
          "same_window",
          "same_domain",
          "risk_suppressed",
          "ambiguous"
        ]);
        const EVIDENCE_SET = new Set(EVIDENCE_PRIORITY);
        function id(value) {
          return String(value == null ? "" : value).trim();
        }
        function timestamp(value) {
          const numeric = Number(value);
          return Number.isFinite(numeric) && numeric >= 0 ? numeric : 0;
        }
        function compareIds(left, right) {
          const first = id(left), second = id(right);
          return first < second ? -1 : first > second ? 1 : 0;
        }
        function compareSuggestions(left, right) {
          return Number(left.rank) - Number(right.rank) || timestamp(right.updatedAt) - timestamp(left.updatedAt) || timestamp(right.createdAt) - timestamp(left.createdAt) || compareIds(left.analysisRunId, right.analysisRunId) || compareIds(left.taskId, right.taskId) || compareIds(left.id, right.id);
        }
        function confidenceKey(confidence) {
          return confidence >= HIGH_CONFIDENCE ? "suggestion.confidence.high" : "suggestion.confidence.medium";
        }
        function sourceKey(origin) {
          return origin === "ai" ? "suggestion.source.ai" : "suggestion.source.local";
        }
        function reasonKeys(evidenceCodes, includeAmbiguous) {
          const codes = new Set((Array.isArray(evidenceCodes) ? evidenceCodes : []).map(id).filter((code) => EVIDENCE_SET.has(code) && (includeAmbiguous || code !== "ambiguous")));
          return EVIDENCE_PRIORITY.filter((code) => codes.has(code)).slice(0, MAX_REASON_KEYS).map((code) => `suggestion.reason.${code}`);
        }
        function validSuggestion(suggestion, now, pageIds, taskIds) {
          if (!suggestion || suggestion.status !== "pending") return false;
          const pageId = id(suggestion.pageId), taskId = id(suggestion.taskId);
          const confidence = Number(suggestion.confidence), rank = Number(suggestion.rank);
          return Boolean(id(suggestion.id) && id(suggestion.analysisRunId) && pageIds.has(pageId) && taskIds.has(taskId)) && Number.isInteger(rank) && rank >= 1 && rank <= 8 && Number.isFinite(confidence) && confidence >= MEDIUM_CONFIDENCE && confidence <= 1 && Number.isFinite(Number(suggestion.expiresAt)) && Number(suggestion.expiresAt) > now && (suggestion.origin === "rule" || suggestion.origin === "ai");
        }
        function uniqueByTask(suggestions) {
          const result = [], seen = /* @__PURE__ */ new Set();
          suggestions.slice().sort(compareSuggestions).forEach((suggestion) => {
            const taskId = id(suggestion.taskId);
            if (seen.has(taskId)) return;
            seen.add(taskId);
            result.push(suggestion);
          });
          return result;
        }
        function runBlock(runSuggestions) {
          const unique = uniqueByTask(runSuggestions);
          const additional = unique.filter((suggestion) => suggestion.isPrimary === false && ["shared", "related"].includes(String(suggestion.role || "")));
          if (additional.length) {
            const candidates2 = additional.slice(0, MAX_AMBIGUOUS_CANDIDATES);
            return { ambiguous: candidates2.length > 1, mode: "multi-associate", candidates: candidates2, lead: candidates2[0] };
          }
          const stablePrimary = unique.filter((suggestion) => suggestion.isPrimary === true && Array.isArray(suggestion.evidenceCodes) && suggestion.evidenceCodes.includes("stable_object"));
          if (stablePrimary.length >= 2) {
            const candidates2 = stablePrimary.slice(0, MAX_AMBIGUOUS_CANDIDATES);
            return { ambiguous: true, mode: "primary-choice", candidates: candidates2, lead: candidates2[0] };
          }
          const ambiguous = unique.filter((suggestion) => Array.isArray(suggestion.riskFlags) && suggestion.riskFlags.includes("ambiguous"));
          if (ambiguous.length >= 2) {
            const candidates2 = ambiguous.slice(0, MAX_AMBIGUOUS_CANDIDATES);
            return { ambiguous: true, mode: "primary-choice", candidates: candidates2, lead: candidates2[0] };
          }
          const candidates = unique.slice(0, 1);
          return candidates.length ? { ambiguous: false, mode: "single", candidates, lead: candidates[0] } : null;
        }
        function candidateView(suggestion, task, ambiguous) {
          return Object.freeze({
            suggestionId: id(suggestion.id),
            taskId: id(suggestion.taskId),
            taskTitle: String(task.title == null ? "" : task.title).trim(),
            taskDomain: id(task.domain || "other"),
            rank: Number(suggestion.rank),
            sourceKey: sourceKey(suggestion.origin),
            confidenceKey: confidenceKey(Number(suggestion.confidence)),
            reasonKeys: Object.freeze(reasonKeys(suggestion.evidenceCodes, ambiguous)),
            relationRole: String(suggestion.role || ""),
            isPrimary: suggestion.isPrimary === true
          });
        }
        function pageOrder(inputPageIds, pagesById) {
          if (!Array.isArray(inputPageIds)) return Array.from(pagesById.keys()).sort();
          const seen = /* @__PURE__ */ new Set();
          return inputPageIds.reduce((result, value) => {
            const pageId = id(value);
            if (pageId && pagesById.has(pageId) && !seen.has(pageId)) {
              seen.add(pageId);
              result.push(pageId);
            }
            return result;
          }, []);
        }
        function buildSuggestionViewBlocks(input = {}) {
          const now = Number(input.now);
          if (!Number.isFinite(now) || now < 0) throw new TypeError("Suggestion view requires a valid now timestamp");
          const tasks = Array.isArray(input.tasks) ? input.tasks : [];
          const pages = Array.isArray(input.pages) ? input.pages : [];
          const suggestions = Array.isArray(input.suggestions) ? input.suggestions : [];
          const tasksById = new Map(tasks.map((task) => [id(task && task.id), task]).filter(([taskId]) => taskId));
          const pagesById = new Map(pages.map((page) => [id(page && page.id), page]).filter(([pageId]) => pageId));
          const taskIds = new Set(tasksById.keys());
          const allowedPages = new Set(pageOrder(input.pageIds, pagesById));
          const eligible = suggestions.filter((suggestion) => validSuggestion(suggestion, now, allowedPages, taskIds));
          const suggestionsByPage = eligible.reduce((map, suggestion) => {
            const pageId = id(suggestion.pageId);
            if (!map.has(pageId)) map.set(pageId, []);
            map.get(pageId).push(suggestion);
            return map;
          }, /* @__PURE__ */ new Map());
          const blocks = [];
          pageOrder(input.pageIds, pagesById).forEach((pageId) => {
            const pageSuggestions = suggestionsByPage.get(pageId) || [];
            const runs = pageSuggestions.reduce((map, suggestion) => {
              const runId = id(suggestion.analysisRunId);
              if (!map.has(runId)) map.set(runId, []);
              map.get(runId).push(suggestion);
              return map;
            }, /* @__PURE__ */ new Map());
            const selected = Array.from(runs.entries()).map(([analysisRunId, items]) => {
              const block = runBlock(items);
              return block && { ...block, analysisRunId };
            }).filter(Boolean).sort((left, right) => compareSuggestions(left.lead, right.lead))[0];
            if (!selected) return;
            blocks.push(Object.freeze({
              pageId,
              analysisRunId: selected.analysisRunId,
              ambiguous: selected.ambiguous,
              mode: selected.mode,
              candidates: Object.freeze(selected.candidates.map((suggestion) => candidateView(suggestion, tasksById.get(id(suggestion.taskId)), selected.ambiguous)))
            }));
          });
          return Object.freeze(blocks);
        }
        return Object.freeze({
          MEDIUM_CONFIDENCE,
          HIGH_CONFIDENCE,
          MAX_AMBIGUOUS_CANDIDATES,
          MAX_REASON_KEYS,
          EVIDENCE_PRIORITY,
          buildSuggestionViewBlocks
        });
      });
    }
  });

  // src/content/overlay-template.js
  var require_overlay_template = __commonJS({
    "src/content/overlay-template.js"(exports, module) {
      (function attachOverlayTemplate(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaOverlayTemplate = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createOverlayTemplate() {
        "use strict";
        const SEARCH_SVG = '<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>';
        const SETTINGS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M12 3.5a2 2 0 0 1 2 2v.3a7 7 0 0 1 1.7 1l.3-.2a2 2 0 1 1 2 3.4l-.3.2c.1.6.1 1.2 0 1.8l.3.2a2 2 0 1 1-2 3.4l-.3-.2a7 7 0 0 1-1.7 1v.3a2 2 0 1 1-4 0v-.3a7 7 0 0 1-1.7-1l-.3.2a2 2 0 1 1-2-3.4l.3-.2a7 7 0 0 1 0-1.8L6 10a2 2 0 1 1 2-3.4l.3.2a7 7 0 0 1 1.7-1v-.3a2 2 0 0 1 2-2Z"/><circle cx="12" cy="11.1" r="2.5"/></svg>';
        const MEMBER_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="m4 8 4 3 4-6 4 6 4-3-1.5 9h-13L4 8Z"/><path d="M6 20h12"/></svg>';
        const ACTIVATION_FALLBACK_CSS = `
    .settings-tool-btn{width:36px;padding:0;justify-content:center}.settings-tool-btn svg{width:17px;height:17px}.settings-tool-btn.member{color:var(--tfa-accent);background:rgba(var(--tfa-accent-rgb),.12)}
    .settings-dialog-shell,.purchase-preview{position:absolute;inset:0;z-index:70;display:flex;align-items:center;justify-content:center;padding:28px;pointer-events:auto}.settings-dialog-overlay,.purchase-preview-backdrop{position:absolute;inset:0;background:rgba(3,6,14,.56);backdrop-filter:blur(8px)}
    .settings-dialog{position:relative;width:min(760px,92vw);height:min(720px,82vh);max-height:min(720px,82vh);display:grid;grid-template-columns:160px minmax(0,1fr);grid-template-rows:minmax(0,1fr);overflow:hidden;border:1px solid var(--tfa-panel-border);border-radius:18px;background:var(--tfa-panel-bg);box-shadow:var(--tfa-panel-shadow)}
    .settings-sidebar{min-height:0;padding:20px 14px;overflow-y:auto;border-right:1px solid var(--tfa-border-soft);background:var(--tfa-hdr-bg)}.settings-nav-item{display:flex;gap:8px;padding:10px;border-radius:10px;color:var(--tfa-text-primary);background:rgba(var(--tfa-accent-rgb),.12)}
    .settings-main{min-width:0;min-height:0;display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden}#settingsContent{min-width:0;min-height:0;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable;touch-action:pan-y}.settings-dialog-header{display:flex;justify-content:space-between;gap:16px;padding:20px 22px 16px;border-bottom:1px solid var(--tfa-border-soft)}.settings-dialog-close{width:34px;height:34px;border:0;border-radius:10px;background:var(--tfa-btn-bg);color:var(--tfa-text-secondary)}
    .activation-panel{display:grid;gap:14px;padding:20px 22px}.activation-card,.activation-success,.activation-purchase-row{border:1px solid var(--tfa-border-soft);border-radius:14px;background:var(--tfa-card-bg);padding:14px}.activation-purchase-layout{display:grid;grid-template-columns:150px 1fr;gap:16px;align-items:center}.activation-purchase-image{width:100%;max-height:260px;object-fit:contain;border-radius:10px;cursor:zoom-in}.activation-form-row{display:grid;grid-template-columns:1fr auto;gap:10px;margin-top:12px}.activation-input{min-width:0;height:42px;border:1px solid var(--tfa-border-medium);border-radius:10px;background:var(--tfa-input-bg);color:var(--tfa-text-primary);padding:0 12px}.activation-submit{gap:8px}.activation-spinner{width:14px;height:14px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:activation-spin .72s linear infinite}.activation-error{color:var(--tfa-danger);margin-top:8px}.activation-success{display:grid;grid-template-columns:auto 1fr;gap:12px}.activation-success-icon{color:var(--tfa-success)}.activation-success-actions{margin-top:14px;padding-top:12px;border-top:1px solid var(--tfa-border-soft)}.activation-deactivate{padding:0;border:0;background:transparent;color:var(--tfa-danger);font:inherit;font-size:12px;cursor:pointer}
    .deactivation-confirm{position:absolute;inset:0;z-index:95;display:flex;align-items:center;justify-content:center;padding:20px}.deactivation-backdrop{position:absolute;inset:0;background:rgba(3,6,14,.62);backdrop-filter:blur(8px)}.deactivation-dialog{position:relative;width:min(420px,92vw);padding:22px;border:1px solid var(--tfa-panel-border);border-radius:16px;background:var(--tfa-panel-bg);color:var(--tfa-text-primary);box-shadow:var(--tfa-panel-shadow)}.deactivation-close{position:absolute;top:14px;right:14px;width:32px;height:32px;border:0;border-radius:9px;background:var(--tfa-btn-bg);color:var(--tfa-text-secondary)}.deactivation-icon{display:flex;align-items:center;justify-content:center;width:38px;height:38px;margin-bottom:14px;border-radius:50%;background:rgba(var(--tfa-danger-rgb),.14);color:var(--tfa-danger);font-weight:800}.deactivation-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}.deactivation-danger{gap:8px;background:var(--tfa-danger);color:#fff}.deactivation-error{margin-top:12px;color:var(--tfa-danger);font-size:12px}.deactivation-error[hidden]{display:none}
    .purchase-preview{z-index:90}.purchase-preview-dialog{position:relative;max-width:min(760px,90vw);max-height:88vh;padding:14px;border:1px solid var(--tfa-panel-border);border-radius:18px;background:var(--tfa-panel-bg)}.purchase-preview-image{display:block;max-width:100%;max-height:78vh;object-fit:contain;border-radius:12px}.purchase-preview-close{position:absolute;right:20px;top:20px;width:36px;height:36px;border:1px solid var(--tfa-border-medium);border-radius:10px;background:var(--tfa-panel-bg);color:var(--tfa-text-primary)}
    @keyframes activation-spin{to{transform:rotate(360deg)}}
    @media(max-width:780px){.settings-dialog-shell{padding:12px}.settings-dialog{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr);width:96vw;height:88vh;max-height:88vh}.settings-sidebar{display:flex;flex-direction:row;gap:8px;overflow-x:auto;overflow-y:hidden;padding:10px 12px;border-right:0;border-bottom:1px solid var(--tfa-border-soft)}.settings-nav-item{flex:1 0 auto;justify-content:center}.activation-purchase-layout{grid-template-columns:110px 1fr}.activation-form-row{grid-template-columns:1fr}}
    @media(prefers-reduced-motion:reduce){.activation-spinner{animation:none}.deactivation-confirm,.deactivation-dialog{transition:none!important}}
  `;
        function translated(translate, key, fallback, params = {}) {
          const value = typeof translate === "function" ? translate(key, params) : "";
          const base = value && value !== key ? value : fallback;
          return String(base).replace(/\{(\w+)\}/g, (_match, name) => String(params[name] ?? ""));
        }
        function localizeOverlay(root, translate) {
          if (!root?.querySelectorAll) return false;
          root.querySelectorAll("[data-i18n]").forEach((node) => {
            node.textContent = translated(translate, node.dataset.i18n, node.dataset.i18nFallback || node.textContent || "");
          });
          for (const [attribute, datasetKey] of [
            ["placeholder", "i18nPlaceholder"],
            ["aria-label", "i18nAriaLabel"],
            ["title", "i18nTitle"]
          ]) {
            root.querySelectorAll(`[data-${datasetKey.replace(/[A-Z]/g, (character) => `-${character.toLowerCase()}`)}]`).forEach((node) => {
              node.setAttribute(attribute, translated(
                translate,
                node.dataset[datasetKey],
                node.dataset[`${datasetKey}Fallback`] || node.getAttribute(attribute) || ""
              ));
            });
          }
          const panel = root.getElementById?.("panel");
          if (panel) panel.dataset.stickyLabel = translated(translate, "overlay.sticky", "\u5DF2\u56FA\u5B9A");
          return true;
        }
        function buildOverlay({ root, version, translate }) {
          const SCRIPT_VERSION = String(version || "");
          const tx = (key, fallback, params) => translated(translate, key, fallback, params);
          root.innerHTML = `
      <style id="tfa-dock-critical">:host([data-styles-ready="false"]) .web-dock-shell{display:none!important}</style>
      <style id="tfa-fallback">
        :host{--tfa-backdrop-bg:rgba(4,8,18,.58);--tfa-panel-bg:rgba(14,18,29,.9);--tfa-panel-border:rgba(255,255,255,.08);--tfa-panel-shadow:0 28px 80px rgba(0,0,0,.42);--tfa-panel-glow:radial-gradient(circle at top,rgba(99,102,241,.12),transparent 38%);--tfa-text-primary:#eef2ff;--tfa-text-secondary:#a8b0c5;--tfa-text-tertiary:#707b91;--tfa-border-soft:rgba(255,255,255,.06);--tfa-border-medium:rgba(255,255,255,.12);--tfa-border-strong:rgba(255,255,255,.18);--tfa-card-bg:rgba(255,255,255,.035);--tfa-card-hover-bg:rgba(255,255,255,.06);--tfa-group-bg:rgba(255,255,255,.03);--tfa-hdr-bg:rgba(255,255,255,.025);--tfa-input-bg:rgba(255,255,255,.045);--tfa-input-focus-bg:rgba(255,255,255,.065);--tfa-btn-bg:rgba(255,255,255,.045);--tfa-btn-hover-bg:rgba(255,255,255,.085);--tfa-accent:#7c8cff;--tfa-accent-2:#5b6df4;--tfa-accent-rgb:124,140,255;--tfa-success:#34d399;--tfa-success-rgb:52,211,153;--tfa-warning:#fbbf24;--tfa-danger:#f87171;--tfa-danger-rgb:248,113,113;--tfa-skeleton-base:rgba(255,255,255,.05);--dock-tile-surface:#1c212b;--dock-accent-contrast:#fff;--tfa-radius-md:12px;--tfa-radius-lg:16px;--tfa-radius-xl:22px;}
        :host([data-theme="light"]){--tfa-backdrop-bg:rgba(220,225,234,.72);--tfa-panel-bg:rgba(255,255,255,.98);--tfa-panel-border:rgba(31,41,55,.12);--tfa-panel-shadow:0 28px 80px rgba(31,41,55,.18);--tfa-panel-glow:radial-gradient(circle at top,rgba(111,98,208,.09),transparent 42%);--tfa-text-primary:#202631;--tfa-text-secondary:#5f6977;--tfa-text-tertiary:#8993a1;--tfa-border-soft:rgba(31,41,55,.09);--tfa-border-medium:rgba(31,41,55,.15);--tfa-border-strong:rgba(31,41,55,.24);--tfa-card-bg:rgba(248,249,251,.98);--tfa-card-hover-bg:#f0f2f5;--tfa-group-bg:rgba(31,41,55,.035);--tfa-hdr-bg:rgba(248,249,251,.96);--tfa-input-bg:#f4f6f8;--tfa-input-focus-bg:#fff;--tfa-btn-bg:#f3f5f7;--tfa-btn-hover-bg:#e7eaf0;--tfa-accent:#6f62d0;--tfa-accent-2:#5f54c4;--tfa-accent-rgb:111,98,208;--tfa-skeleton-base:rgba(31,41,55,.07);--tfa-skeleton-shine:rgba(111,98,208,.15);--tfa-success:#25835f;--tfa-success-rgb:37,131,95;--tfa-danger:#ad4b5a;--tfa-danger-rgb:173,75,90;--tfa-warning:#a66f19;--dock-tile-surface:#fff;--dock-accent-contrast:#fff}
        :host{--tfa-overlay-gutter:clamp(24px,5vw,96px);--tfa-grid-columns:4}
        .overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .22s ease;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Microsoft YaHei','PingFang SC',sans-serif;color:var(--tfa-text-primary)}
        .overlay.show{opacity:1}
        .overlay.show{overscroll-behavior:none}
        .backdrop{position:absolute;inset:0;background:var(--tfa-backdrop-bg);backdrop-filter:blur(18px) saturate(1.18);-webkit-backdrop-filter:blur(18px) saturate(1.18)}
        .panel{position:relative;display:flex;flex-direction:column;width:calc(100vw - var(--tfa-overlay-gutter));height:calc(100vh - var(--tfa-overlay-gutter));max-width:none;max-height:none;background:var(--tfa-panel-bg);border:1px solid var(--tfa-panel-border);border-radius:var(--tfa-radius-xl);box-shadow:var(--tfa-panel-shadow);overflow:hidden;overscroll-behavior:contain;transform:translateY(22px) scale(.97);opacity:0;transition:transform .32s cubic-bezier(.2,.85,.25,1),opacity .24s ease}
        .panel[data-columns="4"]{--tfa-grid-columns:4}.panel[data-columns="5"]{--tfa-grid-columns:5}.panel[data-columns="6"]{--tfa-grid-columns:6}
        .panel::before{content:'';position:absolute;left:0;right:0;top:0;height:180px;background:var(--tfa-panel-glow);pointer-events:none}
        .overlay.show .panel{transform:translateY(0) scale(1);opacity:1}
        .hdr,.body,.ftr{position:relative;z-index:1}
        .hdr{display:flex;flex-direction:column;gap:14px;padding:18px 22px 16px;border-bottom:1px solid var(--tfa-border-soft);background:var(--tfa-hdr-bg)}
        .hdr-top,.hdr-bottom{display:flex;align-items:center;gap:12px}
        .hdr-top{justify-content:space-between}
        .hdr-meta{display:flex;align-items:flex-start;gap:14px;min-width:0;flex:1}
        .hdr-brand{display:flex;flex-direction:column;gap:4px;min-width:0}
        .hdr-kicker{font-size:11px;line-height:1;color:var(--tfa-text-tertiary);text-transform:uppercase;letter-spacing:.12em;font-weight:700}
        .hdr-title-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
        .hdr-title{font-size:18px;line-height:1.2;font-weight:700;color:var(--tfa-text-primary)}
        .hdr-subtitle{font-size:12px;line-height:1.45;color:var(--tfa-text-secondary)}
        .count{display:inline-flex;align-items:center;justify-content:center;min-height:26px;padding:0 10px;border-radius:999px;background:var(--tfa-card-bg);border:1px solid var(--tfa-border-soft);font-size:11.5px;font-weight:700;color:var(--tfa-text-secondary);white-space:nowrap}
        .hdr-tools{display:flex;align-items:center;gap:8px;flex-shrink:0}
        .search-wrap{position:relative;flex:1;min-width:180px}
        .search{width:100%;height:42px;padding:0 38px 0 42px;border-radius:12px;border:1px solid var(--tfa-border-soft);background:var(--tfa-input-bg);color:var(--tfa-text-primary);outline:none;font-size:13.5px}
        .search::placeholder{color:var(--tfa-text-tertiary)}
        .search-icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);width:16px;height:16px;stroke:var(--tfa-text-tertiary);pointer-events:none}
        .search-clear{position:absolute;right:10px;top:50%;transform:translateY(-50%);width:20px;height:20px;border:none;border-radius:999px;background:var(--tfa-btn-bg);color:var(--tfa-text-tertiary);display:flex;align-items:center;justify-content:center;padding:0}
        .actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
        .btn,.close{font-family:inherit}
        .btn{height:36px;padding:0 12px;border-radius:10px;border:1px solid var(--tfa-border-soft);background:var(--tfa-btn-bg);color:var(--tfa-text-primary);font-size:12.5px;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
        .btn.accent{background:linear-gradient(135deg,var(--tfa-accent),var(--tfa-accent-2));border-color:transparent;color:#fff;font-weight:700}
        .theme-btn{width:36px;padding:0;justify-content:center}
        .close{width:36px;height:36px;border:none;border-radius:10px;background:transparent;color:var(--tfa-text-tertiary);font-size:20px;display:flex;align-items:center;justify-content:center}
        .body{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;padding:24px}
        .ftr{display:flex;flex-wrap:wrap;gap:10px;padding:14px 22px;border-top:1px solid var(--tfa-border-soft);background:var(--tfa-hdr-bg);font-size:11px;color:var(--tfa-text-tertiary);align-items:center}
        .ftr-band{display:flex;align-items:center;gap:8px;min-width:0}
        .ftr-hints{justify-content:center}
        .ftr-meta{justify-content:flex-end}
        .hold-indicator{display:flex;align-items:center;gap:8px}
        .hold-bar{width:56px;height:4px;border-radius:999px;background:var(--tfa-border-medium);overflow:hidden}
        .hold-bar .fill{height:100%;width:0;background:linear-gradient(90deg,var(--tfa-accent),var(--tfa-accent-2))}
        .sticky-mode .panel::after{content:attr(data-sticky-label);position:absolute;top:16px;right:68px;padding:4px 8px;border-radius:999px;background:rgba(var(--tfa-accent-rgb),.12);border:1px solid rgba(var(--tfa-accent-rgb),.22);font-size:10px;font-weight:700;color:var(--tfa-accent)}
        .toast-container{position:fixed;left:50%;top:20px;transform:translateX(-50%);z-index:140;display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}
        .toast{display:flex;align-items:center;gap:8px;min-height:42px;padding:0 14px;background:var(--tfa-panel-bg);border:1px solid var(--tfa-panel-border);border-radius:14px;box-shadow:0 12px 36px rgba(0,0,0,.28);opacity:0;transform:translateY(16px) scale(.96);transition:opacity .2s ease,transform .2s cubic-bezier(.2,.85,.25,1);pointer-events:auto;white-space:nowrap;font-size:12.5px;font-weight:600}
        .toast.show{opacity:1;transform:translateY(0) scale(1)}
        .toast.hide{opacity:0;transform:translateY(-8px) scale(.96)}
        .toast-icon{font-size:14px;line-height:1}
        .empty{text-align:center;padding:84px 20px;color:var(--tfa-text-secondary);font-size:14px;display:flex;flex-direction:column;align-items:center;gap:6px}
        .empty .big{font-size:40px;opacity:.34}
        .empty-hint{font-size:12px;color:var(--tfa-text-tertiary)}
        kbd{background:var(--tfa-btn-bg);border:1px solid var(--tfa-border-soft);border-bottom-width:2px;border-radius:5px;padding:1px 5px;font-size:10px;font-weight:700;color:var(--tfa-text-secondary)}
        .tab-preview{position:absolute;width:380px;z-index:50;pointer-events:auto;opacity:0;transform:translateY(8px) scale(.96);transition:opacity .2s ease,transform .2s cubic-bezier(.2,.85,.25,1)}
        .tab-preview.show{opacity:1;transform:translateY(0) scale(1)}
        .preview-inner{background:var(--tfa-panel-bg);border:1px solid var(--tfa-panel-border);border-radius:16px;box-shadow:0 24px 64px rgba(0,0,0,.38);overflow:hidden}
        .preview-header{display:flex;align-items:center;gap:10px;padding:12px 14px 10px;border-bottom:1px solid var(--tfa-border-soft)}
        .preview-header-text{flex:1;min-width:0}.preview-favicon,.preview-favicon-fallback{width:20px;height:20px;border-radius:5px;flex-shrink:0}.preview-favicon{object-fit:contain;background:var(--tfa-skeleton-base)}.preview-favicon-fallback{display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;color:#fff}.preview-title{font-size:13px;font-weight:700;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.preview-url{font-size:11px;color:var(--tfa-text-tertiary);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-snapshot{width:100%;height:200px;background:rgba(6,10,20,.42);overflow:hidden;position:relative}.preview-screenshot{width:100%;height:100%;object-fit:contain;object-position:top center;display:block}.preview-snapshot.placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;background:linear-gradient(135deg,var(--dc,#4a4a6a),rgba(0,0,0,.52))}.preview-letter{font-size:46px;font-weight:800;color:rgba(255,255,255,.92)}.preview-domain{font-size:13px;color:rgba(255,255,255,.72);font-weight:600}.preview-loading{font-size:11px;color:rgba(255,255,255,.54)}.preview-footer{display:flex;flex-wrap:wrap;gap:6px;padding:10px 14px 12px}.preview-tag{font-size:10px;padding:2px 8px;border-radius:999px;background:var(--tfa-card-bg);color:var(--tfa-text-secondary);font-weight:700}
        .grid,.group-cards,.skeleton-grid{display:grid;grid-template-columns:repeat(var(--tfa-grid-columns),minmax(0,1fr));gap:11px}.card-title{display:block;min-height:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-tags:empty{display:none}.layout-controls,.density-control,.view-segment,.preview-toggle{display:flex;align-items:center;gap:8px}.layout-controls{margin-left:auto}.view-segment{border:1px solid var(--tfa-border-medium);border-radius:9px;overflow:hidden}.view-segment-btn{height:30px;padding:0 10px;border:0;background:var(--tfa-btn-bg);color:var(--tfa-text-secondary)}.view-segment-btn.active{color:var(--tfa-accent);background:rgba(var(--tfa-accent-rgb),.14)}.preview-toggle[hidden]{display:none}.card-preview-media{display:none}.panel[data-view-mode="card"] .card-preview-media{display:flex;aspect-ratio:16/9;width:100%;overflow:hidden;align-items:center;justify-content:center}.card-preview-screenshot{width:100%;height:100%;object-fit:cover;object-position:top center}.panel[data-view-mode="card"] .card{padding:0}.panel[data-view-mode="card"] .card-main{padding:11px 13px}
        @media (max-width:1199px){.panel[data-columns="6"]{--tfa-grid-columns:5}}@media (max-width:999px){.panel[data-columns="5"],.panel[data-columns="6"]{--tfa-grid-columns:4}}@media (max-width:839px){.panel[data-columns="4"],.panel[data-columns="5"],.panel[data-columns="6"]{--tfa-grid-columns:3}}@media (max-width:679px){.panel[data-columns="4"],.panel[data-columns="5"],.panel[data-columns="6"]{--tfa-grid-columns:2}.hdr-top,.hdr-bottom{flex-wrap:wrap;align-items:stretch}.hdr-tools,.actions{width:100%}.layout-controls{width:100%;margin-left:0;flex-wrap:wrap}.ftr-hints,.ftr-meta{justify-content:flex-start}.tab-preview{width:min(320px,calc(100vw - 32px))}}@media (max-width:479px){.panel[data-columns="4"],.panel[data-columns="5"],.panel[data-columns="6"]{--tfa-grid-columns:1}}
      </style>
      <style id="tfa-activation-fallback">${ACTIVATION_FALLBACK_CSS}</style>
      <div class="overlay" id="overlay">
        <div class="backdrop" id="backdrop"></div>
        <div class="panel" id="panel" data-columns="4" data-view-mode="hover" data-hover-preview="true" data-sticky-label="${tx("overlay.sticky", "\u5DF2\u56FA\u5B9A")}">
          <header class="hdr">
            <div class="hdr-top">
              <div class="hdr-meta">
                <div class="hdr-brand">
                  <div class="hdr-kicker">Workspace</div>
                  <div class="hdr-title-row">
                    <div class="hdr-title" data-i18n="overlay.title" data-i18n-fallback="\u9875\u7B7E\u5DE5\u4F5C\u53F0">${tx("overlay.title", "\u9875\u7B7E\u5DE5\u4F5C\u53F0")}</div>
                    <div class="count" id="count"></div>
                  </div>
                  <div class="hdr-subtitle" data-i18n="overlay.subtitle" data-i18n-fallback="\u641C\u7D22\u3001\u6574\u7406\u3001\u5206\u7EC4\u3001\u6062\u590D\u4E0E\u9884\u89C8\u90FD\u96C6\u4E2D\u5728\u8FD9\u91CC">${tx("overlay.subtitle", "\u641C\u7D22\u3001\u6574\u7406\u3001\u5206\u7EC4\u3001\u6062\u590D\u4E0E\u9884\u89C8\u90FD\u96C6\u4E2D\u5728\u8FD9\u91CC")}</div>
                </div>
              </div>
              <div class="hdr-tools">
                <button class="btn theme-btn" id="btnTheme" title="${tx("common.theme", "\u5207\u6362\u76AE\u80A4")}" data-i18n-title="common.theme" data-i18n-title-fallback="\u5207\u6362\u76AE\u80A4"><span class="ico">&#x1F3A8;</span></button>
                <button class="btn settings-tool-btn" id="btnSettings" aria-label="${tx("common.settings", "\u6253\u5F00\u8BBE\u7F6E")}" title="${tx("common.settings", "\u6253\u5F00\u8BBE\u7F6E")}" data-i18n-aria-label="common.settings" data-i18n-aria-label-fallback="\u6253\u5F00\u8BBE\u7F6E" data-i18n-title="common.settings" data-i18n-title-fallback="\u6253\u5F00\u8BBE\u7F6E">${SETTINGS_SVG}</button>
                <button class="btn settings-tool-btn member" id="btnMember" aria-label="${tx("overlay.membership", "\u4F1A\u5458\u72B6\u6001")}" title="${tx("overlay.activated", "\u5DF2\u6C38\u4E45\u6FC0\u6D3B")}" style="display:none;" data-i18n-aria-label="overlay.membership" data-i18n-aria-label-fallback="\u4F1A\u5458\u72B6\u6001" data-i18n-title="overlay.activated" data-i18n-title-fallback="\u5DF2\u6C38\u4E45\u6FC0\u6D3B">${MEMBER_SVG}</button>
                <button class="close" id="btnClose" title="${tx("overlay.close", "\u5173\u95ED\u6D6E\u5C42 (Esc)")}" data-i18n-title="overlay.close" data-i18n-title-fallback="\u5173\u95ED\u6D6E\u5C42 (Esc)">\xD7</button>
              </div>
            </div>
            <div class="hdr-bottom">
              <div class="search-wrap">
                ${SEARCH_SVG}
                <input id="search" class="search" placeholder="${tx("overlay.searchPlaceholder", "\u641C\u7D22\u9875\u7B7E\u6807\u9898\u3001\u57DF\u540D\u6216\u7F51\u5740")}" data-i18n-placeholder="overlay.searchPlaceholder" data-i18n-placeholder-fallback="\u641C\u7D22\u9875\u7B7E\u6807\u9898\u3001\u57DF\u540D\u6216\u7F51\u5740" autocomplete="off" spellcheck="false" />
                <button class="search-clear" id="searchClear" style="display:none;">&#x2715;</button>
              </div>
              <div class="actions">
                <button class="btn accent" id="btnNew" title="${tx("overlay.action.newTitle", "\u65B0\u5EFA\u9875\u7B7E\uFF08\u70ED\u95E8\u4E66\u7B7E\uFF09")}" data-i18n-title="overlay.action.newTitle" data-i18n-title-fallback="\u65B0\u5EFA\u9875\u7B7E\uFF08\u70ED\u95E8\u4E66\u7B7E\uFF09"><span class="ico">\uFF0B</span><span data-i18n="overlay.action.new" data-i18n-fallback="\u65B0\u5EFA">${tx("overlay.action.new", "\u65B0\u5EFA")}</span></button>
                <button class="btn" id="btnDomainGroup" title="${tx("overlay.action.groupDomainsTitle", "\u6309\u4E3B\u57DF\u540D\u4E00\u952E\u5206\u7EC4\u6240\u6709\u9875\u7B7E")}" data-i18n-title="overlay.action.groupDomainsTitle" data-i18n-title-fallback="\u6309\u4E3B\u57DF\u540D\u4E00\u952E\u5206\u7EC4\u6240\u6709\u9875\u7B7E"><span class="ico">&#x1F310;</span><span data-i18n="overlay.action.groupDomains" data-i18n-fallback="\u57DF\u540D\u5206\u7EC4">${tx("overlay.action.groupDomains", "\u57DF\u540D\u5206\u7EC4")}</span></button>
                <button class="btn" id="btnUngroupAll" title="${tx("overlay.action.ungroupAllTitle", "\u89E3\u6563\u6240\u6709\u5206\u7EC4")}" data-i18n-title="overlay.action.ungroupAllTitle" data-i18n-title-fallback="\u89E3\u6563\u6240\u6709\u5206\u7EC4"><span class="ico">&#x26D3;</span><span data-i18n="overlay.action.ungroupAll" data-i18n-fallback="\u89E3\u7EC4">${tx("overlay.action.ungroupAll", "\u89E3\u7EC4")}</span></button>
                <button class="btn" id="btnTrash" title="${tx("overlay.action.recycleTitle", "\u67E5\u770B\u56DE\u6536\u7AD9")}" data-i18n-title="overlay.action.recycleTitle" data-i18n-title-fallback="\u67E5\u770B\u56DE\u6536\u7AD9"><span class="ico">&#x267B;</span><span data-i18n="overlay.action.recycle" data-i18n-fallback="\u56DE\u6536\u7AD9">${tx("overlay.action.recycle", "\u56DE\u6536\u7AD9")}</span></button>
                <button class="btn" id="btnUndo" title="${tx("overlay.action.undoTitle", "\u5173\u95ED\u56DE\u64A4\uFF08\u6062\u590D\u6700\u8FD1\u4E00\u4E2A\uFF09")}" data-i18n-title="overlay.action.undoTitle" data-i18n-title-fallback="\u5173\u95ED\u56DE\u64A4\uFF08\u6062\u590D\u6700\u8FD1\u4E00\u4E2A\uFF09"><span class="ico">\u21B6</span><span data-i18n="overlay.action.undo" data-i18n-fallback="\u56DE\u64A4">${tx("overlay.action.undo", "\u56DE\u64A4")}</span></button>
              </div>
            </div>
          </header>
          <div class="body" id="body"></div>
          <footer class="ftr" id="footer">
            <div class="ftr-band">
              <span><kbd>Esc</kbd> <span data-i18n="overlay.footer.escapeClose" data-i18n-fallback="\u5173\u95ED">${tx("overlay.footer.escapeClose", "\u5173\u95ED")}</span></span>
              <span data-i18n="overlay.footer.holdOpen" data-i18n-fallback="\u6309\u4F4F\u5FEB\u6377\u952E\u5524\u8D77">${tx("overlay.footer.holdOpen", "\u6309\u4F4F\u5FEB\u6377\u952E\u5524\u8D77")}</span>
              <span><span data-i18n="overlay.footer.stickyBefore" data-i18n-fallback="\u8D85\u8FC7">${tx("overlay.footer.stickyBefore", "\u8D85\u8FC7")}</span> <span id="holdSec">2</span> <span data-i18n="overlay.footer.stickyAfter" data-i18n-fallback="\u79D2\u677E\u5F00\u4FDD\u6301">${tx("overlay.footer.stickyAfter", "\u79D2\u677E\u5F00\u4FDD\u6301")}</span></span>
            </div>
            <div class="ftr-band hold-indicator" id="holdWrap" style="display:none;">
              <span data-i18n="overlay.footer.holdDuration" data-i18n-fallback="\u6309\u4F4F\u65F6\u957F">${tx("overlay.footer.holdDuration", "\u6309\u4F4F\u65F6\u957F")}</span>
              <div class="hold-bar"><div class="fill" id="holdFill"></div></div>
            </div>
            <div class="ftr-band ftr-hints" data-i18n="overlay.footer.hints" data-i18n-fallback="\u70B9\u51FB\u5207\u6362 \xB7 \u60AC\u505C\u9884\u89C8 \xB7 \u62D6\u52A8\u6392\u5E8F \xB7 \u53F3\u952E\u591A\u9009">${tx("overlay.footer.hints", "\u70B9\u51FB\u5207\u6362 \xB7 \u60AC\u505C\u9884\u89C8 \xB7 \u62D6\u52A8\u6392\u5E8F \xB7 \u53F3\u952E\u591A\u9009")}</div>
            <div class="layout-controls" id="layoutControls" aria-label="${tx("overlay.layout.aria", "\u9875\u7B7E\u5E03\u5C40\u8BBE\u7F6E")}" data-i18n-aria-label="overlay.layout.aria" data-i18n-aria-label-fallback="\u9875\u7B7E\u5E03\u5C40\u8BBE\u7F6E">
              <label class="density-control" for="columnRange">
                <span class="control-label" data-i18n="overlay.layout.perRow" data-i18n-fallback="\u6BCF\u884C">${tx("overlay.layout.perRow", "\u6BCF\u884C")}</span>
                <input id="columnRange" class="density-range" type="range" min="4" max="6" step="1" value="4" aria-label="${tx("overlay.layout.perRowAria", "\u6BCF\u884C\u9875\u7B7E\u6570\u91CF")}" data-i18n-aria-label="overlay.layout.perRowAria" data-i18n-aria-label-fallback="\u6BCF\u884C\u9875\u7B7E\u6570\u91CF" />
                <output id="columnValue" class="density-value" for="columnRange">${tx("overlay.layout.columns", "4\u5217", { count: 4 })}</output>
              </label>
              <div class="view-segment" role="group" aria-label="${tx("overlay.layout.viewAria", "\u9875\u7B7E\u89C6\u56FE")}" data-i18n-aria-label="overlay.layout.viewAria" data-i18n-aria-label-fallback="\u9875\u7B7E\u89C6\u56FE">
                <button class="view-segment-btn active" type="button" data-view-mode="hover" aria-pressed="true" data-i18n="overlay.layout.hover" data-i18n-fallback="\u60AC\u6D6E">${tx("overlay.layout.hover", "\u60AC\u6D6E")}</button>
                <button class="view-segment-btn" type="button" data-view-mode="card" aria-pressed="false" data-i18n="overlay.layout.card" data-i18n-fallback="\u5361\u7247">${tx("overlay.layout.card", "\u5361\u7247")}</button>
              </div>
              <button class="preview-toggle" id="hoverPreviewToggle" type="button" role="switch" aria-checked="true">
                <span class="toggle-track" aria-hidden="true"><span class="toggle-thumb"></span></span>
                <span data-i18n="overlay.layout.hoverPreview" data-i18n-fallback="\u60AC\u505C\u9884\u89C8">${tx("overlay.layout.hoverPreview", "\u60AC\u505C\u9884\u89C8")}</span>
              </button>
            </div>
            <div class="ftr-band ftr-meta"><span id="ftrVersion">v${SCRIPT_VERSION} \xB7 <span id="ftrTheme">${tx("theme.system", "\u8DDF\u968F\u7CFB\u7EDF")}</span></span></div>
          </footer>
        </div>
        <div class="select-bar" id="selectBar">
          <span class="sel-count" id="selCount" data-i18n="overlay.selectedNone" data-i18n-fallback="\u5DF2\u9009 0">${tx("overlay.selectedNone", "\u5DF2\u9009 0")}</span>
          <button class="btn accent" id="btnGroup" title="${tx("overlay.selection.groupTitle", "\u5C06\u9009\u4E2D\u9875\u7B7E\u5F52\u5165\u65B0\u5206\u7EC4")}" data-i18n-title="overlay.selection.groupTitle" data-i18n-title-fallback="\u5C06\u9009\u4E2D\u9875\u7B7E\u5F52\u5165\u65B0\u5206\u7EC4" data-i18n="overlay.selection.group" data-i18n-fallback="\u5206\u7EC4\u9009\u4E2D">${tx("overlay.selection.group", "\u5206\u7EC4\u9009\u4E2D")}</button>
          <button class="btn" id="btnCloseSelected" title="${tx("overlay.selection.closeTitle", "\u6279\u91CF\u5173\u95ED\u9009\u4E2D")}" data-i18n-title="overlay.selection.closeTitle" data-i18n-title-fallback="\u6279\u91CF\u5173\u95ED\u9009\u4E2D" data-i18n="overlay.selection.close" data-i18n-fallback="\u6279\u91CF\u5173\u95ED">${tx("overlay.selection.close", "\u6279\u91CF\u5173\u95ED")}</button>
          <button class="btn" id="btnClearSel" title="${tx("overlay.selection.clearTitle", "\u53D6\u6D88\u9009\u62E9")}" data-i18n-title="overlay.selection.clearTitle" data-i18n-title-fallback="\u53D6\u6D88\u9009\u62E9" data-i18n="overlay.selection.clear" data-i18n-fallback="\u53D6\u6D88">${tx("overlay.selection.clear", "\u53D6\u6D88")}</button>
        </div>
        <div class="tab-preview" id="tabPreview" style="display:none"></div>
      </div>
      <div class="toast-container" id="toastContainer" aria-live="polite" aria-atomic="true"></div>
      <div class="web-dock-shell" id="webDockShell" hidden data-auto-hide="true" data-expanded="false" data-suspended="false">
        <button class="web-dock-trigger" id="webDockTrigger" type="button" aria-label="${tx("dock.expand", "\u5C55\u5F00\u7F51\u9875\u62D3\u5C55\u575E")}" data-i18n-aria-label="dock.expand" data-i18n-aria-label-fallback="\u5C55\u5F00\u7F51\u9875\u62D3\u5C55\u575E"></button>
        <nav class="web-dock" aria-label="${tx("dock.label", "\u7F51\u9875\u62D3\u5C55\u575E")}" data-i18n-aria-label="dock.label" data-i18n-aria-label-fallback="\u7F51\u9875\u62D3\u5C55\u575E">
          <button class="web-dock-control web-dock-add-control" id="webDockAdd" type="button" aria-label="${tx("dock.addSite", "\u65B0\u589E\u7F51\u7AD9")}" data-i18n-aria-label="dock.addSite" data-i18n-aria-label-fallback="\u65B0\u589E\u7F51\u7AD9">
            <span class="web-dock-control-icon" aria-hidden="true" data-icon="tabler:circle-plus-2"><svg viewBox="0 0 24 24"><path d="M20.985 12.522a9 9 0 1 0 -8.475 8.464"/><path d="M16 19h6"/><path d="M19 16v6"/></svg></span>
            <span class="web-dock-control-label" data-i18n="dock.addSite" data-i18n-fallback="\u65B0\u589E\u7F51\u7AD9">${tx("dock.addSite", "\u65B0\u589E\u7F51\u7AD9")}</span>
          </button>
          <button class="web-dock-control web-dock-search-control" id="webDockSearch" type="button" aria-label="${tx("dock.search", "\u7F51\u9875\u641C\u7D22")}" data-i18n-aria-label="dock.search" data-i18n-aria-label-fallback="\u7F51\u9875\u641C\u7D22">
            <span class="web-dock-control-icon" aria-hidden="true" data-icon="tabler:search"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M20 20l-4 -4"/></svg></span>
            <span class="web-dock-control-label" data-i18n="dock.search" data-i18n-fallback="\u7F51\u9875\u641C\u7D22">${tx("dock.search", "\u7F51\u9875\u641C\u7D22")}</span>
          </button>
          <div class="web-dock-track" id="webDockTrack"></div>
          <button class="web-dock-control web-dock-settings-control" id="webDockSettings" type="button" aria-label="${tx("dock.settings", "\u7F51\u9875\u62D3\u5C55\u575E\u8BBE\u7F6E")}" data-i18n-aria-label="dock.settings" data-i18n-aria-label-fallback="\u7F51\u9875\u62D3\u5C55\u575E\u8BBE\u7F6E">
            <span class="web-dock-control-icon" aria-hidden="true" data-icon="tabler:settings"><svg viewBox="0 0 24 24"><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c.996 .608 2.296 .07 2.572 -1.065z"/><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"/></svg></span>
            <span class="web-dock-control-label" data-i18n="dock.settingsShort" data-i18n-fallback="\u62D3\u5C55\u575E\u8BBE\u7F6E">${tx("dock.settingsShort", "\u62D3\u5C55\u575E\u8BBE\u7F6E")}</span>
          </button>
          <button class="web-dock-control web-dock-recent-control" id="webDockRecent" type="button" aria-label="${tx("dock.recent", "\u6700\u8FD1\u5173\u95ED")}" data-i18n-aria-label="dock.recent" data-i18n-aria-label-fallback="\u6700\u8FD1\u5173\u95ED" aria-expanded="false" aria-controls="webDockRecentPanel">
            <span class="web-dock-control-icon" aria-hidden="true" data-icon="tabler:trash"><svg viewBox="0 0 24 24"><path d="M4 7h16"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M5 7l1 14h12l1-14"/><path d="M9 7V4h6v3"/></svg></span>
            <span class="web-dock-control-label" data-i18n="dock.recent" data-i18n-fallback="\u6700\u8FD1\u5173\u95ED">${tx("dock.recent", "\u6700\u8FD1\u5173\u95ED")}</span>
          </button>
        </nav>
        <section class="web-dock-recent-panel" id="webDockRecentPanel" role="region" aria-label="${tx("dock.recentSites", "\u6700\u8FD1\u5173\u95ED\u7684\u7F51\u7AD9")}" data-i18n-aria-label="dock.recentSites" data-i18n-aria-label-fallback="\u6700\u8FD1\u5173\u95ED\u7684\u7F51\u7AD9" data-columns="5" data-visible-rows="3" hidden>
          <header class="web-dock-recent-header"><strong data-i18n="dock.recent" data-i18n-fallback="\u6700\u8FD1\u5173\u95ED">${tx("dock.recent", "\u6700\u8FD1\u5173\u95ED")}</strong><span id="webDockRecentCount">0</span></header>
          <div class="web-dock-recent-status" id="webDockRecentStatus" role="status" data-i18n="dock.recentLoading" data-i18n-fallback="\u6B63\u5728\u8BFB\u53D6\u6700\u8FD1\u5173\u95ED\u2026">${tx("dock.recentLoading", "\u6B63\u5728\u8BFB\u53D6\u6700\u8FD1\u5173\u95ED\u2026")}</div>
          <div class="web-dock-recent-list" id="webDockRecentList" hidden></div>
        </section>
      </div>
    `;
        }
        return Object.freeze({ buildOverlay, localizeOverlay });
      });
    }
  });

  // src/content/v2-workbench-template.js
  var require_v2_workbench_template = __commonJS({
    "src/content/v2-workbench-template.js"(exports, module) {
      (function attachV2WorkbenchTemplate(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchTemplate = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchTemplate() {
        "use strict";
        const WORKBENCH_CSS = `
    .tfa-v2-workbench{--v2-bg:#f4f6f8;--v2-panel:#fff;--v2-header:#fafbfc;--v2-soft:#f6f8fa;--v2-card:#fff;--v2-container:#f6f8fa;--v2-container-head:#f6f8fa;--v2-line:#dce1e8;--v2-line-strong:#cdd4de;--v2-text:#202631;--v2-muted:#66717f;--v2-faint:#8b95a2;--v2-accent:#6f62d0;--v2-accent-soft:#e8e4ff;--v2-danger:#ad4b5a;--v2-shadow:0 34px 94px rgba(31,38,49,.28);position:relative;width:100%;height:100%;min-height:560px;display:grid;grid-template-rows:58px minmax(0,1fr) 34px;overflow:hidden;border:1px solid rgba(255,255,255,.35);border-radius:15px;background:var(--v2-panel);box-shadow:var(--v2-shadow);color:var(--v2-text);font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei","PingFang SC",sans-serif}
    .tfa-v2-workbench[data-theme="dark"]{--v2-bg:#0d1116;--v2-panel:#11151b;--v2-header:#0e1217;--v2-soft:#171c23;--v2-card:#191e25;--v2-container:#151a20;--v2-container-head:#181d24;--v2-line:#303844;--v2-line-strong:#3b4451;--v2-text:#eef1f4;--v2-muted:#9aa3af;--v2-faint:#737d8a;--v2-accent:#8174e7;--v2-accent-soft:#29253e;--v2-danger:#e39aa5;--v2-shadow:0 34px 94px rgba(0,0,0,.6)}
    :host([data-tfa-surface="newtab"]) [data-v2-action="close"]{display:none}
    .tfa-v2-workbench *{box-sizing:border-box}.tfa-v2-workbench button,.tfa-v2-workbench input,.tfa-v2-workbench select{font:inherit}.tfa-v2-workbench button{cursor:pointer}.tfa-v2-header{display:grid;grid-template-columns:minmax(150px,1fr) auto minmax(320px,1fr);align-items:center;gap:14px;padding:0 14px 0 17px;border-bottom:1px solid var(--v2-line);background:var(--v2-header)}
    .tfa-v2-brand{display:flex;align-items:center;gap:10px;min-width:0}.tfa-v2-brand-mark{width:32px;height:32px;display:flex;align-items:flex-end;justify-content:center;gap:3px;padding:7px;border-radius:9px;background:linear-gradient(145deg,#9486fb,#695bd9);box-shadow:0 7px 18px rgba(105,91,217,.25)}.tfa-v2-brand-mark i{width:4px;border-radius:3px;background:#fff}.tfa-v2-brand-mark i:nth-child(1){height:9px}.tfa-v2-brand-mark i:nth-child(2){height:17px}.tfa-v2-brand-mark i:nth-child(3){height:12px}.tfa-v2-brand-copy{min-width:0;display:grid}.tfa-v2-brand-copy strong{font-size:14px}.tfa-v2-brand-copy small{overflow:hidden;color:var(--v2-faint);font-size:10px;text-overflow:ellipsis;white-space:nowrap}
    .tfa-v2-layout{display:flex;padding:3px;border:1px solid var(--v2-line-strong);border-radius:9px;background:var(--v2-soft)}.tfa-v2-layout button{height:32px;display:flex;align-items:center;gap:6px;padding:0 11px;border:0;border-radius:7px;color:var(--v2-muted);background:transparent}.tfa-v2-layout button:hover{color:var(--v2-text);background:color-mix(in srgb,var(--v2-soft) 70%,var(--v2-line))}.tfa-v2-layout button.is-active{color:var(--v2-text);background:var(--v2-accent-soft);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--v2-accent) 35%,transparent)}.tfa-v2-layout button:focus-visible,.tfa-v2-icon-button:focus-visible,.tfa-v2-tab:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px}
    .tfa-v2-header-actions{display:flex;justify-content:flex-end;gap:2px}.tfa-v2-icon-button{width:34px;height:34px;display:grid;place-items:center;border:0;border-radius:8px;color:var(--v2-muted);background:transparent}.tfa-v2-icon-button:hover{color:var(--v2-text);background:var(--v2-soft)}.tfa-v2-icon{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
    .tfa-v2-header-search{position:relative;min-width:0;width:100%;max-width:640px;justify-self:center}.tfa-v2-header-search .tfa-v2-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--v2-faint);pointer-events:none}.tfa-v2-search{width:100%;height:36px;padding:0 58px 0 36px;border:1px solid var(--v2-line-strong);border-radius:9px;outline:0;color:var(--v2-text);background:var(--v2-soft)}.tfa-v2-search:focus{border-color:var(--v2-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--v2-accent) 15%,transparent)}.tfa-v2-search::placeholder{color:var(--v2-faint)}.tfa-v2-search-shortcut{position:absolute;right:9px;top:50%;transform:translateY(-50%);padding:2px 5px;border:1px solid var(--v2-line-strong);border-radius:5px;color:var(--v2-muted);background:var(--v2-panel);font-size:9px;pointer-events:none}.tfa-v2-workbench[data-layout="recycle"] .tfa-v2-header-search{visibility:hidden}
    .tfa-v2-workspace{--v2-browser-width:50%;min-height:0;display:grid;grid-template-columns:minmax(320px,var(--v2-browser-width)) 7px minmax(380px,1fr);overflow:hidden;background:var(--v2-bg)}.tfa-v2-workspace[data-layout="browser"]{grid-template-columns:minmax(0,1fr) 30px}.tfa-v2-workspace[data-layout="browser"] .tfa-v2-task-pane{display:none}.tfa-v2-workspace[data-layout="tasks"]{grid-template-columns:30px minmax(0,1fr)}.tfa-v2-workspace[data-layout="tasks"] .tfa-v2-browser-pane{display:none}.tfa-v2-recycle-pane{display:none}.tfa-v2-workspace[data-layout="recycle"]{grid-template-columns:1fr}.tfa-v2-workspace[data-layout="recycle"] .tfa-v2-browser-pane,.tfa-v2-workspace[data-layout="recycle"] .tfa-v2-task-pane,.tfa-v2-workspace[data-layout="recycle"] .tfa-v2-divider{display:none}.tfa-v2-workspace[data-layout="recycle"] .tfa-v2-recycle-pane{display:grid}.tfa-v2-workspace>[hidden]{display:none!important}.tfa-v2-divider{position:relative;border:0;outline:0;cursor:col-resize;touch-action:none;background:var(--v2-line)}.tfa-v2-workspace[data-layout="browser"] .tfa-v2-divider,.tfa-v2-workspace[data-layout="tasks"] .tfa-v2-divider{cursor:default}.tfa-v2-divider:before{content:"";position:absolute;inset:0 -4px}.tfa-v2-divider:after{content:"";position:absolute;left:2px;top:calc(50% - 19px);width:3px;height:38px;border-radius:4px;background:var(--v2-faint)}.tfa-v2-workspace[data-layout="browser"] .tfa-v2-divider:after,.tfa-v2-workspace[data-layout="tasks"] .tfa-v2-divider:after{display:none}.tfa-v2-divider:hover,.tfa-v2-divider.is-dragging{background:color-mix(in srgb,var(--v2-accent) 35%,var(--v2-line))}.tfa-v2-divider:hover:after,.tfa-v2-divider.is-dragging:after,.tfa-v2-divider:focus-visible:after{background:var(--v2-accent)}.tfa-v2-divider:focus-visible{box-shadow:0 0 0 2px var(--v2-accent)}.tfa-v2-divider-controls{position:absolute;z-index:5;left:50%;top:50%;display:grid;gap:4px;transform:translate(-50%,-50%)}.tfa-v2-divider-action{width:24px;height:24px;display:grid;place-items:center;padding:0;border:1px solid var(--v2-line-strong);border-radius:7px;color:var(--v2-muted);background:var(--v2-panel);box-shadow:0 4px 12px rgba(23,28,40,.12)}.tfa-v2-divider-action:hover{color:var(--v2-text);border-color:color-mix(in srgb,var(--v2-accent) 50%,var(--v2-line-strong));background:var(--v2-accent-soft)}.tfa-v2-divider-action:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px}.tfa-v2-divider-action .tfa-v2-icon{width:13px;height:13px}.tfa-v2-divider-action[hidden]{display:none}
    .tfa-v2-pane{min-width:0;min-height:0;display:grid;grid-template-rows:48px minmax(0,1fr);overflow:hidden;background:var(--v2-panel)}.tfa-v2-task-pane{grid-template-rows:48px 0 minmax(0,1fr)}.tfa-v2-task-pane:has(>[data-v2-ai-adjustment-host]>.tfa-v2-ai-adjustment){grid-template-rows:48px max-content minmax(0,1fr)}.tfa-v2-task-pane>[data-v2-ai-adjustment-host]{grid-row:2;min-height:0;overflow:hidden}.tfa-v2-task-pane>[data-v2-ai-adjustment-host]:empty{display:none}.tfa-v2-task-pane>[data-v2-task-content]{grid-row:3}.tfa-v2-pane-header{display:flex;align-items:center;gap:8px;padding:0 10px;border-bottom:1px solid var(--v2-line);background:var(--v2-header)}.tfa-v2-pane-title{display:flex;align-items:center;gap:7px;min-width:0}.tfa-v2-pane-title strong{font-size:14px}.tfa-v2-count{min-width:20px;padding:2px 6px;border-radius:9px;color:#fff;background:#39324f;font-size:9px;text-align:center}.tfa-v2-task-undo{width:27px;height:27px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:1px solid var(--v2-line-strong);border-radius:7px;color:var(--v2-muted);background:transparent}.tfa-v2-task-undo .tfa-v2-icon{width:14px;height:14px}.tfa-v2-task-undo:hover:not(:disabled){color:var(--v2-text);border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong));background:var(--v2-soft)}.tfa-v2-task-undo:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px}.tfa-v2-task-undo:disabled{cursor:default;opacity:.38}.tfa-v2-filters{min-width:0;display:flex;align-items:center;gap:5px;margin-left:auto}.tfa-v2-segments{display:flex;gap:2px;padding:2px;border:1px solid var(--v2-line-strong);border-radius:7px;background:var(--v2-soft)}.tfa-v2-segments button{height:25px;padding:0 7px;border:0;border-radius:5px;color:var(--v2-muted);background:transparent;font-size:9px}.tfa-v2-segments button.is-active{color:var(--v2-text);background:var(--v2-panel)}.tfa-v2-select{height:29px;min-width:88px;padding:0 24px 0 8px;border:1px solid var(--v2-line-strong);border-radius:7px;color:var(--v2-muted);background:var(--v2-soft)}.tfa-v2-new-task{height:29px;display:flex;align-items:center;gap:4px;padding:0 9px;border:0;border-radius:7px;color:#fff;background:var(--v2-accent);white-space:nowrap}.tfa-v2-new-task .tfa-v2-icon{width:13px;height:13px}
    .tfa-v2-scroll{min-height:0;overflow:auto;padding:9px 9px 44px;scrollbar-width:thin;scrollbar-color:transparent transparent}.tfa-v2-scroll.is-scrolling{scrollbar-color:var(--v2-faint) transparent}.tfa-v2-scroll::-webkit-scrollbar-thumb,.tfa-v2-inbox-pages::-webkit-scrollbar-thumb{background:transparent}.tfa-v2-scroll.is-scrolling::-webkit-scrollbar-thumb,.tfa-v2-inbox-pages.is-scrolling::-webkit-scrollbar-thumb{background:var(--v2-faint)}.tfa-v2-window{margin-bottom:10px}.tfa-v2-window-title{height:34px;display:flex;align-items:center;gap:7px;padding:0 6px;color:var(--v2-muted);font-size:11px;font-weight:700}.tfa-v2-window-title small{margin-left:auto;color:var(--v2-faint);font-weight:500}.tfa-v2-tab-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:7px}.tfa-v2-tab{position:relative;min-width:0;min-height:68px;display:flex;align-items:center;gap:11px;padding:9px 42px 9px 10px;border:1px solid var(--v2-line);border-radius:9px;color:var(--v2-text);background:var(--v2-card);text-align:left;transition:transform .18s cubic-bezier(.16,1,.3,1),opacity .14s ease,border-color .15s ease,background-color .15s ease}.tfa-v2-tab:hover{border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line));background:color-mix(in srgb,var(--v2-accent) 5%,var(--v2-card))}.tfa-v2-tab.is-active{border-color:color-mix(in srgb,var(--v2-accent) 68%,var(--v2-line));background:color-mix(in srgb,var(--v2-accent) 11%,var(--v2-card));box-shadow:0 0 0 2px color-mix(in srgb,var(--v2-accent) 12%,transparent)}.tfa-v2-site-icon{position:relative;width:36px;height:36px;flex:0 0 auto;display:grid;place-items:center;overflow:hidden;border-radius:9px;color:#fff;background:var(--site-color,#6f62d0);font-weight:750}.tfa-v2-site-icon.has-image{background:#fff}.tfa-v2-site-icon b{font-size:13px}.tfa-v2-site-icon img{position:absolute;inset:0;width:100%;height:100%;padding:6px;object-fit:contain;background:#fff}.tfa-v2-tab-copy{min-width:0;display:grid;gap:4px}.tfa-v2-tab-copy strong,.tfa-v2-tab-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-tab-copy strong{font-size:11px}.tfa-v2-tab-copy small{color:var(--v2-faint);font-size:9px}.tfa-v2-tab-flags{display:flex;gap:4px}.tfa-v2-pill{padding:1px 5px;border-radius:5px;color:var(--v2-muted);background:var(--v2-panel);font-size:8px}.tfa-v2-tab-close{position:absolute;right:8px;top:8px;width:25px;height:25px;border:0;border-radius:6px;color:var(--v2-faint);background:transparent}.tfa-v2-tab-close:hover{color:var(--v2-danger);background:color-mix(in srgb,var(--v2-danger) 10%,transparent)}
    .tfa-v2-browser-pane .tfa-v2-tab-grid{grid-template-columns:repeat(var(--v2-browser-columns),minmax(0,1fr))}.tfa-v2-browser-columns{min-width:150px;display:flex;align-items:center;justify-content:flex-end;gap:6px;color:var(--v2-faint);font-size:9px;font-weight:500}.tfa-v2-browser-columns input{width:90px;accent-color:var(--v2-accent)}.tfa-v2-browser-columns output{min-width:24px;color:var(--v2-muted);font-variant-numeric:tabular-nums}.tfa-v2-browser-columns:focus-within{color:var(--v2-text)}
    .tfa-v2-tab{padding-right:70px}.tfa-v2-tab[draggable="true"]{cursor:grab}.tfa-v2-tab.is-dragging{opacity:.55;cursor:grabbing}.tfa-v2-tab-main{min-width:0;flex:1;display:flex;align-items:center;gap:11px;padding:0;border:0;color:inherit;background:transparent;text-align:left}.tfa-v2-tab-main:focus-visible{outline:2px solid var(--v2-accent);outline-offset:3px;border-radius:5px}.tfa-v2-tab-actions{position:absolute;right:6px;top:6px;display:flex;gap:2px;opacity:0;pointer-events:none;transform:translateY(2px);transition:opacity .15s ease,transform .15s ease}.tfa-v2-tab:hover .tfa-v2-tab-actions,.tfa-v2-tab:focus-within .tfa-v2-tab-actions,.tfa-v2-tab.has-open-menu .tfa-v2-tab-actions{opacity:1;pointer-events:auto;transform:none}.tfa-v2-tab-action{width:25px;height:25px;display:grid;place-items:center;padding:0;border:0;border-radius:6px;color:var(--v2-faint);background:color-mix(in srgb,var(--v2-panel) 88%,transparent)}.tfa-v2-tab-action:hover{color:var(--v2-text);background:var(--v2-panel)}.tfa-v2-tab-action.is-danger:hover{color:var(--v2-danger);background:color-mix(in srgb,var(--v2-danger) 10%,var(--v2-panel))}.tfa-v2-tab-action:focus-visible,.tfa-v2-task-action:focus-visible{outline:2px solid var(--v2-accent);outline-offset:1px}.tfa-v2-tab-action .tfa-v2-icon{width:14px;height:14px}
    .tfa-v2-task-list{display:grid;gap:8px}.tfa-v2-task{overflow:hidden;border:1px solid color-mix(in srgb,var(--task-color,#6f62d0) 32%,var(--v2-line));border-left:3px solid var(--task-color,#6f62d0);border-radius:10px;background:color-mix(in srgb,var(--task-color,#6f62d0) 6%,var(--v2-container))}.tfa-v2-task-header{min-height:48px;display:flex;align-items:center;gap:8px;padding:7px 9px;border-bottom:1px solid color-mix(in srgb,var(--task-color,#6f62d0) 18%,var(--v2-line));background:color-mix(in srgb,var(--task-color,#6f62d0) 5%,var(--v2-container-head))}.tfa-v2-task-title{min-width:0;display:grid;gap:3px}.tfa-v2-task-title strong{overflow:hidden;font-size:13px;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-task-title small{color:var(--v2-faint);font-size:9px}.tfa-v2-task-tags{display:flex;gap:5px;margin-left:auto}.tfa-v2-task-tags span{height:22px;display:flex;align-items:center;padding:0 7px;border:1px solid var(--v2-line-strong);border-radius:6px;color:var(--v2-muted);font-size:9px}.tfa-v2-task-pages{padding:7px;background:transparent}.tfa-v2-task-pages .tfa-v2-tab-grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr))}.tfa-v2-task-pages .tfa-v2-tab{min-height:68px}
    .tfa-v2-task:not(:has(.tfa-v2-task-pages)) .tfa-v2-task-header{min-height:68px;border-bottom:0}
    .tfa-v2-task-content-inner{min-height:100%;display:flex;flex-direction:column}.tfa-v2-inbox{--v2-inbox:#d69b45;position:sticky;z-index:8;bottom:0;overflow:hidden;margin-top:10px;border:1px solid var(--v2-line);border-left:3px solid var(--v2-inbox);border-radius:10px;background:var(--v2-container);box-shadow:none}.tfa-v2-inbox-header{min-height:45px;display:flex;align-items:center;gap:8px;padding:7px 9px;background:var(--v2-container-head)}.tfa-v2-inbox-marker{width:7px;height:7px;flex:0 0 auto;border-radius:3px;background:var(--v2-inbox)}.tfa-v2-inbox-header strong{font-size:13px}.tfa-v2-inbox-header small{margin-left:auto;color:var(--v2-faint);font-size:9px}.tfa-v2-inbox-pages{padding:7px;border-top:1px solid var(--v2-line);background:var(--v2-container);scrollbar-width:thin;scrollbar-color:transparent transparent}.tfa-v2-inbox-pages.is-scrolling{scrollbar-color:var(--v2-faint) transparent}.tfa-v2-inbox-pages .tfa-v2-tab-grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr))}.tfa-v2-inbox-pages .tfa-v2-tab{min-height:68px}.tfa-v2-inbox:not(.is-expanded) .tfa-v2-inbox-pages .tfa-v2-tab-grid{max-height:68px;overflow:hidden}.tfa-v2-inbox-footer{height:28px;border-top:1px solid var(--v2-line)}.tfa-v2-inbox-footer[hidden]{display:none}.tfa-v2-inbox-footer button{width:100%;height:27px;display:grid;place-items:center;padding:0;border:0;color:var(--v2-faint);background:transparent}.tfa-v2-inbox-footer button:hover{color:var(--v2-text);background:color-mix(in srgb,var(--v2-inbox) 7%,transparent)}.tfa-v2-inbox-footer button:focus-visible{outline:2px solid var(--v2-accent);outline-offset:-3px}.tfa-v2-inbox-footer .tfa-v2-icon{width:16px;height:16px}
    .tfa-v2-task{transition:border-color .15s ease,background .15s ease,box-shadow .15s ease}.tfa-v2-task.is-drop-target{border-color:var(--v2-accent);border-left-color:var(--v2-accent);background:color-mix(in srgb,var(--v2-accent) 10%,var(--v2-soft))}.tfa-v2-task.is-task-drop-before{box-shadow:inset 0 3px var(--v2-accent)}.tfa-v2-task.is-task-drop-after{box-shadow:inset 0 -3px var(--v2-accent)}.tfa-v2-task.is-task-dragging{opacity:.48}.tfa-v2-task.has-open-menu{position:relative;z-index:20;overflow:visible}.tfa-v2-task-drag-handle{width:22px;height:28px;flex:0 0 auto;display:grid;place-items:center;padding:0;border:0;border-radius:5px;color:var(--v2-faint);background:transparent;cursor:grab;opacity:0;pointer-events:none}.tfa-v2-task:hover .tfa-v2-task-drag-handle,.tfa-v2-task:focus-within .tfa-v2-task-drag-handle{opacity:1;pointer-events:auto}.tfa-v2-task-drag-handle:hover:not(:disabled){color:var(--v2-text);background:var(--v2-panel)}.tfa-v2-task-drag-handle:focus-visible{opacity:1;outline:2px solid var(--v2-accent);outline-offset:1px}.tfa-v2-task-drag-handle:disabled{cursor:not-allowed;opacity:.35}.tfa-v2-task-drag-handle .tfa-v2-icon{width:15px;height:15px}.tfa-v2-task-header-actions{display:flex;align-items:center;gap:3px;opacity:0;pointer-events:none;transform:translateY(2px);transition:opacity .15s ease,transform .15s ease}.tfa-v2-task:hover .tfa-v2-task-header-actions,.tfa-v2-task:focus-within .tfa-v2-task-header-actions,.tfa-v2-task.has-open-menu .tfa-v2-task-header-actions{opacity:1;pointer-events:auto;transform:none}.tfa-v2-task-action{height:26px;display:inline-flex;align-items:center;justify-content:center;padding:0 7px;border:1px solid var(--v2-line-strong);border-radius:6px;color:var(--v2-muted);background:var(--v2-panel);font-size:9px;white-space:nowrap}.tfa-v2-task-action:hover{color:var(--v2-text);border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong))}.tfa-v2-task-action.is-danger:hover{color:var(--v2-danger);border-color:color-mix(in srgb,var(--v2-danger) 45%,var(--v2-line-strong))}.tfa-v2-task-action.is-icon{width:26px;padding:0}.tfa-v2-task-action .tfa-v2-icon{width:14px;height:14px}.tfa-v2-domain-control,.tfa-v2-status-control,.tfa-v2-task-more-wrap{position:relative}.tfa-v2-domain-trigger,.tfa-v2-status-trigger{height:22px;padding:0 7px;border:1px solid var(--v2-line-strong);border-radius:6px;color:var(--v2-muted);background:transparent;font-size:9px}.tfa-v2-domain-trigger:after,.tfa-v2-status-trigger:after{content:"";display:inline-block;margin-left:5px;border:3px solid transparent;border-top-color:currentColor;transform:translateY(2px)}.tfa-v2-domain-trigger:focus-visible,.tfa-v2-status-trigger:focus-visible{outline:2px solid var(--v2-accent);outline-offset:1px}
    .tfa-v2-menu[hidden]{display:none!important}.tfa-v2-menu{z-index:60;min-width:116px;display:grid;gap:2px;padding:5px;border:1px solid var(--v2-line-strong);border-radius:8px;background:var(--v2-panel);box-shadow:0 14px 34px rgba(0,0,0,.24)}.tfa-v2-menu-label{padding:4px 8px;color:var(--v2-faint);font-size:9px;white-space:nowrap}.tfa-v2-menu button{min-height:29px;padding:0 8px;border:0;border-radius:6px;color:var(--v2-muted);background:transparent;text-align:left;white-space:nowrap}.tfa-v2-menu button:hover,.tfa-v2-menu button:focus-visible,.tfa-v2-menu button.is-current{outline:0;color:var(--v2-text);background:var(--v2-soft)}.tfa-v2-menu button.is-danger{color:var(--v2-danger)}.tfa-v2-domain-menu,.tfa-v2-status-menu,.tfa-v2-task-more-menu,.tfa-v2-tab-menu,.tfa-v2-primary-menu{position:absolute;top:0;left:0}.tfa-v2-primary-menu{min-width:164px;max-width:240px}.tfa-v2-primary-menu button{overflow:hidden;text-overflow:ellipsis}
    .tfa-v2-recycle-caption{overflow:hidden;color:var(--v2-faint);font-size:9px;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-restore-all{height:29px;display:inline-flex;align-items:center;gap:6px;margin-left:auto;padding:0 9px;border:1px solid color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong));border-radius:7px;color:var(--v2-text);background:var(--v2-accent-soft);font-size:10px;font-weight:650;white-space:nowrap}.tfa-v2-restore-all:disabled{cursor:default;opacity:.45}.tfa-v2-restore-all:focus-visible,.tfa-v2-recycle-action:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px}.tfa-v2-restore-all .tfa-v2-icon,.tfa-v2-recycle-action .tfa-v2-icon{width:14px;height:14px}
    .tfa-v2-recycle-scroll{padding:14px 18px 40px}.tfa-v2-recycle-list{display:grid;gap:10px}.tfa-v2-recycle-card{--trash-color:#7d6cad;min-height:92px;display:grid;grid-template-columns:72px minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px 12px;border:1px solid var(--v2-line);border-radius:11px;color:var(--v2-text);background:var(--v2-panel)}.tfa-v2-recycle-card.is-group{min-height:132px;padding:0;border:0;background:transparent}.tfa-v2-recycle-time{display:grid;gap:3px}.tfa-v2-recycle-time strong{color:var(--v2-muted);font-size:10px}.tfa-v2-recycle-time span{color:var(--v2-faint);font-size:8px}.tfa-v2-recycle-main{min-width:0}.tfa-v2-recycle-tab{display:flex;align-items:center;gap:11px}.tfa-v2-recycle-copy{min-width:0;display:grid;gap:4px}.tfa-v2-recycle-copy strong,.tfa-v2-recycle-copy span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-recycle-copy strong{font-size:12px}.tfa-v2-recycle-copy span{color:var(--v2-faint);font-size:9px}
    .tfa-v2-recycle-task{overflow:hidden;border:1px solid var(--v2-line);border-left:3px solid var(--trash-color);border-radius:10px;background:var(--v2-soft)}.tfa-v2-recycle-task-header{min-height:48px;display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--v2-line)}.tfa-v2-recycle-task-copy{min-width:0;display:grid;gap:5px}.tfa-v2-recycle-task-title{display:flex;align-items:center;gap:7px;flex-wrap:wrap}.tfa-v2-recycle-task-title strong{overflow:hidden;max-width:min(390px,45vw);font-size:13.5px;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-recycle-tag{height:22px;display:inline-flex;align-items:center;gap:5px;padding:0 7px;border:1px solid var(--v2-line-strong);border-radius:6px;color:var(--v2-muted);font-size:9px;font-weight:650;white-space:nowrap}.tfa-v2-recycle-tag.is-domain{border-color:color-mix(in srgb,var(--trash-color) 30%,var(--v2-line-strong));color:color-mix(in srgb,var(--trash-color) 72%,var(--v2-text))}.tfa-v2-recycle-task-copy>small{color:var(--v2-faint);font-size:9px}.tfa-v2-recycle-pages{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;padding:7px}.tfa-v2-recycle-page{min-width:0;min-height:48px;display:flex;align-items:center;gap:8px;padding:7px 9px;border:1px solid var(--v2-line);border-radius:8px;background:var(--v2-panel)}.tfa-v2-recycle-page .tfa-v2-site-icon{width:28px;height:28px;border-radius:7px}.tfa-v2-recycle-page-copy{min-width:0;display:grid;gap:3px}.tfa-v2-recycle-page-copy strong,.tfa-v2-recycle-page-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-recycle-page-copy strong{font-size:10px}.tfa-v2-recycle-page-copy small{color:var(--v2-faint);font-size:8px}.tfa-v2-recycle-more{align-self:center;color:var(--v2-faint);font-size:9px}
    .tfa-v2-recycle-actions{display:flex;align-items:center;gap:5px}.tfa-v2-recycle-action{height:29px;display:inline-flex;align-items:center;gap:5px;padding:0 9px;border:1px solid var(--v2-line-strong);border-radius:7px;color:var(--v2-muted);background:var(--v2-panel);font-size:9px;font-weight:650;white-space:nowrap}.tfa-v2-recycle-action:hover{border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong));color:var(--v2-text);background:var(--v2-soft)}.tfa-v2-recycle-action.is-restore{color:color-mix(in srgb,var(--v2-accent) 78%,var(--v2-text));background:var(--v2-accent-soft)}.tfa-v2-recycle-action.is-delete{opacity:0;pointer-events:none;transform:translateX(3px);transition:opacity .15s ease,transform .15s ease}.tfa-v2-recycle-card:hover .tfa-v2-recycle-action.is-delete,.tfa-v2-recycle-card:focus-within .tfa-v2-recycle-action.is-delete{opacity:1;pointer-events:auto;transform:none}.tfa-v2-recycle-action.is-delete:hover{border-color:color-mix(in srgb,var(--v2-danger) 45%,var(--v2-line-strong));color:var(--v2-danger);background:color-mix(in srgb,var(--v2-danger) 9%,var(--v2-panel))}
    .tfa-v2-empty{min-height:170px;display:grid;place-content:center;gap:6px;padding:24px;color:var(--v2-muted);text-align:center}.tfa-v2-empty strong{color:var(--v2-text);font-size:13px}.tfa-v2-empty small{color:var(--v2-faint)}.tfa-v2-footer{display:flex;align-items:center;justify-content:space-between;padding:0 13px;border-top:1px solid var(--v2-line);color:var(--v2-faint);background:var(--v2-header);font-size:9px}.tfa-v2-sync{display:flex;align-items:center;gap:6px}.tfa-v2-sync:before{content:"";width:6px;height:6px;border-radius:50%;background:#4fb284}
    .tfa-v2-task-pane{container:taskpane / inline-size}.tfa-v2-select:hover{border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong))}.tfa-v2-new-task:hover{background:color-mix(in srgb,var(--v2-accent) 88%,#000)}.tfa-v2-select:focus-visible,.tfa-v2-new-task:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px}.tfa-v2-menu button:disabled,.tfa-v2-task-action:disabled{cursor:not-allowed;opacity:.4;color:var(--v2-faint);background:transparent}.tfa-v2-task-tags .tfa-v2-status-dot{width:7px;height:7px;padding:0;border:0}.tfa-v2-tab-meta{min-width:0;display:flex;align-items:center;gap:5px}.tfa-v2-tab-meta small{min-width:0;flex:1}.tfa-v2-source-tag{flex:0 0 auto;padding:1px 5px;border:1px solid var(--v2-line-strong);border-radius:5px;font-size:8px;white-space:nowrap}.tfa-v2-source-tag.is-manual{border-color:color-mix(in srgb,#4fb284 42%,var(--v2-line));color:color-mix(in srgb,#4fb284 72%,var(--v2-text));background:color-mix(in srgb,#4fb284 8%,transparent)}.tfa-v2-source-tag.is-smart{border-color:color-mix(in srgb,var(--v2-accent) 42%,var(--v2-line));color:color-mix(in srgb,var(--v2-accent) 72%,var(--v2-text));background:color-mix(in srgb,var(--v2-accent) 8%,transparent)}.tfa-v2-tab.is-page-drop-before:before,.tfa-v2-tab.is-page-drop-after:after{content:"";position:absolute;z-index:3;top:7px;bottom:7px;width:3px;border-radius:3px;background:var(--v2-accent);pointer-events:none}.tfa-v2-tab.is-page-drop-before:before{left:-4px}.tfa-v2-tab.is-page-drop-after:after{right:-4px}.tfa-v2-task-pages .tfa-v2-tab-grid.is-page-drop-end{box-shadow:inset 0 -3px var(--v2-accent)}
    .tfa-v2-inbox-item{min-width:0;display:grid;align-content:start;gap:5px}.tfa-v2-inbox-item>.tfa-v2-tab{width:100%;min-height:68px}.tfa-v2-suggestion{min-width:0;display:grid;gap:5px;padding:7px 8px;border:1px solid color-mix(in srgb,var(--v2-accent) 34%,var(--v2-line));border-radius:8px;color:var(--v2-text);background:color-mix(in srgb,var(--v2-accent) 4%,var(--v2-panel));transition:border-color .18s ease,background-color .18s ease,opacity .18s ease}.tfa-v2-suggestion:hover,.tfa-v2-suggestion:focus-within{border-color:color-mix(in srgb,var(--v2-accent) 58%,var(--v2-line))}.tfa-v2-suggestion[aria-busy="true"],.tfa-v2-suggestion.is-loading{cursor:wait;opacity:.72}.tfa-v2-suggestion-head{min-width:0;display:flex;align-items:center;gap:5px;flex-wrap:wrap}.tfa-v2-suggestion-source,.tfa-v2-suggestion-confidence{min-height:19px;display:inline-flex;align-items:center;padding:0 6px;border-radius:5px;font-size:8px;font-weight:700;line-height:1.2;white-space:nowrap}.tfa-v2-suggestion-source{border:1px solid var(--v2-line-strong);color:var(--v2-muted);background:var(--v2-soft)}.tfa-v2-suggestion-source.is-local{border-color:color-mix(in srgb,var(--v2-accent) 32%,var(--v2-line));color:color-mix(in srgb,var(--v2-accent) 72%,var(--v2-text));background:var(--v2-accent-soft)}.tfa-v2-suggestion-source.is-ai{border-color:color-mix(in srgb,var(--v2-accent) 54%,var(--v2-line));color:color-mix(in srgb,var(--v2-accent) 84%,var(--v2-text));background:color-mix(in srgb,var(--v2-accent) 14%,var(--v2-panel))}.tfa-v2-suggestion-confidence{margin-left:auto;color:var(--v2-muted);background:var(--v2-soft)}.tfa-v2-suggestion-confidence.is-high{color:color-mix(in srgb,var(--v2-accent) 84%,var(--v2-text));background:var(--v2-accent-soft)}.tfa-v2-suggestion-why{min-width:0;margin:0;color:var(--v2-text);font-size:10px;font-weight:680;line-height:1.35;overflow-wrap:anywhere}.tfa-v2-suggestion-candidates{min-width:0;display:flex;align-items:stretch;gap:4px;overflow:hidden}.tfa-v2-suggestion-candidates:empty{display:none}.tfa-v2-suggestion-candidate{min-width:0;min-height:28px;flex:1 1 0;display:flex;align-items:center;gap:5px;padding:4px 6px;border:1px solid var(--v2-line);border-radius:7px;color:var(--v2-muted);background:var(--v2-soft);text-align:left}.tfa-v2-suggestion-candidate:hover{border-color:color-mix(in srgb,var(--v2-accent) 44%,var(--v2-line));color:var(--v2-text)}.tfa-v2-suggestion-candidate.is-selected{border-color:color-mix(in srgb,var(--v2-accent) 68%,var(--v2-line));color:var(--v2-text);background:var(--v2-accent-soft)}.tfa-v2-suggestion-choice{width:13px;height:13px;flex:0 0 auto;margin:0;accent-color:var(--v2-accent)}.tfa-v2-suggestion-copy{min-width:0;display:grid;gap:1px}.tfa-v2-suggestion-copy strong,.tfa-v2-suggestion-copy small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-suggestion-copy strong{color:inherit;font-size:9px}.tfa-v2-suggestion-copy small{color:var(--v2-faint);font-size:8px}.tfa-v2-suggestion-reasons{min-width:0;display:grid;gap:2px;margin:0;padding:0;color:var(--v2-muted);font-size:9px;line-height:1.3;list-style:none}.tfa-v2-suggestion-reasons>*{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-suggestion-reasons>*:nth-child(n+3){display:none}.tfa-v2-suggestion-actions{display:flex;align-items:center;justify-content:flex-end;gap:5px;min-width:0}.tfa-v2-suggestion-actions button,.tfa-v2-smart-undo{min-height:27px;display:inline-flex;align-items:center;justify-content:center;padding:0 8px;border-radius:6px;font-size:9px;font-weight:680;line-height:1.2}.tfa-v2-suggestion-accept{border:1px solid var(--v2-accent);color:#fff;background:var(--v2-accent)}.tfa-v2-suggestion-accept:hover:not(:disabled){background:color-mix(in srgb,var(--v2-accent) 86%,#000)}.tfa-v2-suggestion-reject,.tfa-v2-smart-undo{border:1px solid var(--v2-line-strong);color:var(--v2-muted);background:var(--v2-panel)}.tfa-v2-suggestion-reject:hover:not(:disabled),.tfa-v2-smart-undo:hover:not(:disabled){border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong));color:var(--v2-text);background:var(--v2-soft)}.tfa-v2-suggestion-candidate:focus-visible,.tfa-v2-suggestion-accept:focus-visible,.tfa-v2-suggestion-reject:focus-visible,.tfa-v2-smart-undo:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px}.tfa-v2-suggestion button:disabled,.tfa-v2-smart-undo:disabled{cursor:not-allowed;opacity:.42}.tfa-v2-suggestion-notice{min-width:0;margin:0;color:var(--v2-muted);font-size:9px;line-height:1.35;overflow-wrap:anywhere}.tfa-v2-suggestion-notice[hidden]{display:none}.tfa-v2-suggestion-notice.is-error{color:var(--v2-danger)}.tfa-v2-suggestion-notice.is-success{color:color-mix(in srgb,#25835f 82%,var(--v2-text))}.tfa-v2-smart-undo{opacity:0;pointer-events:none;transform:translateY(2px);transition:opacity .15s ease,transform .15s ease}.tfa-v2-tab:hover .tfa-v2-smart-undo,.tfa-v2-tab:focus-within .tfa-v2-smart-undo,.tfa-v2-smart-undo:focus,.tfa-v2-smart-undo:focus-visible{opacity:1;pointer-events:auto;transform:none}.tfa-v2-inbox:not(.is-expanded):has(.tfa-v2-suggestion) .tfa-v2-inbox-pages .tfa-v2-tab-grid{max-height:196px}.tfa-v2-inbox:not(.is-expanded):has(.tfa-v2-suggestion-candidate:nth-child(2)) .tfa-v2-inbox-pages .tfa-v2-tab-grid{max-height:228px}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-suggestion{border-color:color-mix(in srgb,var(--v2-accent) 44%,var(--v2-line));background:color-mix(in srgb,var(--v2-accent) 7%,var(--v2-panel))}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-suggestion-source.is-local{color:#c6bfff}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-suggestion-notice.is-success{color:#73cba7}
    .tfa-v2-suggestion-batch-entry{min-height:27px;display:inline-flex;align-items:center;justify-content:center;gap:5px;margin-left:auto;padding:0 8px;border:1px solid color-mix(in srgb,var(--v2-inbox,#d69b45) 44%,var(--v2-line-strong));border-radius:6px;color:color-mix(in srgb,var(--v2-inbox,#d69b45) 76%,var(--v2-text));background:color-mix(in srgb,var(--v2-inbox,#d69b45) 7%,var(--v2-panel));font-size:9px;font-weight:680;line-height:1.2;white-space:normal;text-align:center}.tfa-v2-suggestion-batch-entry:hover:not(:disabled),.tfa-v2-suggestion-batch-entry.is-active{border-color:color-mix(in srgb,var(--v2-accent) 58%,var(--v2-line-strong));color:var(--v2-text);background:var(--v2-accent-soft)}.tfa-v2-suggestion-batch-entry.is-loading{cursor:wait;opacity:.58}.tfa-v2-suggestion-batch-select{width:14px;height:14px;flex:0 0 auto;margin:0;accent-color:var(--v2-accent)}.tfa-v2-inbox-item.is-active>.tfa-v2-suggestion{border-color:color-mix(in srgb,var(--v2-accent) 68%,var(--v2-line));background:color-mix(in srgb,var(--v2-accent) 8%,var(--v2-panel))}.tfa-v2-suggestion-batch-bar{position:sticky;z-index:15;bottom:4px;width:max-content;max-width:calc(100% - 14px);min-height:43px;display:flex;align-items:center;justify-content:center;gap:5px;margin:7px auto 3px;padding:6px;border:1px solid var(--v2-line-strong);border-radius:9px;color:var(--v2-text);background:var(--v2-panel);box-shadow:0 4px 8px rgba(31,38,49,.18)}.tfa-v2-suggestion-batch-bar[hidden]{display:none!important}.tfa-v2-suggestion-batch-bar.is-active{border-color:color-mix(in srgb,var(--v2-accent) 48%,var(--v2-line-strong))}.tfa-v2-suggestion-batch-bar.is-loading{cursor:wait;opacity:.72}.tfa-v2-suggestion-batch-count{min-width:0;padding:0 6px;color:var(--v2-muted);font-size:9px;font-weight:700;line-height:1.3;overflow-wrap:anywhere}.tfa-v2-suggestion-batch-status,.tfa-v2-suggestion-batch-limit{min-width:0;color:var(--v2-muted);font-size:9px;line-height:1.3;overflow-wrap:anywhere}.tfa-v2-suggestion-batch-limit{color:color-mix(in srgb,var(--v2-inbox,#d69b45) 78%,var(--v2-text))}.tfa-v2-suggestion-batch-select-all,.tfa-v2-suggestion-batch-accept,.tfa-v2-suggestion-batch-reject,.tfa-v2-suggestion-batch-cancel{min-height:29px;display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border-radius:6px;font-size:9px;font-weight:680;line-height:1.2;white-space:normal;text-align:center}.tfa-v2-suggestion-batch-select-all,.tfa-v2-suggestion-batch-cancel{border:1px solid var(--v2-line-strong);color:var(--v2-muted);background:var(--v2-soft)}.tfa-v2-suggestion-batch-accept{border:1px solid var(--v2-accent);color:#fff;background:var(--v2-accent)}.tfa-v2-suggestion-batch-reject{border:1px solid color-mix(in srgb,var(--v2-danger) 38%,var(--v2-line-strong));color:var(--v2-danger);background:color-mix(in srgb,var(--v2-danger) 6%,var(--v2-panel))}.tfa-v2-suggestion-batch-select-all:hover:not(:disabled),.tfa-v2-suggestion-batch-cancel:hover:not(:disabled){border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong));color:var(--v2-text);background:var(--v2-accent-soft)}.tfa-v2-suggestion-batch-accept:hover:not(:disabled){background:color-mix(in srgb,var(--v2-accent) 86%,#000)}.tfa-v2-suggestion-batch-reject:hover:not(:disabled){border-color:color-mix(in srgb,var(--v2-danger) 58%,var(--v2-line-strong));background:color-mix(in srgb,var(--v2-danger) 11%,var(--v2-panel))}.tfa-v2-suggestion-batch-entry:focus-visible,.tfa-v2-suggestion-batch-select:focus-visible,.tfa-v2-suggestion-batch-select-all:focus-visible,.tfa-v2-suggestion-batch-accept:focus-visible,.tfa-v2-suggestion-batch-reject:focus-visible,.tfa-v2-suggestion-batch-cancel:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px}.tfa-v2-suggestion-batch-entry:disabled,.tfa-v2-suggestion-batch-select:disabled,.tfa-v2-suggestion-batch-bar button:disabled{cursor:not-allowed;opacity:.4}.tfa-v2-suggestion-batch-bar.is-loading button,.tfa-v2-suggestion-batch-bar.is-loading .tfa-v2-suggestion-batch-select{pointer-events:none}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-suggestion-batch-bar{background:var(--v2-soft);box-shadow:0 4px 8px rgba(0,0,0,.34)}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-suggestion-batch-entry{color:#dfbd83}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-suggestion-batch-reject{background:color-mix(in srgb,var(--v2-danger) 9%,var(--v2-panel))}
    @container taskpane (max-width:560px){.tfa-v2-task-pane>.tfa-v2-pane-header{align-content:center;flex-wrap:wrap;row-gap:6px;padding:6px 10px}.tfa-v2-task-pane .tfa-v2-filters{width:100%;flex:1 1 100%;margin-left:0;overflow:hidden}.tfa-v2-task-pane .tfa-v2-select{min-width:72px;flex:1 1 72px}.tfa-v2-task-pane .tfa-v2-new-task{flex:0 0 auto}}
    @container taskpane (max-width:560px){.tfa-v2-suggestion-candidates{display:grid;grid-template-columns:1fr}.tfa-v2-suggestion-copy strong,.tfa-v2-suggestion-copy small,.tfa-v2-suggestion-reasons>*{white-space:normal;overflow-wrap:anywhere}.tfa-v2-suggestion-actions{justify-content:stretch;flex-wrap:wrap}.tfa-v2-suggestion-actions button{flex:1 1 110px;white-space:normal}.tfa-v2-inbox:not(.is-expanded):has(.tfa-v2-suggestion) .tfa-v2-inbox-pages .tfa-v2-tab-grid{max-height:292px}.tfa-v2-inbox:not(.is-expanded):has(.tfa-v2-suggestion-candidate:nth-child(2)) .tfa-v2-inbox-pages .tfa-v2-tab-grid{max-height:372px}}
    @container taskpane (max-width:560px){.tfa-v2-suggestion-batch-bar{width:calc(100% - 14px);max-width:none;flex-wrap:wrap;justify-content:stretch}.tfa-v2-suggestion-batch-count{flex:1 1 120px}.tfa-v2-suggestion-batch-status,.tfa-v2-suggestion-batch-limit{flex:1 1 100%}.tfa-v2-suggestion-batch-select-all{flex:1 1 120px}.tfa-v2-suggestion-batch-accept,.tfa-v2-suggestion-batch-reject,.tfa-v2-suggestion-batch-cancel{flex:1 1 88px}.tfa-v2-suggestion-batch-entry{max-width:170px;overflow-wrap:anywhere}}
    @media(max-width:900px){.tfa-v2-header{grid-template-columns:minmax(150px,.6fr) minmax(230px,1fr) auto;grid-template-rows:58px 42px}.tfa-v2-layout{grid-row:2;grid-column:1/-1;justify-self:center}.tfa-v2-header-actions{grid-column:3}.tfa-v2-workbench{grid-template-rows:100px minmax(0,1fr) 34px}.tfa-v2-task-pane{grid-template-rows:max-content 0 minmax(0,1fr)}.tfa-v2-task-pane:has(>[data-v2-ai-adjustment-host]>.tfa-v2-ai-adjustment){grid-template-rows:max-content max-content minmax(0,1fr)}.tfa-v2-workspace,.tfa-v2-workspace[data-layout="browser"],.tfa-v2-workspace[data-layout="tasks"]{grid-template-columns:1fr}.tfa-v2-workspace[data-layout="split"] .tfa-v2-task-pane{border-top:7px solid var(--v2-line)}.tfa-v2-workspace[data-layout="split"]{overflow:auto}.tfa-v2-workspace[data-layout="split"] .tfa-v2-pane{min-height:360px}.tfa-v2-divider{display:none}.tfa-v2-filters{overflow:auto}.tfa-v2-select{min-width:80px}}
    @media(max-width:760px){.tfa-v2-recycle-card{grid-template-columns:58px minmax(0,1fr)}.tfa-v2-recycle-actions{grid-column:2;justify-self:start}.tfa-v2-recycle-pages{grid-template-columns:1fr}}
    @media(max-width:620px){.tfa-v2-header{grid-template-columns:44px minmax(150px,1fr) auto;padding-left:9px}.tfa-v2-brand-copy{display:none}.tfa-v2-header-search .tfa-v2-search-shortcut{display:none}.tfa-v2-search{padding-right:12px}.tfa-v2-layout button{padding:0 8px}.tfa-v2-layout .tfa-v2-layout-label{display:none}.tfa-v2-pane-header{align-items:flex-start;flex-direction:column;height:auto;padding:8px 10px}.tfa-v2-pane{grid-template-rows:auto minmax(0,1fr)}.tfa-v2-task-pane{grid-template-rows:max-content 0 minmax(0,1fr)}.tfa-v2-task-pane:has(>[data-v2-ai-adjustment-host]>.tfa-v2-ai-adjustment){grid-template-rows:max-content max-content minmax(0,1fr)}.tfa-v2-filters{width:100%;margin-left:0}.tfa-v2-task-tags{display:none}.tfa-v2-recycle-scroll{padding:10px}.tfa-v2-recycle-caption{display:none}.tfa-v2-restore-all{margin-left:0}}
    @media(hover:none){.tfa-v2-tab-actions,.tfa-v2-task-header-actions,.tfa-v2-task-drag-handle,.tfa-v2-recycle-action.is-delete,.tfa-v2-smart-undo{opacity:1;pointer-events:auto;transform:none}.tfa-v2-suggestion-batch-entry,.tfa-v2-suggestion-batch-bar button{min-height:32px}}
    @media(prefers-reduced-motion:reduce){.tfa-v2-workbench *{scroll-behavior:auto!important;transition:none!important;animation:none!important}}
    .tfa-v2-task-pane>.tfa-v2-scroll{padding-bottom:9px}.tfa-v2-task-content-inner>.tfa-v2-task-list{padding-bottom:10px}.tfa-v2-task-content-inner>.tfa-v2-inbox{margin-top:auto}
    .tfa-v2-task-title{position:relative;min-width:0;display:block;padding:0;border:0;color:inherit;background:transparent;text-align:left}.tfa-v2-task-title strong{display:block;overflow:hidden;font-size:13px;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-task-title small{position:absolute;z-index:10;left:0;top:calc(100% + 5px);width:max-content;max-width:220px;padding:4px 7px;border:1px solid var(--v2-line-strong);border-radius:6px;color:var(--v2-muted);background:var(--v2-panel);box-shadow:0 8px 18px rgba(0,0,0,.14);font-size:9px;opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .15s ease,transform .15s ease}.tfa-v2-task-title:hover small,.tfa-v2-task-title:focus-visible small{opacity:1;transform:none}.tfa-v2-task-title:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px;border-radius:4px}.tfa-v2-status-trigger{display:inline-flex;align-items:center;gap:5px}.tfa-v2-status-dot{width:7px;height:7px;flex:0 0 auto;border-radius:50%;background:#7e8997}.tfa-v2-status-dot.is-active{background:#4fb284}.tfa-v2-status-dot.is-paused{background:#d99a45}.tfa-v2-status-dot.is-done{background:#86909d}.tfa-v2-status-menu button{display:flex;align-items:center;gap:7px}.tfa-v2-task:not(.is-expanded) .tfa-v2-task-pages .tfa-v2-tab-grid{max-height:68px;overflow:hidden}.tfa-v2-task-footer{height:28px;border-top:1px solid var(--v2-line)}.tfa-v2-task-footer button{width:100%;height:27px;display:grid;place-items:center;padding:0;border:0;color:var(--v2-faint);background:transparent}.tfa-v2-task-footer button:hover{color:var(--v2-text);background:color-mix(in srgb,var(--task-color) 7%,transparent)}.tfa-v2-task-footer button:focus-visible{outline:2px solid var(--v2-accent);outline-offset:-3px}.tfa-v2-task-footer .tfa-v2-icon{width:16px;height:16px}
    .tfa-v2-task:hover .tfa-v2-task-title small,.tfa-v2-task:focus-within .tfa-v2-task-title small{opacity:1;transform:none}
    .tfa-v2-suggestion-notice-action{margin:0;padding:0;border:0;color:var(--v2-accent);background:transparent;font:inherit;font-weight:700;text-decoration:underline;text-underline-offset:2px}.tfa-v2-suggestion-notice-action:hover{color:color-mix(in srgb,var(--v2-accent) 78%,var(--v2-text))}.tfa-v2-suggestion-notice-action:focus-visible{outline:2px solid var(--v2-accent);outline-offset:2px;border-radius:3px}.tfa-v2-suggestion-notice-action:disabled{cursor:not-allowed;opacity:.42}
    .tfa-v2-observation{min-width:0;display:flex;align-items:center;gap:5px;color:color-mix(in srgb,var(--v2-inbox,#d69b45) 78%,var(--v2-text));font-size:8px;line-height:1.25}.tfa-v2-observation b{flex:0 0 auto;padding:1px 5px;border:1px solid color-mix(in srgb,var(--v2-inbox,#d69b45) 42%,var(--v2-line));border-radius:5px;background:color-mix(in srgb,var(--v2-inbox,#d69b45) 9%,var(--v2-panel));font-size:8px}.tfa-v2-observation small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--v2-muted);font-size:8px}.tfa-v2-tab:hover .tfa-v2-observation small,.tfa-v2-tab:focus-within .tfa-v2-observation small{white-space:normal;overflow-wrap:anywhere}.tfa-v2-observation.is-possible_misclick,.tfa-v2-observation.is-redirect_or_ad{color:color-mix(in srgb,var(--v2-danger) 72%,var(--v2-text))}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-observation{color:#dfbd83}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-observation.is-possible_misclick,.tfa-v2-workbench[data-theme="dark"] .tfa-v2-observation.is-redirect_or_ad{color:#eea7a7}
    .tfa-v2-tab-main[draggable="true"]{cursor:grab}[data-v2-browser-content].is-relation-remove-target,[data-v2-inbox].is-relation-remove-target{outline:2px dashed var(--v2-accent);outline-offset:-5px;background:color-mix(in srgb,var(--v2-accent) 7%,var(--v2-container))}
    .tfa-v2-site-icon.has-image{border-radius:0;background:transparent}.tfa-v2-site-icon img{background:transparent}.tfa-v2-tab-copy strong{font-size:13px}.tfa-v2-tab-copy small{font-size:11px}.tfa-v2-tab:not([draggable="true"]){cursor:default}.tfa-v2-tab.is-dragging .tfa-v2-tab-main{cursor:grabbing}.tfa-v2-inbox.is-expanded .tfa-v2-inbox-pages{max-height:192px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
    .tfa-v2-recycle-card.is-group{min-height:0}.tfa-v2-recycle-time[title]{cursor:help}
    .tfa-v2-layout{justify-self:center}.tfa-v2-header-tools{min-width:0;display:flex;align-items:center;justify-content:flex-end;gap:8px}.tfa-v2-header-actions{flex:0 0 auto}.tfa-v2-header-search{min-width:160px;width:min(29vw,420px);max-width:420px;justify-self:auto}
    @media(max-width:1000px){.tfa-v2-header{grid-template-columns:minmax(150px,.7fr) minmax(280px,1fr);grid-template-rows:58px 42px}.tfa-v2-layout{grid-row:2;grid-column:1/-1;justify-self:center}.tfa-v2-header-tools{grid-column:2}.tfa-v2-workbench{grid-template-rows:100px minmax(0,1fr) 34px}}
    @media(max-width:620px){.tfa-v2-header{grid-template-columns:44px minmax(0,1fr);padding-left:9px}.tfa-v2-header-tools{grid-column:2}.tfa-v2-header-search{min-width:0;width:100%}}
  `;
        function escapeHtml(value) {
          return String(value == null ? "" : value).replace(/[&<>"']/g, (character) => ({
            "&": "&amp;",
            "<": "&lt;",
            ">": "&gt;",
            '"': "&quot;",
            "'": "&#39;"
          })[character]);
        }
        function icon(name) {
          const paths = {
            columns: '<rect x="2.5" y="3" width="6" height="14" rx="1"/><rect x="11.5" y="3" width="6" height="14" rx="1"/>',
            browser: '<path d="M3 5h14v10H3z"/><path d="M3 8h14"/>',
            tasks: '<rect x="3" y="3" width="5" height="5" rx="1"/><rect x="12" y="3" width="5" height="5" rx="1"/><rect x="3" y="12" width="5" height="5" rx="1"/><rect x="12" y="12" width="5" height="5" rx="1"/>',
            search: '<circle cx="8.5" cy="8.5" r="5.5"/><path d="m13 13 4 4"/>',
            close: '<path d="m5 5 10 10M15 5 5 15"/>',
            theme: '<path d="M16 12.2A6.8 6.8 0 0 1 7.8 4a6.8 6.8 0 1 0 8.2 8.2Z"/>',
            settings: '<path d="M8.6 3.2a1.5 1.5 0 0 1 2.8 0l.2.7c.5.1.9.3 1.3.5l.7-.3a1.5 1.5 0 0 1 1.9 1.9l-.3.7c.2.4.4.8.5 1.3l.7.2a1.5 1.5 0 0 1 0 2.8l-.7.2c-.1.5-.3.9-.5 1.3l.3.7a1.5 1.5 0 0 1-1.9 1.9l-.7-.3c-.4.2-.8.4-1.3.5l-.2.7a1.5 1.5 0 0 1-2.8 0l-.2-.7a6 6 0 0 1-1.3-.5l-.7.3a1.5 1.5 0 0 1-1.9-1.9l.3-.7a6 6 0 0 1-.5-1.3l-.7-.2a1.5 1.5 0 0 1 0-2.8l.7-.2c.1-.5.3-.9.5-1.3L4.5 6a1.5 1.5 0 0 1 1.9-1.9l.7.3c.4-.2.8-.4 1.3-.5l.2-.7Z"/><circle cx="10" cy="9.6" r="2.2"/>',
            plus: '<path d="M10 4v12M4 10h12"/>',
            more: '<circle cx="5" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="10" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="15" cy="10" r="1" fill="currentColor" stroke="none"/>',
            remove: '<path d="M4 10h12"/>',
            undo: '<path d="M7 6H3v-4"/><path d="M3.5 6A7 7 0 1 1 3 13"/>',
            recycle: '<path d="M6.2 5.2A6.5 6.5 0 0 1 16 8"/><path d="M16 4.5V8h-3.5M13.8 14.8A6.5 6.5 0 0 1 4 12"/><path d="M4 15.5V12h3.5"/>',
            restore: '<path d="M5.5 6H2.8V3.3"/><path d="M3 6a7 7 0 1 1 .8 8.8"/>',
            trash: '<path d="M4 6h12M8 6V4h4v2M6 6l.7 10h6.6L14 6M8.5 9v4M11.5 9v4"/>',
            "chevron-up": '<path d="m5 12 5-5 5 5"/>',
            "chevron-down": '<path d="m5 8 5 5 5-5"/>',
            "chevron-left": '<path d="m12 5-5 5 5 5"/>',
            "chevron-right": '<path d="m8 5 5 5-5 5"/>',
            drag: '<circle cx="7" cy="5" r="1" fill="currentColor" stroke="none"/><circle cx="13" cy="5" r="1" fill="currentColor" stroke="none"/><circle cx="7" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="13" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="7" cy="15" r="1" fill="currentColor" stroke="none"/><circle cx="13" cy="15" r="1" fill="currentColor" stroke="none"/>'
          };
          return `<svg class="tfa-v2-icon" viewBox="0 0 20 20" aria-hidden="true">${paths[name] || paths.tasks}</svg>`;
        }
        function buildWorkbenchShell(options = {}) {
          const translate = typeof options.t === "function" ? options.t : () => "";
          const tr = (key, fallback) => {
            const translated = translate(key);
            return escapeHtml(translated && translated !== key ? translated : fallback);
          };
          const theme = options.theme === "dark" ? "dark" : "light";
          return `
      <style data-tfa-v2-styles>${WORKBENCH_CSS}${String(options.extraCss || "")}</style>
      <main class="tfa-v2-workbench" data-theme="${theme}">
        <header class="tfa-v2-header">
          <div class="tfa-v2-brand"><span class="tfa-v2-brand-mark"><i></i><i></i><i></i></span><span class="tfa-v2-brand-copy"><strong>TabFlow</strong><small data-v2-global-count></small></span></div>
          <nav class="tfa-v2-layout" aria-label="${tr("workbench.layoutLabel", "\u4E3B\u89C6\u56FE\u5207\u6362")}">
            <button type="button" data-v2-layout="split">${icon("columns")}<span class="tfa-v2-layout-label">${tr("workbench.layout.split", "\u53CC\u680F\u603B\u89C8")}</span></button>
            <button type="button" data-v2-layout="browser">${icon("browser")}<span class="tfa-v2-layout-label">${tr("workbench.layout.browser", "\u771F\u5B9E\u9875\u7B7E")}</span></button>
            <button type="button" data-v2-layout="tasks">${icon("tasks")}<span class="tfa-v2-layout-label">${tr("workbench.layout.tasks", "\u4EFB\u52A1\u603B\u89C8")}</span></button>
            <button type="button" data-v2-layout="recycle">${icon("recycle")}<span class="tfa-v2-layout-label">${tr("workbench.layout.recycle", "\u56DE\u6536\u7AD9")}</span></button>
          </nav>
          <div class="tfa-v2-header-tools"><label class="tfa-v2-header-search">${icon("search")}<input type="search" class="tfa-v2-search" data-v2-query placeholder="${tr("workbench.searchPlaceholder", "\u641C\u7D22\u9875\u7B7E\u3001\u7F51\u5740\u6216\u4EFB\u52A1")}" autocomplete="off" spellcheck="false"><kbd class="tfa-v2-search-shortcut">Ctrl K</kbd></label><div class="tfa-v2-header-actions"><button class="tfa-v2-icon-button" type="button" data-v2-action="theme" aria-label="${tr("common.theme", "\u5207\u6362\u76AE\u80A4")}">${icon("theme")}</button><button class="tfa-v2-icon-button" type="button" data-v2-action="settings" aria-label="${tr("common.settings", "\u8BBE\u7F6E")}">${icon("settings")}</button><button class="tfa-v2-icon-button" type="button" data-v2-action="close" aria-label="${tr("common.close", "\u5173\u95ED")}">${icon("close")}</button></div></div>
        </header>
        <section class="tfa-v2-workspace" data-v2-workspace>
          <section class="tfa-v2-pane tfa-v2-browser-pane"><header class="tfa-v2-pane-header"><div class="tfa-v2-pane-title"><strong>${tr("workbench.browserTitle", "\u5F53\u524D\u6D4F\u89C8\u5668\u9875\u7B7E")}</strong><span class="tfa-v2-count" data-v2-browser-count>0</span></div><div class="tfa-v2-filters"><div class="tfa-v2-segments" data-v2-window-options></div></div></header><div class="tfa-v2-scroll" data-v2-browser-content></div></section>
          <div class="tfa-v2-divider" data-v2-divider role="separator" aria-orientation="vertical" aria-label="${tr("workbench.resizePanes", "\u8C03\u6574\u53CC\u680F\u5BBD\u5EA6")}" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50" tabindex="0"><span class="tfa-v2-divider-controls"><button type="button" class="tfa-v2-divider-action" data-v2-divider-action="collapse-browser" aria-label="${tr("workbench.collapseBrowserPane", "\u6536\u8D77\u771F\u5B9E\u9875\u7B7E\u680F")}" title="${tr("workbench.collapseBrowserPane", "\u6536\u8D77\u771F\u5B9E\u9875\u7B7E\u680F")}">${icon("chevron-left")}</button><button type="button" class="tfa-v2-divider-action" data-v2-divider-action="restore-split" aria-label="${tr("workbench.restoreSplitPane", "\u6062\u590D\u53CC\u680F\u603B\u89C8")}" title="${tr("workbench.restoreSplitPane", "\u6062\u590D\u53CC\u680F\u603B\u89C8")}" hidden>${icon("columns")}</button><button type="button" class="tfa-v2-divider-action" data-v2-divider-action="collapse-tasks" aria-label="${tr("workbench.collapseTaskPane", "\u6536\u8D77\u4EFB\u52A1\u603B\u89C8\u680F")}" title="${tr("workbench.collapseTaskPane", "\u6536\u8D77\u4EFB\u52A1\u603B\u89C8\u680F")}">${icon("chevron-right")}</button></span></div>
          <section class="tfa-v2-pane tfa-v2-task-pane"><header class="tfa-v2-pane-header"><div class="tfa-v2-pane-title"><strong>${tr("workbench.taskTitle", "\u4EFB\u52A1\u5212\u5206\u603B\u89C8")}</strong><span class="tfa-v2-count" data-v2-task-count>0</span><button class="tfa-v2-task-undo" type="button" data-v2-action="undo-task-change" aria-label="${tr("task.undoLastChange", "\u64A4\u9500\u4E0A\u4E00\u6B21\u4EFB\u52A1\u4FEE\u6539")}" title="${tr("task.undoLastChange", "\u64A4\u9500\u4E0A\u4E00\u6B21\u4EFB\u52A1\u4FEE\u6539")}"${options.canUndo === true ? "" : " disabled"}>${icon("undo")}</button></div><div class="tfa-v2-filters"><div class="tfa-v2-task-view-switch" role="group" aria-label="${tr("task.view.label", "\u4EFB\u52A1\u89C6\u56FE")}"><button type="button" class="is-active" data-v2-task-view="cards" aria-pressed="true">${tr("task.view.cards", "\u5361\u7247")}</button><button type="button" data-v2-task-view="aggregate" aria-pressed="false">${tr("task.view.aggregate", "\u805A\u5408\u56FE")}</button><button type="button" data-v2-task-view="fishbone" aria-pressed="false">${tr("task.view.fishbone", "\u9C7C\u9AA8\u56FE")}</button></div><select class="tfa-v2-select" data-v2-status-filter aria-label="${tr("workbench.statusFilter", "\u72B6\u6001\u7B5B\u9009")}"></select><select class="tfa-v2-select" data-v2-domain-filter aria-label="${tr("workbench.domainFilter", "\u9886\u57DF\u7B5B\u9009")}"></select><select class="tfa-v2-select" data-v2-task-sort aria-label="${tr("workbench.taskSort", "\u4EFB\u52A1\u6392\u5E8F")}"></select><button class="tfa-v2-new-task" type="button" data-v2-action="new-task">${icon("plus")}${tr("task.new", "\u65B0\u589E\u4EFB\u52A1")}</button></div></header><div data-v2-ai-adjustment-host></div><div class="tfa-v2-scroll" data-v2-task-content></div></section>
          <section class="tfa-v2-pane tfa-v2-recycle-pane" hidden inert aria-hidden="true"><header class="tfa-v2-pane-header"><div class="tfa-v2-pane-title"><strong>${tr("workbench.recycleTitle", "\u56DE\u6536\u7AD9")}</strong><span class="tfa-v2-count" data-v2-recycle-count>0</span><small class="tfa-v2-recycle-caption">${tr("workbench.recycleHint", "\u6309\u5173\u95ED\u65F6\u95F4\u6392\u5217\uFF0C\u53EF\u6062\u590D\u9875\u7B7E\u3001\u9875\u7B7E\u7EC4\u548C\u4EFB\u52A1")}</small></div><button class="tfa-v2-restore-all" type="button" data-v2-restore-all>${icon("restore")}${tr("recycle.restoreAll", "\u6062\u590D\u5168\u90E8")}</button></header><div class="tfa-v2-scroll tfa-v2-recycle-scroll" data-v2-recycle-content></div></section>
        </section>
        <footer class="tfa-v2-footer"><span class="tfa-v2-sync">${tr("workbench.localReady", "\u672C\u5730\u5DE5\u4F5C\u53F0\u5DF2\u5C31\u7EEA")}</span><span>${tr("workbench.footerHint", "\u70B9\u51FB\u9875\u7B7E\u5207\u6362 \xB7 \u641C\u7D22\u540C\u6B65\u8FC7\u6EE4\u4E24\u680F")}</span></footer>
        <div class="tfa-v2-menu tfa-v2-tab-menu" data-v2-tab-menu role="menu" hidden><button type="button" data-v2-toggle-dock-site role="menuitem"></button><button type="button" data-v2-inbox-action="ignore-page" role="menuitem" hidden>${tr("inbox.ignorePage", "\u5FFD\u7565\u6B64\u9875\u9762")}</button><button type="button" data-v2-inbox-action="mark-shared" role="menuitem" hidden>${tr("inbox.markShared", "\u6807\u8BB0\u4E3A\u5171\u4EAB\u5DE5\u5177 / \u591A\u4EFB\u52A1\u9875")}</button><button type="button" data-v2-inbox-action="exclude-site" role="menuitem" hidden>${tr("inbox.excludeSite", "\u4E0D\u8BB0\u5F55\u6B64\u7AD9\u70B9")}</button></div>
      </main>`;
        }
        return Object.freeze({ WORKBENCH_CSS, buildWorkbenchShell, escapeHtml, icon });
      });
    }
  });

  // src/content/v2-workbench-layout-preferences.js
  var require_v2_workbench_layout_preferences = __commonJS({
    "src/content/v2-workbench-layout-preferences.js"(exports, module) {
      (function attachV2WorkbenchLayoutPreferences(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchLayoutPreferences = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchLayoutPreferencesModule() {
        "use strict";
        const STORAGE_KEY = "tfa_v2_workbench_layout_preferences";
        const LAYOUTS = Object.freeze(["split", "browser", "tasks", "recycle"]);
        const DEFAULT_PREFERENCES = Object.freeze({ splitRatio: 0.5, layout: "split" });
        function normalizeSplitRatio(value) {
          const ratio = Number(value);
          return Number.isFinite(ratio) ? Math.min(0.75, Math.max(0.25, ratio)) : DEFAULT_PREFERENCES.splitRatio;
        }
        function normalizeLayout(value) {
          const layout = String(value || "");
          return LAYOUTS.includes(layout) ? layout : DEFAULT_PREFERENCES.layout;
        }
        function normalizePreferences(value) {
          const input = value && typeof value === "object" ? value : {};
          return Object.freeze({ splitRatio: normalizeSplitRatio(input.splitRatio), layout: normalizeLayout(input.layout) });
        }
        function createLayoutPreferences({ storage } = {}) {
          let current = DEFAULT_PREFERENCES;
          let writeQueue = Promise.resolve(true);
          async function load() {
            if (!storage?.get) return current;
            try {
              const values = await storage.get(STORAGE_KEY);
              current = normalizePreferences(values?.[STORAGE_KEY]);
            } catch (_error) {
              current = DEFAULT_PREFERENCES;
            }
            return current;
          }
          function save(value) {
            current = normalizePreferences(value);
            if (!storage?.set) return Promise.resolve(false);
            const snapshot = current;
            const operation = writeQueue.then(async () => {
              try {
                await storage.set({ [STORAGE_KEY]: snapshot });
                return true;
              } catch (_error) {
                return false;
              }
            });
            writeQueue = operation.catch(() => false);
            return operation;
          }
          return Object.freeze({ load, save, get: () => current });
        }
        return Object.freeze({ STORAGE_KEY, LAYOUTS, DEFAULT_PREFERENCES, normalizeSplitRatio, normalizeLayout, normalizePreferences, createLayoutPreferences });
      });
    }
  });

  // src/content/v2-workbench-resizer.js
  var require_v2_workbench_resizer = __commonJS({
    "src/content/v2-workbench-resizer.js"(exports, module) {
      (function attachV2WorkbenchResizer(rootScope, factory) {
        const api = factory(rootScope);
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchResizer = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchResizerModule(rootScope) {
        "use strict";
        function mountWorkbenchResizer(options = {}) {
          const { workspace, divider, logic } = options;
          if (!workspace || !divider || !logic) throw new TypeError("Workbench resizer requires workspace, divider, and logic");
          const windowRef = options.window || divider.ownerDocument?.defaultView || rootScope.window;
          const ResizeObserverClass = options.ResizeObserver || rootScope.ResizeObserver;
          let layout = options.layout === "split" ? "split" : String(options.layout || "split");
          let preferredRatio = Number.isFinite(Number(options.ratio)) ? Number(options.ratio) : 0.5;
          let appliedRatio = preferredRatio;
          let pointerId = null;
          let destroyed = false;
          let resizeObserver = null;
          function width() {
            return Number(workspace.getBoundingClientRect?.().width) || 0;
          }
          function apply(value = preferredRatio, commit = false) {
            const workspaceWidth = width();
            appliedRatio = workspaceWidth > 0 ? logic.clampSplitRatio(value, workspaceWidth) : Math.min(0.75, Math.max(0.25, Number(value) || 0.5));
            if (commit) preferredRatio = appliedRatio;
            workspace.style?.setProperty?.("--v2-browser-width", `${appliedRatio * 100}%`);
            const bounds = workspaceWidth > 0 ? logic.splitRatioBounds(workspaceWidth) : { min: 0.25, max: 0.75 };
            if (layout === "split") {
              divider.setAttribute("aria-valuemin", String(Math.round(bounds.min * 100)));
              divider.setAttribute("aria-valuemax", String(Math.round(bounds.max * 100)));
              divider.setAttribute("aria-valuenow", String(Math.round(appliedRatio * 100)));
            } else ["aria-valuemin", "aria-valuemax", "aria-valuenow"].forEach((name) => divider.removeAttribute?.(name));
            return appliedRatio;
          }
          function syncVisibility() {
            const visible = layout === "split";
            const railVisible = layout !== "recycle";
            const setPaneVisibility = (element, shown) => {
              if (!element) return;
              element.hidden = !shown;
              element.inert = !shown;
              element.setAttribute("aria-hidden", String(!shown));
            };
            setPaneVisibility(options.browserPane, visible || layout === "browser");
            setPaneVisibility(options.taskPane, visible || layout === "tasks");
            setPaneVisibility(options.recyclePane, layout === "recycle");
            divider.hidden = !railVisible;
            divider.setAttribute("aria-hidden", String(!railVisible));
            divider.setAttribute("role", visible ? "separator" : "none");
            divider.tabIndex = visible ? 0 : -1;
            divider.querySelectorAll?.("[data-v2-divider-action]").forEach((button) => {
              const action = button.dataset.v2DividerAction;
              button.hidden = visible ? action === "restore-split" : action !== "restore-split";
            });
          }
          function applyPointer(event) {
            const rect = workspace.getBoundingClientRect?.();
            if (!rect?.width) return;
            apply((event.clientX - rect.left) / rect.width, true);
          }
          function finish(event) {
            if (pointerId == null || event?.pointerId != null && event.pointerId !== pointerId) return false;
            try {
              divider.releasePointerCapture?.(pointerId);
            } catch (_error) {
            }
            pointerId = null;
            divider.classList.remove("is-dragging");
            options.onRatioChange?.(preferredRatio, { source: "pointer" });
            return true;
          }
          function onPointerDown(event) {
            if (layout !== "split" || event.button != null && event.button !== 0) return;
            if (event.target?.closest?.("[data-v2-divider-action]")) return;
            pointerId = event.pointerId;
            divider.classList.add("is-dragging");
            divider.setPointerCapture?.(event.pointerId);
            applyPointer(event);
            event.preventDefault();
          }
          function onPointerMove(event) {
            if (pointerId == null || event.pointerId !== pointerId) return;
            applyPointer(event);
            event.preventDefault();
          }
          function onPointerUp(event) {
            if (finish(event)) event.preventDefault();
          }
          function onKeydown(event) {
            if (layout !== "split") return;
            const workspaceWidth = width();
            const bounds = workspaceWidth > 0 ? logic.splitRatioBounds(workspaceWidth) : { min: 0.25, max: 0.75 };
            const next = { ArrowLeft: appliedRatio - 0.03, ArrowRight: appliedRatio + 0.03, Home: bounds.min, End: bounds.max }[event.key];
            if (next == null) return;
            event.preventDefault();
            event.stopPropagation();
            apply(next, true);
            options.onRatioChange?.(preferredRatio, { source: "keyboard" });
          }
          function onClick(event) {
            const action = event.target?.closest?.("[data-v2-divider-action]")?.dataset?.v2DividerAction;
            const requested = { "collapse-browser": "tasks", "collapse-tasks": "browser", "restore-split": "split" }[action];
            if (!requested) return;
            options.onLayoutRequest?.(requested);
            if (requested === "split") divider.focus?.();
            else divider.querySelector?.('[data-v2-divider-action="restore-split"]')?.focus?.();
          }
          function update(next = {}) {
            if (destroyed) return appliedRatio;
            if (Object.hasOwn(next, "layout")) layout = String(next.layout || "split");
            if (Object.hasOwn(next, "ratio") && Number.isFinite(Number(next.ratio))) preferredRatio = Number(next.ratio);
            syncVisibility();
            return apply();
          }
          function destroy() {
            if (destroyed) return false;
            destroyed = true;
            finish();
            divider.removeEventListener("pointerdown", onPointerDown);
            divider.removeEventListener("pointermove", onPointerMove);
            divider.removeEventListener("pointerup", onPointerUp);
            divider.removeEventListener("pointercancel", onPointerUp);
            divider.removeEventListener("keydown", onKeydown);
            divider.removeEventListener("click", onClick);
            windowRef?.removeEventListener?.("blur", finish);
            resizeObserver?.disconnect?.();
            resizeObserver = null;
            return true;
          }
          divider.addEventListener("pointerdown", onPointerDown);
          divider.addEventListener("pointermove", onPointerMove);
          divider.addEventListener("pointerup", onPointerUp);
          divider.addEventListener("pointercancel", onPointerUp);
          divider.addEventListener("keydown", onKeydown);
          divider.addEventListener("click", onClick);
          windowRef?.addEventListener?.("blur", finish);
          if (typeof ResizeObserverClass === "function") {
            resizeObserver = new ResizeObserverClass(() => apply());
            resizeObserver.observe(workspace);
          }
          update({ layout, ratio: preferredRatio });
          return Object.freeze({ update, destroy, getRatio: () => appliedRatio, getPreferredRatio: () => preferredRatio });
        }
        return Object.freeze({ mountWorkbenchResizer });
      });
    }
  });

  // src/content/v2-workbench-menu.js
  var require_v2_workbench_menu = __commonJS({
    "src/content/v2-workbench-menu.js"(exports, module) {
      (function attachV2WorkbenchMenu(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchMenu = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchMenuModule() {
        "use strict";
        function createWorkbenchMenuController(options = {}) {
          const root = options.root;
          const ownerDocument = options.ownerDocument || null;
          if (!root || typeof root.addEventListener !== "function") {
            throw new TypeError("createWorkbenchMenuController requires an event root");
          }
          let openMenu = null;
          function current() {
            return openMenu;
          }
          function items(menu) {
            return [...menu.querySelectorAll('[role="menuitem"], [role="menuitemradio"]')].filter((item) => !item.disabled && !item.hidden);
          }
          function close(returnFocus = false) {
            if (!openMenu) return;
            const { menu, owner, trigger } = openMenu;
            menu.hidden = true;
            owner.classList.remove("has-open-menu");
            trigger.setAttribute("aria-expanded", "false");
            openMenu = null;
            if (returnFocus && trigger.isConnected) trigger.focus();
          }
          function toggle(trigger, menu, owner, preferredItem = null) {
            if (openMenu && openMenu.trigger === trigger) {
              close(true);
              return false;
            }
            close();
            menu.hidden = false;
            owner.classList.add("has-open-menu");
            trigger.setAttribute("aria-expanded", "true");
            openMenu = { trigger, menu, owner };
            const availableItems = items(menu);
            const focusTarget = availableItems.includes(preferredItem) ? preferredItem : availableItems[0];
            availableItems.forEach((item) => {
              item.tabIndex = item === focusTarget ? 0 : -1;
            });
            focusTarget?.focus();
            return true;
          }
          function position(trigger, menu, boundary, align = "start") {
            const boundaryRect = boundary.getBoundingClientRect();
            const triggerRect = trigger.getBoundingClientRect();
            const positioningParent = menu.offsetParent || menu.parentElement;
            const parentRect = positioningParent.getBoundingClientRect();
            const gap = 6;
            const inset = 8;
            menu.style.maxHeight = `${Math.max(80, boundaryRect.height - inset * 2)}px`;
            menu.style.overflowY = "auto";
            const width = menu.offsetWidth;
            const height = menu.offsetHeight;
            const minLeft = boundaryRect.left + inset;
            const maxLeft = Math.max(minLeft, boundaryRect.right - width - inset);
            const preferredLeft = align === "end" ? triggerRect.right - width : triggerRect.left;
            const left = Math.max(minLeft, Math.min(maxLeft, preferredLeft));
            const below = triggerRect.bottom + gap;
            const minTop = boundaryRect.top + inset;
            const maxTop = Math.max(minTop, boundaryRect.bottom - height - inset);
            const preferredTop = below + height <= boundaryRect.bottom - inset ? below : triggerRect.top - height - gap;
            const top = Math.max(minTop, Math.min(maxTop, preferredTop));
            menu.style.left = `${left - parentRect.left}px`;
            menu.style.top = `${top - parentRect.top}px`;
          }
          function onKeydown(event) {
            if (!openMenu) return;
            if (event.key === "Escape") {
              event.preventDefault();
              event.stopPropagation();
              close(true);
              return;
            }
            const movement = { ArrowDown: 1, ArrowUp: -1, Home: "first", End: "last" }[event.key];
            if (movement == null || !openMenu.menu.contains(event.target)) return;
            const availableItems = items(openMenu.menu);
            if (!availableItems.length) return;
            event.preventDefault();
            event.stopPropagation();
            const item = event.target.closest?.('[role="menuitem"], [role="menuitemradio"]') || event.target;
            const currentIndex = availableItems.indexOf(item);
            let nextIndex;
            if (movement === "first") nextIndex = 0;
            else if (movement === "last") nextIndex = availableItems.length - 1;
            else nextIndex = (Math.max(0, currentIndex) + movement + availableItems.length) % availableItems.length;
            availableItems.forEach((candidate, index) => {
              candidate.tabIndex = index === nextIndex ? 0 : -1;
            });
            availableItems[nextIndex].focus();
          }
          function onOutsideInteraction(event) {
            if (!openMenu) return;
            const path = typeof event.composedPath === "function" ? event.composedPath() : [];
            if (path.includes(openMenu.menu) || path.includes(openMenu.trigger) || openMenu.menu.contains(event.target) || openMenu.trigger.contains(event.target)) return;
            close();
          }
          root.addEventListener("click", onOutsideInteraction);
          root.addEventListener("keydown", onKeydown);
          if (ownerDocument) ownerDocument.addEventListener("pointerdown", onOutsideInteraction, true);
          return Object.freeze({
            current,
            close,
            toggle,
            position,
            destroy() {
              root.removeEventListener("click", onOutsideInteraction);
              root.removeEventListener("keydown", onKeydown);
              if (ownerDocument) ownerDocument.removeEventListener("pointerdown", onOutsideInteraction, true);
              close();
            }
          });
        }
        return Object.freeze({ createWorkbenchMenuController });
      });
    }
  });

  // src/content/v2-task-relation-menu.js
  var require_v2_task_relation_menu = __commonJS({
    "src/content/v2-task-relation-menu.js"(exports, module) {
      (function attachV2TaskRelationMenu(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2TaskRelationMenu = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2TaskRelationMenuModule() {
        "use strict";
        const CSS = `
.tfa-v2-relation-menu{display:grid;gap:2px;border-top:1px solid var(--v2-line);padding-top:4px;margin-top:2px}.tfa-v2-relation-menu[hidden],.tfa-v2-relation-targets[hidden]{display:none!important}.tfa-v2-relation-targets{display:grid;gap:2px;max-height:min(240px,42vh);overflow:auto}.tfa-v2-relation-heading{padding:4px 8px;color:var(--v2-faint);font-size:9px;line-height:1.35}.tfa-v2-relation-primary{display:inline-flex;align-items:center;gap:3px;padding:1px 5px;border:1px solid color-mix(in srgb,var(--v2-accent) 30%,transparent);border-radius:999px;color:var(--v2-accent);font-size:9px;white-space:nowrap}.tfa-v2-relation-targets button.is-related:after{content:'\\2713';float:right;color:var(--v2-accent)}
.tfa-v2-task-relation-suggestion{display:grid;gap:5px;margin:0 8px 7px;padding-top:6px;border-top:1px dashed var(--v2-line)}.tfa-v2-task-relation-suggestion>small{color:var(--v2-muted);font-size:9px;line-height:1.35;overflow-wrap:anywhere}.tfa-v2-suggestion.is-multi-associate .tfa-v2-suggestion-candidate{flex-wrap:wrap}.tfa-v2-suggestion.is-multi-associate .tfa-v2-suggestion-reasons{flex:1 1 120px}.tfa-v2-suggestion-actions.is-inline{margin-left:auto}.tfa-v2-suggestion-actions.is-inline button{min-height:25px;padding:0 6px}@container taskpane (max-width:560px){.tfa-v2-suggestion-actions.is-inline{width:100%;margin-left:0}.tfa-v2-suggestion-actions.is-inline button{flex:1 1 72px}}
`;
        function comparableUrl(value) {
          try {
            const url = new URL(String(value || ""));
            url.hash = "";
            return url.href;
          } catch (_error) {
            return String(value || "").split("#")[0];
          }
        }
        function pageOf(task, tab) {
          const pages = task?.pages || task?.tabs || [];
          const id = String(tab?.pageId || tab?.id || "");
          const url = comparableUrl(tab?.url || tab?.restoreUrl);
          return pages.find((page) => {
            const pageId = String(page?.pageId || page?.id || "");
            return id.startsWith("page-") && id === pageId || url && url === comparableUrl(page?.url || page?.restoreUrl);
          }) || null;
        }
        function relationContext(tab, tasks = [], currentTask = null) {
          const relations = tasks.map((task) => ({ task, page: pageOf(task, tab) })).filter((item) => item.page);
          const relatedTaskIds = new Set(relations.map((item) => String(item.task.id)));
          const primary = relations.find((item) => item.page.isPrimary === true || item.page.role === "primary") || null;
          const current = currentTask ? relations.find((item) => String(item.task.id) === String(currentTask.id)) : null;
          return {
            relations,
            relatedTaskIds,
            primaryTaskId: String(primary?.task?.id || ""),
            pageId: String(current?.page?.pageId || current?.page?.id || primary?.page?.pageId || primary?.page?.id || ""),
            currentIsPrimary: Boolean(current && String(current.task.id) === String(primary?.task?.id))
          };
        }
        function createTaskRelationMenu({ menu, tr, escapeHtml } = {}) {
          if (!menu || typeof menu.insertAdjacentHTML !== "function") throw new TypeError("Task relation menu requires a menu root");
          const translate = typeof tr === "function" ? tr : (_key, fallback) => fallback;
          const escape = typeof escapeHtml === "function" ? escapeHtml : (value) => String(value || "");
          menu.insertAdjacentHTML("beforeend", '<div class="tfa-v2-relation-menu" data-v2-relation-menu hidden></div>');
          const host = menu.querySelector("[data-v2-relation-menu]");
          let prepared = null;
          function taskButton(task, mode, related) {
            const title = task.title || task.name || translate("task.untitled", "\u672A\u547D\u540D\u4EFB\u52A1");
            return `<button type="button" data-v2-relation-target="${escape(task.id)}" data-v2-relation-mode="${mode}" role="menuitem" class="${related ? "is-related" : ""}">${escape(title)}</button>`;
          }
          function renderMain() {
            if (!prepared) return;
            const { context, currentTask, tasks } = prepared;
            const sourceTaskId = String(currentTask?.id || context.primaryTaskId || "");
            const moveTargets = tasks.filter((task) => String(task.id) !== sourceTaskId);
            const shareTargets = tasks.filter((task) => !context.relatedTaskIds.has(String(task.id)));
            const canSetPrimary = Boolean(currentTask && context.relations.length > 1 && !context.currentIsPrimary);
            const hasRelations = context.relations.length > 0;
            host.hidden = !tasks.length;
            host.innerHTML = [
              !hasRelations && tasks.length ? `<button type="button" data-v2-relation-open="assign" role="menuitem">${escape(translate("task.relation.assign", "\u52A0\u5165\u4EFB\u52A1\u2026"))}</button>` : "",
              hasRelations && moveTargets.length ? `<button type="button" data-v2-relation-open="move" role="menuitem">${escape(translate("task.relation.move", "\u79FB\u52A8\u5230\u4EFB\u52A1\u2026"))}</button>` : "",
              hasRelations && shareTargets.length ? `<button type="button" data-v2-relation-open="share" role="menuitem">${escape(translate("task.relation.share", "\u540C\u65F6\u5173\u8054\u4EFB\u52A1\u2026"))}</button>` : "",
              canSetPrimary ? `<button type="button" data-v2-relation-primary="${escape(currentTask.id)}" role="menuitem">${escape(translate("task.relation.makePrimary", "\u8BBE\u4E3A\u4E3B\u8981\u4EFB\u52A1"))}</button>` : "",
              '<div class="tfa-v2-relation-targets" data-v2-relation-targets hidden></div>'
            ].join("");
          }
          function prepare(tab, tasks, currentTask) {
            prepared = { tab, tasks: Array.isArray(tasks) ? tasks : [], currentTask: currentTask || null };
            prepared.context = relationContext(tab, prepared.tasks, prepared.currentTask);
            renderMain();
            return prepared.context;
          }
          function showTargets(mode) {
            if (!prepared || !["assign", "move", "share"].includes(mode)) return false;
            const { tasks, currentTask, context } = prepared;
            const sourceTaskId = String(currentTask?.id || context.primaryTaskId || "");
            const targets = tasks.filter((task) => mode === "assign" || (mode === "move" ? String(task.id) !== sourceTaskId : !context.relatedTaskIds.has(String(task.id))));
            const list = host.querySelector("[data-v2-relation-targets]");
            host.querySelectorAll(":scope > button").forEach((button) => {
              button.hidden = true;
            });
            list.hidden = false;
            list.innerHTML = `<button type="button" data-v2-relation-back role="menuitem">${escape(translate("common.back", "\u8FD4\u56DE"))}</button><span class="tfa-v2-relation-heading">${escape(translate(`task.relation.${mode}Hint`, mode === "move" ? "\u76EE\u6807\u5C06\u6210\u4E3A\u4E3B\u8981\u4EFB\u52A1\uFF1B\u5F53\u524D\u4EFB\u52A1\u5173\u7CFB\u4F1A\u79FB\u9664\uFF0C\u771F\u5B9E\u9875\u7B7E\u4E0D\u53D7\u5F71\u54CD\u3002" : mode === "share" ? "\u4FDD\u7559\u5F53\u524D\u4E3B\u8981\u4EFB\u52A1\uFF0C\u5E76\u65B0\u589E\u4E00\u4E2A\u5173\u8054\u4EFB\u52A1\u3002" : "\u9009\u62E9\u9875\u9762\u7684\u4E3B\u8981\u4EFB\u52A1\u3002"))}</span>${targets.map((task) => taskButton(task, mode, context.relatedTaskIds.has(String(task.id)))).join("")}`;
            list.querySelector("button")?.focus();
            return true;
          }
          function showDropChoice(tab, tasks, sourceTask, targetTask) {
            prepared = { tab, tasks, currentTask: sourceTask, context: relationContext(tab, tasks, sourceTask), dropTarget: targetTask };
            host.hidden = false;
            host.innerHTML = `<span class="tfa-v2-relation-heading">${escape(translate("task.relation.dropChoice", "\u9009\u62E9\u5982\u4F55\u52A0\u5165\u201C{task}\u201D", { task: targetTask.title || targetTask.name || "" }))}</span><button type="button" data-v2-relation-target="${escape(targetTask.id)}" data-v2-relation-mode="move" role="menuitem">${escape(translate("task.relation.moveHere", "\u79FB\u52A8\u5230\u6B64\u4EFB\u52A1"))}</button><button type="button" data-v2-relation-target="${escape(targetTask.id)}" data-v2-relation-mode="share" role="menuitem">${escape(translate("task.relation.shareHere", "\u540C\u65F6\u5173\u8054\u6B64\u4EFB\u52A1"))}</button>`;
            return prepared;
          }
          function actionFor(target) {
            if (!prepared || !target) return null;
            const primary = target.closest("[data-v2-relation-primary]");
            if (primary) return { type: "primary", tab: prepared.tab, pageId: prepared.context.pageId, sourceTask: prepared.currentTask, targetTask: prepared.currentTask };
            const choice = target.closest("[data-v2-relation-target]");
            if (!choice) return null;
            const targetTask = prepared.tasks.find((task) => String(task.id) === String(choice.dataset.v2RelationTarget));
            if (!targetTask) return null;
            return {
              type: choice.dataset.v2RelationMode,
              tab: prepared.tab,
              pageId: prepared.context.pageId,
              sourceTask: prepared.currentTask || prepared.tasks.find((task) => String(task.id) === prepared.context.primaryTaskId) || null,
              targetTask
            };
          }
          function handleNavigation(target) {
            const open = target?.closest?.("[data-v2-relation-open]");
            if (open) return showTargets(open.dataset.v2RelationOpen);
            if (target?.closest?.("[data-v2-relation-back]")) {
              renderMain();
              host.querySelector("[data-v2-relation-open]")?.focus();
              return true;
            }
            return false;
          }
          return Object.freeze({ prepare, showDropChoice, actionFor, handleNavigation, relationContext, destroy() {
            host.remove();
            prepared = null;
          } });
        }
        return Object.freeze({ CSS, comparableUrl, relationContext, createTaskRelationMenu });
      });
    }
  });

  // src/content/v2-task-dialog.js
  var require_v2_task_dialog = __commonJS({
    "src/content/v2-task-dialog.js"(exports, module) {
      (function attachV2TaskDialog(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2TaskDialog = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2TaskDialogModule() {
        "use strict";
        const DOMAINS = Object.freeze(["work", "study", "life", "interest", "admin", "other"]);
        const FALLBACK = Object.freeze({
          createTitle: "\u65B0\u5EFA\u4EFB\u52A1",
          renameTitle: "\u91CD\u547D\u540D\u4EFB\u52A1",
          titleLabel: "\u4EFB\u52A1\u540D\u79F0",
          titlePlaceholder: "\u8F93\u5165\u4EFB\u52A1\u540D\u79F0",
          domainLabel: "\u6240\u5C5E\u9886\u57DF",
          cancel: "\u53D6\u6D88",
          create: "\u521B\u5EFA\u4EFB\u52A1",
          save: "\u4FDD\u5B58",
          saving: "\u4FDD\u5B58\u4E2D\u2026",
          required: "\u8BF7\u8F93\u5165\u4EFB\u52A1\u540D\u79F0",
          failed: "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5",
          work: "\u5DE5\u4F5C",
          study: "\u5B66\u4E60",
          life: "\u751F\u6D3B",
          interest: "\u5174\u8DA3",
          admin: "\u4E8B\u52A1",
          other: "\u5176\u4ED6"
        });
        let dialogSequence = 0;
        function createV2TaskDialog({ document: document2, root, t = (key) => key, onSubmit } = {}) {
          if (!document2 || typeof document2.createElement !== "function" || !root || typeof root.appendChild !== "function" || typeof onSubmit !== "function") {
            throw new TypeError("V2 task dialog requires document, root and onSubmit");
          }
          const tr = (key, fallback) => {
            try {
              const value = t(key);
              return value && value !== key ? String(value) : fallback;
            } catch (_) {
              return fallback;
            }
          };
          const make = (tag, className, text) => {
            const node = document2.createElement(tag);
            if (className) node.className = className;
            if (text != null) node.textContent = text;
            return node;
          };
          const style = make("style");
          style.textContent = `
.tfa-task-dialog-layer{position:fixed;inset:0;z-index:2147483646;display:grid;place-items:center;padding:24px;background:var(--tfa-backdrop-bg,rgba(15,23,42,.46))}
.tfa-task-dialog-layer[hidden]{display:none}.tfa-task-dialog{width:min(440px,calc(100vw - 32px));padding:22px;border:1px solid var(--tfa-panel-border,#dbe2ee);border-radius:var(--tfa-radius-lg,18px);background:var(--tfa-panel-bg,#fff);color:var(--tfa-text-primary,#172033);box-shadow:var(--tfa-panel-shadow,0 22px 60px rgba(15,23,42,.22))}
.tfa-task-dialog h2{margin:0 0 18px;font-size:18px;line-height:1.35}.tfa-task-dialog label,.tfa-task-domain-label{display:block;margin:0 0 8px;font-size:13px;font-weight:650;color:var(--tfa-text-secondary,#526078)}
.tfa-task-title{box-sizing:border-box;width:100%;height:42px;padding:0 12px;border:1px solid var(--tfa-input-border,#ccd5e3);border-radius:var(--tfa-radius-sm,10px);outline:none;background:var(--tfa-input-bg,#f7f9fc);color:inherit;font:inherit}
.tfa-task-title:focus-visible,.tfa-task-domain:focus-visible,.tfa-task-action:focus-visible{outline:2px solid var(--tfa-accent,#7656e8);outline-offset:2px}.tfa-task-domains{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:8px}
.tfa-task-domain,.tfa-task-action{min-height:38px;border:1px solid var(--tfa-border-soft,#dbe2ee);border-radius:var(--tfa-radius-sm,10px);background:var(--tfa-btn-bg,#f6f8fb);color:inherit;font:inherit;cursor:pointer}.tfa-task-domain[aria-checked=true]{border-color:var(--tfa-accent,#7656e8);background:color-mix(in srgb,var(--tfa-accent,#7656e8) 14%,var(--tfa-panel-bg,#fff));color:var(--tfa-accent,#7656e8);font-weight:700}
.tfa-task-domain:hover,.tfa-task-action:hover{background:var(--tfa-btn-hover-bg,#eef1f7)}.tfa-task-domain:disabled,.tfa-task-action:disabled,.tfa-task-title:disabled{cursor:not-allowed;opacity:.58}.tfa-task-error{min-height:18px;margin:9px 0 0;color:var(--tfa-danger,#d33b4b);font-size:12px}.tfa-task-error[hidden]{visibility:hidden}
.tfa-task-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:18px}.tfa-task-action{min-width:82px;padding:0 16px}.tfa-task-confirm{border-color:var(--tfa-accent,#7656e8);background:var(--tfa-accent,#7656e8);color:#fff}.tfa-task-confirm:hover{filter:brightness(1.04)}
@media(max-width:520px){.tfa-task-dialog-layer{padding:12px}.tfa-task-domains{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(prefers-reduced-motion:reduce){.tfa-task-dialog-layer *{scroll-behavior:auto!important;transition:none!important}}
`;
          const layer = make("div", "tfa-task-dialog-layer");
          layer.hidden = true;
          const dialog = make("section", "tfa-task-dialog");
          const heading = make("h2");
          const headingId = `tfaTaskDialogTitle${++dialogSequence}`;
          heading.id = headingId;
          dialog.setAttribute("role", "dialog");
          dialog.setAttribute("aria-modal", "true");
          dialog.setAttribute("aria-labelledby", headingId);
          const form = make("form");
          const titleLabel = make("label", "", tr("taskDialogTitleLabel", FALLBACK.titleLabel));
          const input = make("input", "tfa-task-title");
          input.type = "text";
          input.maxLength = 30;
          input.autocomplete = "off";
          input.placeholder = tr("taskDialogTitlePlaceholder", FALLBACK.titlePlaceholder);
          const inputId = `${headingId}Input`;
          input.id = inputId;
          titleLabel.setAttribute("for", inputId);
          const domainLabel = make("div", "tfa-task-domain-label", tr("taskDialogDomainLabel", FALLBACK.domainLabel));
          const domains = make("div", "tfa-task-domains");
          domains.setAttribute("role", "radiogroup");
          domains.setAttribute("aria-label", domainLabel.textContent);
          const domainButtons = DOMAINS.map((domain) => {
            const button = make("button", "tfa-task-domain", tr(`taskDomain_${domain}`, FALLBACK[domain]));
            button.type = "button";
            button.dataset.domain = domain;
            button.setAttribute("role", "radio");
            button.setAttribute("aria-checked", "false");
            domains.appendChild(button);
            return button;
          });
          const error = make("div", "tfa-task-error");
          error.setAttribute("role", "alert");
          error.hidden = true;
          const actions = make("div", "tfa-task-actions");
          const cancel = make("button", "tfa-task-action", tr("commonCancel", FALLBACK.cancel));
          cancel.type = "button";
          cancel.dataset.action = "cancel";
          const confirm = make("button", "tfa-task-action tfa-task-confirm");
          confirm.type = "submit";
          confirm.dataset.action = "confirm";
          actions.appendChild(cancel);
          actions.appendChild(confirm);
          form.appendChild(titleLabel);
          form.appendChild(input);
          form.appendChild(domainLabel);
          form.appendChild(domains);
          form.appendChild(error);
          form.appendChild(actions);
          dialog.appendChild(heading);
          dialog.appendChild(form);
          layer.appendChild(dialog);
          root.appendChild(style);
          root.appendChild(layer);
          const focusables = [input, ...domainButtons, cancel, confirm];
          let opened = false;
          let pending = false;
          let destroyed = false;
          let selectedDomain = "work";
          let mode = "create";
          let previousFocus = null;
          let operation = 0;
          const setError = (message = "") => {
            error.textContent = message;
            error.hidden = !message;
          };
          function selectDomain(domain) {
            selectedDomain = DOMAINS.includes(domain) ? domain : "work";
            domainButtons.forEach((button) => button.setAttribute("aria-checked", String(button.dataset.domain === selectedDomain)));
          }
          function setPending(value) {
            pending = value;
            focusables.forEach((node) => {
              node.disabled = value;
            });
            confirm.textContent = value ? tr("taskDialogSaving", FALLBACK.saving) : tr(mode === "rename" ? "taskDialogSave" : "taskDialogCreate", mode === "rename" ? FALLBACK.save : FALLBACK.create);
          }
          function closeInternal(restoreFocus = true) {
            if (!opened) return false;
            operation += 1;
            opened = false;
            layer.hidden = true;
            setPending(false);
            setError();
            if (restoreFocus && previousFocus?.isConnected && typeof previousFocus.focus === "function") previousFocus.focus();
            previousFocus = null;
            return true;
          }
          function requestClose() {
            if (!pending) closeInternal(true);
          }
          async function submit() {
            if (pending || !opened) return;
            const title = String(input.value || "").trim().slice(0, 30);
            if (!title) {
              setError(tr("taskDialogRequired", FALLBACK.required));
              input.focus();
              return;
            }
            setError();
            setPending(true);
            const token = ++operation;
            try {
              await onSubmit({ title, domain: selectedDomain, mode });
              if (opened && operation === token) closeInternal(true);
            } catch (_) {
              if (opened && operation === token) {
                setPending(false);
                setError(tr("taskDialogSubmitFailed", FALLBACK.failed));
                input.focus();
              }
            }
          }
          function onKeydown(event) {
            if (!opened) return;
            if (event.key === "Escape") {
              event.preventDefault();
              requestClose();
              return;
            }
            if (event.key !== "Tab" || pending) return;
            const available = focusables.filter((node) => !node.disabled && !node.hidden);
            const index = available.indexOf(document2.activeElement);
            if (index < 0) {
              event.preventDefault();
              available[0]?.focus();
            } else if (event.shiftKey && index === 0) {
              event.preventDefault();
              available.at(-1)?.focus();
            } else if (!event.shiftKey && index === available.length - 1) {
              event.preventDefault();
              available[0]?.focus();
            }
          }
          layer.addEventListener("click", (event) => {
            if (event.target === layer) requestClose();
          });
          layer.addEventListener("keydown", onKeydown);
          cancel.addEventListener("click", requestClose);
          form.addEventListener("submit", (event) => {
            event.preventDefault();
            submit();
          });
          domainButtons.forEach((button) => button.addEventListener("click", () => {
            if (!pending) selectDomain(button.dataset.domain);
          }));
          return Object.freeze({
            open(options = {}) {
              if (destroyed) return false;
              if (!opened) previousFocus = document2.activeElement;
              operation += 1;
              mode = options.mode === "rename" ? "rename" : "create";
              opened = true;
              layer.hidden = false;
              heading.textContent = tr(mode === "rename" ? "taskDialogRenameTitle" : "taskDialogCreateTitle", mode === "rename" ? FALLBACK.renameTitle : FALLBACK.createTitle);
              input.value = String(options.title || "").slice(0, 30);
              selectDomain(options.domain);
              setPending(false);
              setError();
              input.focus();
              if (typeof input.select === "function") input.select();
              return true;
            },
            close() {
              return closeInternal(true);
            },
            destroy() {
              if (destroyed) return;
              closeInternal(false);
              destroyed = true;
              layer.remove();
              style.remove();
            },
            isOpen() {
              return opened;
            }
          });
        }
        return Object.freeze({ DOMAINS, createV2TaskDialog });
      });
    }
  });

  // src/content/v2-task-trash-coordinator.js
  var require_v2_task_trash_coordinator = __commonJS({
    "src/content/v2-task-trash-coordinator.js"(exports, module) {
      (function attachV2TaskTrashCoordinator(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        if (rootScope) rootScope.TfaV2TaskTrashCoordinator = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2TaskTrashCoordinatorModule() {
        "use strict";
        function stableDissolveToken(task = {}) {
          const id = String(task.id || "").trim();
          const updatedAt = Number(task.updatedAt);
          if (!id || !Number.isFinite(updatedAt)) throw new TypeError("Task id and updatedAt are required");
          return `dissolve:${id}:${updatedAt}`;
        }
        function succeeded(response) {
          return response === true || Boolean(response && response.ok !== false && !response.error);
        }
        function failure(response, fallback) {
          return String(response?.error || response?.message || fallback);
        }
        function replacementsFor(task = {}) {
          return Object.fromEntries((Array.isArray(task.pages) ? task.pages : []).map((page) => [page, (Array.isArray(page.relatedTaskIds) ? page.relatedTaskIds : []).filter((taskId) => String(taskId) !== String(task.id))]).filter(([page, alternatives]) => page.isPrimary === true && alternatives.length === 1).map(([page, alternatives]) => [page.pageId || page.id, alternatives[0]]));
        }
        function createV2TaskTrashCoordinator(deps = {}) {
          const required = ["addTaskToTrash", "updateTaskTrashOperation", "getTaskTrashOperations", "deleteTask", "restoreTask", "undoLast"];
          required.forEach((name) => {
            if (typeof deps[name] !== "function") throw new TypeError(`Task trash coordinator requires ${name}`);
          });
          async function setPhase(operationToken, phase, id) {
            try {
              const response = await deps.updateTaskTrashOperation(operationToken, phase, id);
              return { ok: succeeded(response), response, uncertain: false };
            } catch (error) {
              return { ok: false, error, uncertain: true };
            }
          }
          async function dissolve(task, replacements = {}) {
            const operationToken = stableDissolveToken(task);
            let prepared;
            try {
              prepared = await deps.addTaskToTrash(task, operationToken, { prepared: true });
            } catch (error) {
              return { ok: false, outcome: "prepare-unknown", stage: "prepare", uncertain: true, operationToken, error };
            }
            if (!succeeded(prepared)) {
              return { ok: false, outcome: "prepare-failed", stage: "prepare", uncertain: false, operationToken, error: failure(prepared, "Task trash prepare failed") };
            }
            let deleted;
            try {
              deleted = await deps.deleteTask(task.id, replacements, operationToken);
            } catch (error) {
              return { ok: false, outcome: "delete-unknown", stage: "delete", uncertain: true, operationToken, phase: "prepared", error };
            }
            if (!succeeded(deleted)) {
              const rollback = await setPhase(operationToken, "remove", prepared.id);
              return {
                ok: false,
                outcome: "delete-failed",
                stage: "delete",
                uncertain: false,
                operationToken,
                rolledBack: rollback.ok,
                compensationPending: !rollback.ok,
                error: failure(deleted, "Task delete failed")
              };
            }
            if (deleted.undone === true) {
              const cleanup = await setPhase(operationToken, "remove", prepared.id);
              return {
                ok: true,
                outcome: "undone",
                changed: false,
                operationToken,
                cleanupPending: !cleanup.ok,
                deleteResponse: deleted
              };
            }
            const committed = await setPhase(operationToken, "ready", prepared.id);
            return {
              ok: true,
              outcome: "dissolved",
              changed: true,
              operationToken,
              trashReady: committed.ok,
              cleanupPending: !committed.ok,
              deleteResponse: deleted
            };
          }
          async function restore(item = {}) {
            const operationToken = String(item.operationKey || "").trim();
            if (!item.id || !item.task) return { ok: false, outcome: "invalid", stage: "restore", uncertain: false };
            if (operationToken) {
              const started = await setPhase(operationToken, "restoring", item.id);
              if (!started.ok) {
                return { ok: false, outcome: "restore-prepare-failed", stage: "restore-prepare", uncertain: started.uncertain, operationToken };
              }
            }
            let response;
            try {
              response = await deps.restoreTask(item.task, item.id);
            } catch (error) {
              return {
                ok: false,
                outcome: "restore-unknown",
                stage: "restore",
                uncertain: true,
                operationToken,
                phase: operationToken ? "restoring" : "legacy",
                error
              };
            }
            if (!succeeded(response)) {
              const released = operationToken ? await setPhase(operationToken, "ready", item.id) : { ok: false };
              return {
                ok: false,
                outcome: "restore-failed",
                stage: "restore",
                uncertain: false,
                operationToken,
                retryReady: released.ok,
                cleanupPending: Boolean(operationToken) && !released.ok,
                error: failure(response, "Task restore failed")
              };
            }
            const removed = operationToken ? await setPhase(operationToken, "remove", item.id) : { ok: false };
            if (response.consumed === true) {
              return {
                ok: true,
                outcome: "consumed",
                restored: false,
                operationToken,
                cleanupPending: !operationToken || !removed.ok,
                legacyCleanupRequired: !operationToken,
                restoreResponse: response
              };
            }
            if (response.existing === true) {
              return {
                ok: true,
                outcome: "already-restored",
                restored: false,
                operationToken,
                cleanupPending: !operationToken || !removed.ok,
                legacyCleanupRequired: !operationToken,
                restoreResponse: response
              };
            }
            return {
              ok: true,
              outcome: "restored",
              restored: true,
              operationToken,
              cleanupPending: !operationToken || !removed.ok,
              legacyCleanupRequired: !operationToken,
              restoreResponse: response
            };
          }
          async function undo() {
            let response;
            try {
              response = await deps.undoLast();
            } catch (error) {
              return { ok: false, outcome: "undo-unknown", uncertain: true, error };
            }
            if (!succeeded(response)) {
              return { ok: false, outcome: "undo-failed", uncertain: false, error: failure(response, "Task undo failed") };
            }
            const compensation = response.trashCompensation;
            if (compensation?.action !== "remove" || !compensation.operationToken) {
              return { ok: true, outcome: "undone", compensationRequired: false, undoResponse: response };
            }
            const applied = await setPhase(compensation.operationToken, "remove");
            return {
              ok: true,
              outcome: "undone",
              compensationRequired: true,
              operationToken: compensation.operationToken,
              compensationApplied: applied.ok,
              compensationPending: !applied.ok,
              undoResponse: response
            };
          }
          async function reconcile(tasks = []) {
            let response;
            try {
              response = await deps.getTaskTrashOperations();
            } catch (error) {
              return { ok: false, uncertain: true, error, results: [] };
            }
            if (!succeeded(response) || !Array.isArray(response.operations)) {
              return { ok: false, uncertain: false, error: failure(response, "Task trash reconcile unavailable"), results: [] };
            }
            const liveTasks = new Map((Array.isArray(tasks) ? tasks : []).map((task) => [String(task.id), task]));
            const results = [];
            for (const item of response.operations) {
              const operationToken = String(item?.operationKey || "").trim();
              const live = item?.task ? liveTasks.get(String(item.task.id)) : null;
              const sameLiveTask = Boolean(live && Number(live.updatedAt) === Number(item.task.updatedAt));
              if (!operationToken || !item?.task) {
                results.push({ id: item?.id, outcome: "skipped" });
                continue;
              }
              if (sameLiveTask && ["prepared", "ready"].includes(item.operationPhase)) {
                const removed = await setPhase(operationToken, "remove", item.id);
                results.push({ id: item.id, outcome: removed.ok ? "ghost-removed" : "ghost-cleanup-pending" });
                continue;
              }
              if (item.operationPhase === "prepared") {
                let deleted;
                try {
                  deleted = await deps.deleteTask(item.task.id, replacementsFor(item.task), operationToken);
                } catch (_error) {
                  results.push({ id: item.id, outcome: "delete-unknown" });
                  continue;
                }
                const phase = succeeded(deleted) && deleted.undone !== true ? "ready" : deleted?.undone === true ? "remove" : "ready";
                const settled = await setPhase(operationToken, phase, item.id);
                results.push({ id: item.id, outcome: settled.ok ? `prepared-${phase}` : "prepared-pending" });
                continue;
              }
              if (item.operationPhase === "restoring") {
                let restored;
                try {
                  restored = await deps.restoreTask(item.task, item.id);
                } catch (_error) {
                  results.push({ id: item.id, outcome: "restore-unknown" });
                  continue;
                }
                const phase = succeeded(restored) ? "remove" : "ready";
                const settled = await setPhase(operationToken, phase, item.id);
                results.push({
                  id: item.id,
                  outcome: settled.ok ? restored?.consumed === true ? "restore-consumed" : `restoring-${phase}` : "restoring-pending"
                });
                continue;
              }
              results.push({ id: item.id, outcome: "skipped" });
            }
            return { ok: true, uncertain: false, results };
          }
          return Object.freeze({ dissolve, restore, undo, reconcile });
        }
        return Object.freeze({ createV2TaskTrashCoordinator, stableDissolveToken });
      });
    }
  });

  // src/content/v2-suggestion-controller.js
  var require_v2_suggestion_controller = __commonJS({
    "src/content/v2-suggestion-controller.js"(exports, module) {
      (function attachV2SuggestionController(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        if (rootScope) rootScope.TfaV2SuggestionController = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2SuggestionControllerModule() {
        "use strict";
        const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/;
        const PAGE_BATCH_SIZE = 100;
        const MAX_RESOLVE_MANY = 50;
        function succeeded(response) {
          return response === true || Boolean(response && response.ok !== false && !response.error);
        }
        function responseError(response, fallback) {
          const error = new Error(String(response?.error || response?.message || fallback));
          if (response?.code) error.code = response.code;
          return error;
        }
        function ids(value) {
          if (!Array.isArray(value)) throw new TypeError("Suggestion context pageIds must be an array");
          const seen = /* @__PURE__ */ new Set();
          return value.reduce((result, item) => {
            if (typeof item !== "string") throw new TypeError("Suggestion context pageIds must contain strings");
            const pageId = item.trim();
            if (!pageId.startsWith("page-") || !SAFE_ID.test(pageId)) throw new TypeError("Invalid suggestion context pageId");
            if (!seen.has(pageId)) {
              seen.add(pageId);
              result.push(pageId);
            }
            return result;
          }, []);
        }
        function suggestionId(value) {
          const id = String(value == null ? "" : value).trim();
          if (!id.startsWith("suggestion-") || !SAFE_ID.test(id)) throw new TypeError("Invalid suggestionId");
          return id;
        }
        function suggestionIds(value) {
          if (!Array.isArray(value)) throw new TypeError("Suggestion ids must be an array");
          const result = [], seen = /* @__PURE__ */ new Set();
          value.forEach((value2) => {
            const id = suggestionId(value2);
            if (!seen.has(id)) {
              seen.add(id);
              result.push(id);
            }
          });
          if (result.length > MAX_RESOLVE_MANY) throw new RangeError(`At most ${MAX_RESOLVE_MANY} suggestions can be resolved at once`);
          return result;
        }
        function createV2SuggestionController(deps = {}) {
          const taskApi = deps.taskApi;
          const buildSuggestionViewBlocks = deps.buildSuggestionViewBlocks;
          ["refreshSuggestions", "listSuggestions", "resolveSuggestion", "undoSuggestion"].forEach((name) => {
            if (!taskApi || typeof taskApi[name] !== "function") throw new TypeError(`Suggestion controller requires taskApi.${name}`);
          });
          if (typeof buildSuggestionViewBlocks !== "function") {
            throw new TypeError("Suggestion controller requires buildSuggestionViewBlocks");
          }
          const now = typeof deps.now === "function" ? deps.now : Date.now;
          const pending = /* @__PURE__ */ new Map();
          let context = Object.freeze({ pages: Object.freeze([]), tasks: Object.freeze([]), pageIds: Object.freeze([]) });
          let blocks = Object.freeze([]);
          let requestToken = 0;
          let lifecycle = 0;
          let loading = false;
          let destroyed = false;
          let mutationReloadPromise = null;
          let mutationVersion = 0;
          let mutationReloadTarget = 0;
          let activeBatchCount = 0;
          let batchReloadNeeded = false;
          let batchReloadDeferred = null;
          function current(token, epoch) {
            return !destroyed && token === requestToken && epoch === lifecycle;
          }
          function report(error, details) {
            try {
              deps.onError?.(error, Object.freeze({ ...details }));
            } catch (_error) {
            }
          }
          function publish(nextBlocks) {
            blocks = Object.freeze(Array.isArray(nextBlocks) ? nextBlocks.slice() : []);
            try {
              deps.onChange?.(blocks);
            } catch (_error) {
            }
            return blocks;
          }
          async function load(token, epoch, snapshot) {
            let phase = "refresh";
            try {
              const batches = [];
              for (let index = 0; index < snapshot.pageIds.length; index += PAGE_BATCH_SIZE) {
                batches.push(snapshot.pageIds.slice(index, index + PAGE_BATCH_SIZE));
              }
              for (const batch of batches) {
                const refreshed = await taskApi.refreshSuggestions(batch);
                if (!current(token, epoch)) return false;
                if (!succeeded(refreshed)) throw responseError(refreshed, "Suggestion refresh failed");
              }
              phase = "list";
              const suggestions = [];
              for (const batch of batches) {
                const listed = await taskApi.listSuggestions(batch);
                if (!current(token, epoch)) return false;
                if (!succeeded(listed)) throw responseError(listed, "Suggestion list failed");
                if (Array.isArray(listed.suggestions)) suggestions.push(...listed.suggestions);
              }
              phase = "build";
              const nextBlocks = buildSuggestionViewBlocks({
                suggestions,
                pages: snapshot.pages,
                tasks: snapshot.tasks,
                pageIds: snapshot.pageIds,
                now: Number(now())
              });
              if (!current(token, epoch)) return false;
              loading = false;
              return publish(nextBlocks);
            } catch (error) {
              if (!current(token, epoch)) return false;
              loading = false;
              report(error, { phase });
              return false;
            }
          }
          function reload() {
            if (destroyed) return Promise.resolve(false);
            const token = ++requestToken, epoch = lifecycle, snapshot = context;
            loading = true;
            return load(token, epoch, snapshot);
          }
          function setContext(next = {}) {
            if (destroyed) return Promise.resolve(false);
            if (!Array.isArray(next.pages) || !Array.isArray(next.tasks)) {
              throw new TypeError("Suggestion context requires pages and tasks arrays");
            }
            context = Object.freeze({
              pages: Object.freeze(next.pages.map((page) => Object.freeze({ ...page }))),
              tasks: Object.freeze(next.tasks.map((task) => Object.freeze({ ...task }))),
              pageIds: Object.freeze(ids(next.pageIds))
            });
            return reload();
          }
          function mutationResult(ok, code = null) {
            return Object.freeze({ ok: ok === true, code: ok === true ? null : String(code || "FAILED") });
          }
          function resultCode(error, fallback = "FAILED") {
            const code = String(error?.code || fallback).trim().toUpperCase().replace(/[^A-Z0-9_-]/g, "_");
            return code.slice(0, 64) || fallback;
          }
          function createDeferred() {
            let resolve;
            const promise = new Promise((done) => {
              resolve = done;
            });
            return { promise, resolve };
          }
          function reloadAfterMutationNow() {
            if (destroyed) return Promise.resolve(false);
            const target = mutationVersion;
            if (mutationReloadPromise) {
              if (mutationReloadTarget >= target) return mutationReloadPromise;
              return mutationReloadPromise.then(() => reloadAfterMutationNow());
            }
            mutationReloadTarget = target;
            const operation = Promise.resolve().then(() => reload());
            mutationReloadPromise = operation.finally(() => {
              if (mutationReloadPromise === operation || mutationReloadTarget === target) mutationReloadPromise = null;
            });
            return mutationReloadPromise;
          }
          function requestMutationReload() {
            if (destroyed) return Promise.resolve(false);
            if (activeBatchCount > 0 && batchReloadDeferred) {
              batchReloadNeeded = true;
              return batchReloadDeferred.promise;
            }
            return reloadAfterMutationNow();
          }
          function beginBatch() {
            if (activeBatchCount === 0) {
              batchReloadNeeded = false;
              batchReloadDeferred = createDeferred();
            }
            activeBatchCount += 1;
          }
          function finishBatch(needsReload) {
            if (batchReloadDeferred == null) return Promise.resolve(false);
            batchReloadNeeded = batchReloadNeeded || needsReload === true;
            activeBatchCount = Math.max(0, activeBatchCount - 1);
            const deferred = batchReloadDeferred;
            if (activeBatchCount === 0) {
              const shouldReload = batchReloadNeeded;
              batchReloadDeferred = null;
              batchReloadNeeded = false;
              Promise.resolve(shouldReload && !destroyed ? reloadAfterMutationNow() : !destroyed).then((value) => deferred.resolve(value), () => deferred.resolve(false));
            }
            return deferred.promise;
          }
          function startMutation(id, action, decision, reportFailure) {
            const existing = pending.get(id);
            if (existing) {
              if (existing.action === action && existing.decision === decision) return existing;
              return {
                action,
                decision,
                singlePromise: null,
                transaction: Promise.resolve(mutationResult(false, "PENDING_CONFLICT"))
              };
            }
            const epoch = lifecycle;
            const entry = { action, decision, transaction: null, singlePromise: null };
            mutationVersion += 1;
            entry.transaction = Promise.resolve().then(async () => {
              let response;
              try {
                response = action === "resolve" ? await taskApi.resolveSuggestion(id, decision) : await taskApi.undoSuggestion(id);
              } catch (error) {
                if (!destroyed && epoch === lifecycle && reportFailure) report(error, { phase: action, suggestionId: id });
                return mutationResult(false, resultCode(error));
              }
              if (destroyed || epoch !== lifecycle) return mutationResult(false, "DESTROYED");
              if (!succeeded(response)) {
                const error = responseError(response, action === "resolve" ? "Suggestion resolve failed" : "Suggestion undo failed");
                if (reportFailure) report(error, { phase: action, suggestionId: id });
                return mutationResult(false, resultCode(error));
              }
              return mutationResult(true);
            });
            pending.set(id, entry);
            return entry;
          }
          function completeSingle(id, entry) {
            if (entry.singlePromise) return entry.singlePromise;
            entry.singlePromise = entry.transaction.then((result) => result.ok ? requestMutationReload() : false).finally(() => {
              if (pending.get(id) === entry) pending.delete(id);
            });
            return entry.singlePromise;
          }
          function mutate(idInput, action, decision) {
            const id = suggestionId(idInput);
            if (destroyed) return Promise.resolve(false);
            return completeSingle(id, startMutation(id, action, decision, true));
          }
          function resolveSuggestion(id, decision) {
            if (decision !== "accept" && decision !== "reject") throw new TypeError("Invalid suggestion decision");
            return mutate(id, "resolve", decision);
          }
          function undoSuggestion(id) {
            return mutate(id, "undo");
          }
          async function resolveMany(idInputs, decision) {
            if (decision !== "accept" && decision !== "reject") throw new TypeError("Invalid suggestion decision");
            const normalized = suggestionIds(idInputs);
            if (!normalized.length) return Object.freeze({ total: 0, succeeded: 0, failed: 0, results: Object.freeze([]) });
            if (destroyed) {
              const results2 = Object.freeze(normalized.map((id) => Object.freeze({ suggestionId: id, ok: false, code: "DESTROYED" })));
              return Object.freeze({ total: results2.length, succeeded: 0, failed: results2.length, results: results2 });
            }
            beginBatch();
            const entries = normalized.map((id) => [id, startMutation(id, "resolve", decision, false)]);
            const outcomes = await Promise.all(entries.map(([, entry]) => entry.transaction));
            await finishBatch(outcomes.some((result) => result.ok));
            entries.forEach(([id, entry]) => {
              if (pending.get(id) === entry) pending.delete(id);
            });
            const results = Object.freeze(outcomes.map((result, index) => Object.freeze({
              suggestionId: entries[index][0],
              ok: result.ok,
              code: result.code
            })));
            const succeededCount = results.filter((result) => result.ok).length;
            return Object.freeze({
              total: results.length,
              succeeded: succeededCount,
              failed: results.length - succeededCount,
              results
            });
          }
          function getState() {
            return Object.freeze({
              blocks,
              loading,
              pendingSuggestionIds: Object.freeze(Array.from(pending.keys()).sort()),
              destroyed
            });
          }
          function destroy() {
            if (destroyed) return false;
            destroyed = true;
            lifecycle += 1;
            requestToken += 1;
            loading = false;
            activeBatchCount = 0;
            batchReloadNeeded = false;
            batchReloadDeferred?.resolve(false);
            batchReloadDeferred = null;
            pending.clear();
            return true;
          }
          return Object.freeze({ setContext, reload, resolveSuggestion, resolveMany, undoSuggestion, getState, destroy });
        }
        return Object.freeze({ PAGE_BATCH_SIZE, MAX_RESOLVE_MANY, createV2SuggestionController });
      });
    }
  });

  // src/content/v2-workbench-focus-runtime.js
  var require_v2_workbench_focus_runtime = __commonJS({
    "src/content/v2-workbench-focus-runtime.js"(exports, module) {
      (function attachV2WorkbenchFocusRuntime(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchFocusRuntime = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchFocusRuntimeModule() {
        "use strict";
        function createV2WorkbenchFocusRuntime(options = {}) {
          const { root, queryInput } = options;
          let pendingFocus = null;
          let suggestionIntent = null;
          let batchFocus = null;
          function descriptor(element) {
            if (!element) return null;
            const attributes = [
              "data-v2-tab-more",
              "data-v2-activate-tab",
              "data-v2-domain-trigger",
              "data-v2-status-trigger",
              "data-v2-task-more",
              "data-v2-open-task",
              "data-v2-close-task",
              "data-v2-action",
              "data-v2-query",
              "data-v2-status-filter",
              "data-v2-domain-filter",
              "data-v2-task-sort",
              "data-v2-layout",
              "data-v2-restore-trash",
              "data-v2-delete-trash",
              "data-v2-restore-all",
              "data-v2-inbox-toggle",
              "data-v2-edit-task",
              "data-v2-task-toggle",
              "data-v2-task-drag-handle",
              "data-v2-suggestion-choice",
              "data-v2-suggestion-decision",
              "data-v2-undo-suggestion",
              "data-v2-suggestion-batch-entry",
              "data-v2-suggestion-batch-select",
              "data-v2-suggestion-batch-select-all",
              "data-v2-suggestion-batch-accept",
              "data-v2-suggestion-batch-reject",
              "data-v2-suggestion-batch-cancel"
            ];
            const attribute = attributes.find((name) => element.hasAttribute(name));
            if (!attribute) return null;
            const card = element.closest("[data-v2-tab]");
            return {
              attribute,
              value: element.getAttribute(attribute),
              context: card?.dataset.v2Context || "",
              taskId: card?.dataset.v2TaskId || "",
              pageId: element.closest("[data-v2-inbox-item]")?.dataset.v2InboxItem || card?.dataset.v2Tab || "",
              suggestionId: element.dataset.v2SuggestionId || element.dataset.v2UndoSuggestion || ""
            };
          }
          function remember(...elements) {
            pendingFocus = elements.map(descriptor).filter(Boolean);
          }
          function findTarget(value) {
            return [...root.querySelectorAll(`[${value.attribute}]`)].find((element) => {
              if (element.getAttribute(value.attribute) !== value.value) return false;
              const card = element.closest("[data-v2-tab]");
              return (!value.context || card?.dataset.v2Context === value.context) && (!value.taskId || card?.dataset.v2TaskId === value.taskId || element.dataset.v2TaskId === value.taskId) && (!value.pageId || element.closest("[data-v2-inbox-item]")?.dataset.v2InboxItem === value.pageId || card?.dataset.v2Tab === value.pageId) && (!value.suggestionId || element.dataset.v2SuggestionId === value.suggestionId || element.dataset.v2UndoSuggestion === value.suggestionId);
            });
          }
          function restoreRemembered() {
            const values = pendingFocus;
            pendingFocus = null;
            if (!values) return;
            const target = values.map(findTarget).find((element) => element && !element.disabled && !element.hidden && !element.closest("[hidden],[inert]"));
            target?.focus();
          }
          function elementsWithSuggestion(attribute, suggestionId) {
            return [...root.querySelectorAll(`[${attribute}]`)].filter((element) => element.getAttribute(attribute) === suggestionId || element.dataset.v2SuggestionId === suggestionId);
          }
          function restoreSuggestion() {
            const intent = suggestionIntent;
            if (!intent || options.getPendingSuggestionIds?.().has(intent.suggestionId)) return;
            let target = null;
            if (intent.type === "accept") {
              target = elementsWithSuggestion("data-v2-undo-suggestion", intent.suggestionId).find((element) => element.closest('[data-v2-context="task"]'));
            } else if (intent.type === "undo-reject") {
              target = elementsWithSuggestion("data-v2-suggestion-decision", intent.suggestionId).find((element) => element.dataset.v2SuggestionDecision === "accept");
            }
            if (!target && (intent.type === "reject" || intent.type === "undo-accepted")) {
              target = [...root.querySelectorAll("[data-v2-inbox-item]")].find((item) => item.dataset.v2InboxItem === intent.pageId)?.querySelector("[data-v2-activate-tab]");
            }
            if (!target) {
              const decision = intent.type === "reject" ? "reject" : "accept";
              target = [...root.querySelectorAll("[data-v2-suggestion-decision]")].find((element) => element.dataset.v2SuggestionId === intent.suggestionId && element.dataset.v2SuggestionDecision === decision);
            }
            if (target && !target.disabled && !target.hidden) {
              suggestionIntent = null;
              target.focus();
            }
          }
          function restoreBatch() {
            const focus = batchFocus;
            if (!focus || options.isBatchPending?.()) return;
            let target = null;
            if (focus.type === "failure") {
              target = [...root.querySelectorAll("[data-v2-suggestion-batch-select]")].find((element) => element.dataset.v2SuggestionId === focus.suggestionId);
            }
            if (!target) target = root.querySelector("[data-v2-suggestion-batch-entry]") || root.querySelector("#tfa-v2-inbox-title");
            if (target && !target.disabled && !target.hidden) {
              batchFocus = null;
              target.focus();
            }
          }
          function rememberAdjacentTab(button) {
            const card = button.closest("[data-v2-tab]");
            const cards = card ? [...card.parentElement.children].filter((item) => item.matches("[data-v2-tab]")) : [];
            const index = cards.indexOf(card);
            const adjacent = cards[index + 1] || cards[index - 1];
            const task = card?.closest("[data-v2-task]");
            remember(adjacent?.querySelector("[data-v2-activate-tab]"), task?.querySelector("[data-v2-domain-trigger]"), queryInput);
          }
          function rememberAdjacentTask(button) {
            const task = button.closest("[data-v2-task]");
            const tasks = task ? [...task.parentElement.children].filter((item) => item.matches("[data-v2-task]")) : [];
            const index = tasks.indexOf(task);
            const adjacent = tasks[index + 1] || tasks[index - 1];
            remember(adjacent?.querySelector("[data-v2-domain-trigger]"), root.querySelector('[data-v2-action="new-task"]'));
          }
          function rememberAdjacentTrash(button) {
            const card = button.closest("[data-v2-trash-item]");
            const cards = card ? [...card.parentElement.children].filter((item) => item.matches("[data-v2-trash-item]")) : [];
            const index = cards.indexOf(card);
            const adjacent = cards[index + 1] || cards[index - 1];
            remember(adjacent?.querySelector("[data-v2-restore-trash]"), root.querySelector('[data-v2-layout="recycle"]'));
          }
          function restore() {
            restoreRemembered();
            restoreSuggestion();
            restoreBatch();
          }
          function clear() {
            pendingFocus = null;
            suggestionIntent = null;
            batchFocus = null;
          }
          return Object.freeze({
            remember,
            rememberAdjacentTab,
            rememberAdjacentTask,
            rememberAdjacentTrash,
            restore,
            setSuggestionIntent(value) {
              suggestionIntent = value || null;
            },
            setBatchFocus(value) {
              batchFocus = value || null;
            },
            clear
          });
        }
        function createV2WorkbenchScrollActivity(options = {}) {
          const { root } = options;
          const timerWindow = options.window || globalThis;
          const schedule = timerWindow.setTimeout.bind(timerWindow);
          const cancel = timerWindow.clearTimeout.bind(timerWindow);
          const activeTimers = /* @__PURE__ */ new Map();
          const selector = ".tfa-v2-scroll,.tfa-v2-inbox-pages";
          function hide(target) {
            const timer = activeTimers.get(target);
            if (timer != null) cancel(timer);
            activeTimers.delete(target);
            target?.classList?.remove("is-scrolling");
          }
          function onScroll(event) {
            const target = event?.target;
            if (!target?.matches?.(selector)) return;
            hide(target);
            target.classList.add("is-scrolling");
            let timer = null;
            timer = schedule(() => {
              if (activeTimers.get(target) !== timer) return;
              activeTimers.delete(target);
              target.classList.remove("is-scrolling");
            }, 650);
            activeTimers.set(target, timer);
          }
          root.addEventListener?.("scroll", onScroll, true);
          return Object.freeze({
            destroy() {
              root.removeEventListener?.("scroll", onScroll, true);
              [...activeTimers.keys()].forEach(hide);
            }
          });
        }
        return Object.freeze({ createV2WorkbenchFocusRuntime, createV2WorkbenchScrollActivity });
      });
    }
  });

  // src/content/v2-native-tab-group-view.js
  var require_v2_native_tab_group_view = __commonJS({
    "src/content/v2-native-tab-group-view.js"(exports, module) {
      (function attachV2NativeTabGroupView(rootScope, factory) {
        const modelModule = typeof module === "object" && module.exports ? require_v2_native_tab_group_model() : rootScope.TfaV2NativeTabGroupModel;
        const api = factory(modelModule);
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2NativeTabGroupView = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2NativeTabGroupViewModule(modelModule) {
        "use strict";
        const CSS = `
    .tfa-v2-native-groups{display:grid;gap:8px}.tfa-v2-native-group{--native-group-color:#8b95a2;overflow:hidden;border:1px solid color-mix(in srgb,var(--native-group-color) 26%,var(--v2-line));border-left:3px solid var(--native-group-color);border-radius:10px;background:color-mix(in srgb,var(--native-group-color) 4%,var(--v2-container))}
    .tfa-v2-native-group[data-group-color="blue"]{--native-group-color:#4f83d1}.tfa-v2-native-group[data-group-color="red"]{--native-group-color:#d35f69}.tfa-v2-native-group[data-group-color="yellow"]{--native-group-color:#d7a335}.tfa-v2-native-group[data-group-color="green"]{--native-group-color:#4da779}.tfa-v2-native-group[data-group-color="pink"]{--native-group-color:#d66fa6}.tfa-v2-native-group[data-group-color="purple"]{--native-group-color:#806bd6}.tfa-v2-native-group[data-group-color="cyan"]{--native-group-color:#3ba5b7}.tfa-v2-native-group[data-group-color="orange"]{--native-group-color:#d9823f}
    .tfa-v2-window-title{display:flex;align-items:center}.tfa-v2-window-actions{display:flex;gap:4px;margin-left:auto}.tfa-v2-window-actions button{padding:4px 7px;border:1px solid var(--v2-line);border-radius:6px;color:var(--v2-muted);background:var(--v2-panel);font-size:9px}.tfa-v2-window-actions button:focus-visible{outline:2px solid var(--v2-accent)}.tfa-v2-native-group-header{min-height:38px;display:flex;align-items:center;gap:7px;padding:5px 7px;border-bottom:1px solid var(--v2-line)}.tfa-v2-native-group-marker{width:8px;height:8px;flex:0 0 auto;border-radius:50%;background:var(--native-group-color)}.tfa-v2-native-group-title{min-width:0;overflow:hidden;color:var(--v2-text);font-size:11px;font-weight:700;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-native-group-count{color:var(--v2-faint);font-size:9px}.tfa-v2-native-group-actions{position:relative;display:flex;gap:3px;margin-left:auto;opacity:0;pointer-events:none}.tfa-v2-native-group:hover .tfa-v2-native-group-actions,.tfa-v2-native-group:focus-within .tfa-v2-native-group-actions{opacity:1;pointer-events:auto}.tfa-v2-native-group-action{min-width:26px;height:26px;display:grid;place-items:center;padding:0 6px;border:1px solid var(--v2-line-strong);border-radius:6px;color:var(--v2-muted);background:var(--v2-panel);font-size:9px}.tfa-v2-native-group-action:hover{color:var(--v2-text);border-color:color-mix(in srgb,var(--v2-accent) 45%,var(--v2-line-strong))}.tfa-v2-native-group-action:focus-visible{outline:2px solid var(--v2-accent);outline-offset:1px}.tfa-v2-native-group-pages{padding:7px;transition:background .15s,box-shadow .15s}.tfa-v2-native-group.is-tab-drop-target .tfa-v2-native-group-pages{background:color-mix(in srgb,var(--native-group-color) 11%,transparent);box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--native-group-color) 55%,transparent)}.tfa-v2-tab.is-tab-move-pending{opacity:.55;transform:scale(.97)}.tfa-v2-native-group:not(.is-expanded) .tfa-v2-native-group-pages .tfa-v2-tab-grid{max-height:72px;overflow:hidden}.tfa-v2-native-group-footer{height:28px;border-top:1px solid var(--v2-line)}.tfa-v2-native-group-footer button{width:100%;height:27px;display:grid;place-items:center;padding:0;border:0;color:var(--v2-faint);background:transparent}.tfa-v2-native-group-footer button:hover{color:var(--v2-text);background:color-mix(in srgb,var(--native-group-color) 7%,transparent)}.tfa-v2-native-group-footer button:focus-visible{outline:2px solid var(--v2-accent);outline-offset:-3px}.tfa-v2-native-group-footer .tfa-v2-icon{width:16px;height:16px;transition:transform .15s ease}.tfa-v2-native-group.is-expanded .tfa-v2-native-group-footer .tfa-v2-icon{transform:rotate(180deg)}
    .tfa-v2-native-group-header{border-bottom-color:color-mix(in srgb,var(--native-group-color) 18%,var(--v2-line));background:color-mix(in srgb,var(--native-group-color) 4%,var(--v2-container-head))}.tfa-v2-native-group-pages{background:transparent}.tfa-v2-native-group-footer[hidden]{display:none}.tfa-v2-native-group-action,.tfa-v2-window-actions button{background:var(--v2-card)}.tfa-v2-tab.is-tab-sort-dragging{z-index:2;opacity:.24;transform:scale(.975);border-style:dashed}.tfa-v2-tab.is-page-drop-before,.tfa-v2-tab.is-page-drop-after{z-index:3}.tfa-v2-tab.is-page-drop-before:before,.tfa-v2-tab.is-page-drop-after:after{width:4px;box-shadow:0 0 0 1px color-mix(in srgb,var(--v2-accent) 20%,transparent),0 0 14px color-mix(in srgb,var(--v2-accent) 48%,transparent)}
    @media(hover:none){.tfa-v2-native-group-actions{opacity:1;pointer-events:auto}}
  `;
        function createNativeTabGroupView(options = {}) {
          const { root, template, tr, escapeHtml, renderTab } = options;
          const groups = /* @__PURE__ */ new Map(), collapseOverrides = /* @__PURE__ */ new Map();
          function onClick(event) {
            const windowAction = event.target?.closest?.("[data-v2-window-action]");
            if (windowAction) {
              const intent = modelModule.createWindowOperationIntent(windowAction.dataset.v2WindowAction, windowAction.dataset.v2WindowId);
              if (intent) options.onWindowIntent?.(intent);
              return;
            }
            const toggle = event.target?.closest?.("[data-v2-native-group-toggle]");
            if (toggle) {
              const section = toggle.closest("[data-v2-native-group]"), key = section?.dataset?.v2NativeGroup;
              if (!section || !key) return;
              const expanded = !section.classList.contains("is-expanded");
              section.classList.toggle("is-expanded", expanded);
              toggle.setAttribute("aria-expanded", String(expanded));
              collapseOverrides.set(key, expanded);
              groups.get(key).expanded = expanded;
              return;
            }
            const action = event.target?.closest?.("[data-v2-native-group-action]");
            if (action) {
              const section = action.closest("[data-v2-native-group]"), group = groups.get(section?.dataset?.v2NativeGroup);
              if (!group) return;
              if (action.dataset.v2NativeGroupAction === "edit-group") options.onEditGroup?.(group);
              else {
                const intent = modelModule.createGroupOperationIntent(action.dataset.v2NativeGroupAction, group);
                if (intent) options.onIntent?.(intent, group);
              }
              return;
            }
          }
          function renderGroup(group) {
            const key = String(group.id);
            const expanded = collapseOverrides.has(key) ? collapseOverrides.get(key) : group.collapsed !== true;
            groups.set(key, { ...group, expanded });
            const title = group.native ? group.title || tr("workbench.untitledTabGroup", "\u672A\u547D\u540D\u6807\u7B7E\u7EC4") : tr("workbench.ungroupedTabs", "\u672A\u5206\u7EC4\u9875\u7B7E");
            const toggleLabel = expanded ? tr("workbench.collapseTabGroup", "\u6536\u8D77\u6807\u7B7E\u7EC4") : tr("workbench.expandTabGroup", "\u5C55\u5F00\u6807\u7B7E\u7EC4");
            const actions = group.native ? `<div class="tfa-v2-native-group-actions"><button type="button" class="tfa-v2-native-group-action" data-v2-native-group-action="move-out-group" title="${escapeHtml(tr("workbench.ungroupTabGroup", "\u89E3\u7EC4"))}">${escapeHtml(tr("workbench.ungroupTabGroup", "\u89E3\u7EC4"))}</button><button type="button" class="tfa-v2-native-group-action is-danger" data-v2-native-group-action="close-group" title="${escapeHtml(tr("workbench.closeAllTabGroup", "\u5168\u90E8\u5173\u95ED"))}">${escapeHtml(tr("workbench.closeAllTabGroup", "\u5168\u90E8\u5173\u95ED"))}</button></div>` : "";
            return `<section class="tfa-v2-native-group${expanded ? " is-expanded" : ""}" data-v2-native-group="${escapeHtml(key)}" data-window-id="${escapeHtml(group.tabs[0]?.windowId)}" data-group-id="${escapeHtml(group.groupId)}" data-group-color="${escapeHtml(group.color)}"><header class="tfa-v2-native-group-header"><span class="tfa-v2-native-group-marker" aria-hidden="true"></span><strong class="tfa-v2-native-group-title" title="${escapeHtml(title)}">${escapeHtml(title)}</strong><span class="tfa-v2-native-group-count">${escapeHtml(tr("workbench.tabCount", "{count} \u4E2A\u9875\u7B7E", { count: group.tabs.length }))}</span>${actions}</header><div class="tfa-v2-native-group-pages"><div class="tfa-v2-tab-grid">${group.tabs.map((tab) => renderTab(tab, "browser")).join("")}</div></div>${group.tabs.length > 1 ? `<footer class="tfa-v2-native-group-footer"><button type="button" data-v2-native-group-toggle aria-expanded="${expanded}" aria-label="${escapeHtml(toggleLabel)}" title="${escapeHtml(toggleLabel)}">${template.icon("chevron-down")}</button></footer>` : ""}</section>`;
          }
          function render(windows, windowPosition) {
            groups.clear();
            return (Array.isArray(windows) ? windows : []).map((window2) => `<section class="tfa-v2-window"><header class="tfa-v2-window-title">${escapeHtml(tr("workbench.window", "\u7A97\u53E3 {number}", { number: windowPosition(window2.windowId) }))}<small>${escapeHtml(tr("workbench.tabCount", "{count} \u4E2A\u9875\u7B7E", { count: window2.tabs.length }))}</small><span class="tfa-v2-window-actions"><button type="button" data-v2-window-action="group-by-domain" data-v2-window-id="${window2.windowId}">${escapeHtml(tr("workbench.groupByDomain", "\u6309\u57DF\u540D\u5206\u7EC4"))}</button><button type="button" data-v2-window-action="ungroup-all" data-v2-window-id="${window2.windowId}">${escapeHtml(tr("workbench.ungroupAll", "\u5168\u90E8\u89E3\u7EC4"))}</button></span></header><div class="tfa-v2-native-groups">${window2.groups.map(renderGroup).join("")}</div></section>`).join("");
          }
          root.addEventListener?.("click", onClick);
          return Object.freeze({ render, destroy() {
            root.removeEventListener?.("click", onClick);
            groups.clear();
            collapseOverrides.clear();
          } });
        }
        return Object.freeze({ CSS, createNativeTabGroupView });
      });
    }
  });

  // src/content/v2-tab-awareness-view.js
  var require_v2_tab_awareness_view = __commonJS({
    "src/content/v2-tab-awareness-view.js"(exports, module) {
      (function attachV2TabAwarenessView(rootScope, factory) {
        const logicModule = typeof module === "object" && module.exports ? require_v2_tab_awareness_logic() : rootScope.TfaV2TabAwarenessLogic;
        const api = factory(logicModule);
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2TabAwarenessView = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2TabAwarenessViewModule(logicModule) {
        "use strict";
        const CSS = `
    .tfa-v2-tab.is-linked{border-color:color-mix(in srgb,var(--v2-accent) 62%,var(--v2-line));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--v2-accent) 18%,transparent)}.tfa-v2-tab-meta{min-width:0;display:flex;align-items:center;gap:5px}.tfa-v2-session-dwell{flex:0 0 auto;margin-left:auto;color:var(--v2-faint);font-size:8px;white-space:nowrap;visibility:hidden;opacity:0;transition:opacity .14s ease}.tfa-v2-tab:hover .tfa-v2-session-dwell,.tfa-v2-tab:focus-within .tfa-v2-session-dwell{visibility:visible;opacity:1}.tfa-v2-availability{position:absolute;right:8px;bottom:8px;width:7px;height:7px;border-radius:50%;background:#7f8996;transition:opacity .14s}.tfa-v2-availability.is-open{background:#4fb284;box-shadow:0 0 0 3px color-mix(in srgb,#4fb284 13%,transparent)}.tfa-v2-tab:hover .tfa-v2-availability,.tfa-v2-tab:focus-within .tfa-v2-availability{opacity:0}
    .tfa-v2-hover-preview{position:fixed;z-index:2147483645;width:min(340px,calc(100vw - 24px));padding:10px;border:1px solid var(--v2-line-strong);border-radius:10px;color:var(--v2-text);background:color-mix(in srgb,var(--v2-panel) 97%,transparent);box-shadow:0 18px 48px rgba(0,0,0,.36);pointer-events:none;opacity:0;transform:translateY(5px) scale(.98);transition:opacity .16s ease,transform .16s ease}.tfa-v2-hover-preview.is-visible{opacity:1;transform:none}.tfa-v2-hover-preview[hidden]{display:none}.tfa-v2-hover-preview-head{display:flex;align-items:center;gap:8px;min-width:0;margin-bottom:8px}.tfa-v2-hover-preview-head strong,.tfa-v2-hover-preview-head small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-hover-preview-head span{min-width:0}.tfa-v2-hover-preview-head small{color:var(--v2-faint);font-size:9px}.tfa-v2-hover-preview-media{aspect-ratio:16/9;display:grid;place-items:center;overflow:hidden;border:1px solid var(--v2-line);border-radius:8px;background:linear-gradient(145deg,var(--v2-soft),var(--v2-panel))}.tfa-v2-hover-preview-media img{width:100%;height:100%;display:block;object-fit:contain;object-position:top center}.tfa-v2-hover-preview-placeholder{display:grid;gap:5px;color:var(--v2-muted);text-align:center}.tfa-v2-hover-preview-placeholder b{color:var(--v2-text);font-size:13px}.tfa-v2-hover-preview-foot{display:flex;justify-content:space-between;gap:8px;margin-top:7px;color:var(--v2-faint);font-size:9px}
    .tfa-v2-hover-preview{background:var(--v2-panel)}.tfa-v2-hover-preview-media img{background:var(--v2-panel);opacity:1}
    @media(hover:none){.tfa-v2-session-dwell{visibility:visible;opacity:1}}
    @media(prefers-reduced-motion:reduce){.tfa-v2-hover-preview,.tfa-v2-session-dwell{transition:none}}
  `;
        const PREVIEW_CONTEXTS = /* @__PURE__ */ new Set(["browser", "task"]);
        function createTabAwarenessView(options = {}) {
          const { root, escapeHtml, tr } = options;
          const previewContainer = options.previewContainer || root;
          const documentRef = root?.ownerDocument || globalThis.document;
          const windowRef = documentRef?.defaultView || globalThis.window;
          const scheduleMicrotask = options.queueMicrotask || windowRef?.queueMicrotask?.bind?.(windowRef) || globalThis.queueMicrotask?.bind?.(globalThis) || ((callback) => Promise.resolve().then(callback));
          const preview = documentRef?.createElement?.("aside");
          if (preview) {
            preview.className = "tfa-v2-hover-preview";
            preview.hidden = true;
            preview.setAttribute("role", "tooltip");
            previewContainer.appendChild?.(preview);
          }
          let hovered = null, focused = null, activeCard = null, showTimer = null, requestToken = 0, dragging = false, dragEpoch = 0;
          const cardFrom = (target) => target?.closest?.("[data-v2-tab][data-v2-link-key]") || null;
          const safeScreenshot = (value) => /^data:image\/[a-z0-9.+-]+;base64,/i.test(String(value || "")) ? String(value) : "";
          function previewPlaceholder(tab, pending = false) {
            let key = "workbench.previewUnavailable", fallback = "\u6682\u65E0\u53EF\u7528\u9884\u89C8";
            let restricted = false;
            try {
              restricted = !["http:", "https:", "file:"].includes(new URL(tab?.url || "").protocol);
            } catch (_error) {
              restricted = true;
            }
            if (restricted) {
              key = "workbench.previewRestricted";
              fallback = "\u6D4F\u89C8\u5668\u9650\u5236\u9875\u9762\u65E0\u6CD5\u751F\u6210\u9884\u89C8";
            } else if (!tab?.active) {
              key = "workbench.previewActivateRequired";
              fallback = "\u5207\u6362\u5230\u6B64\u9875\u7B7E\u5E76\u7B49\u5F85\u52A0\u8F7D\u540E\uFF0C\u5C06\u81EA\u52A8\u751F\u6210\u9884\u89C8";
            } else if (tab?.status && tab.status !== "complete") {
              key = "workbench.previewWaitingForLoad";
              fallback = "\u9875\u9762\u52A0\u8F7D\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u751F\u6210\u9884\u89C8";
            } else if (pending) {
              key = "workbench.previewLoading";
              fallback = "\u6B63\u5728\u52A0\u8F7D\u5B89\u5168\u9884\u89C8\u2026";
            }
            return escapeHtml(tr(key, fallback));
          }
          function dwellMilliseconds(label) {
            const total = Math.max(0, Number(label.dataset.v2DwellTotal) || 0), since = Number(label.dataset.v2DwellSince);
            return total + (Number.isFinite(since) && since > 0 ? Math.max(0, Date.now() - since) : 0);
          }
          function updateDwell() {
            root.querySelectorAll?.("[data-v2-dwell-total]").forEach((label) => {
              label.textContent = tr("workbench.sessionDwell", "\u505C\u7559 {time}", { time: logicModule.formatSessionDwell(dwellMilliseconds(label), label.dataset.v2DwellLanguage) });
            });
          }
          function clearLinked() {
            root.querySelectorAll?.(".tfa-v2-tab.is-linked").forEach((card) => card.classList.remove("is-linked"));
          }
          function link(card) {
            clearLinked();
            const key = card?.dataset?.v2LinkKey;
            if (key) root.querySelectorAll?.(`[data-v2-link-key="${key}"]`).forEach((match) => match.classList.add("is-linked"));
          }
          function hidePreview() {
            requestToken += 1;
            if (showTimer) clearTimeout(showTimer);
            showTimer = null;
            preview?.classList?.remove("is-visible");
            if (preview) preview.hidden = true;
          }
          function position(card) {
            if (!preview || !card?.getBoundingClientRect) return;
            const rect = card.getBoundingClientRect(), width = Math.min(340, (windowRef?.innerWidth || 364) - 24), height = 270, gutter = 12;
            let left = rect.right + 10;
            if (left + width > (windowRef?.innerWidth || 1e3) - gutter) left = rect.left - width - 10;
            preview.style.left = `${Math.max(gutter, Math.min(left, (windowRef?.innerWidth || 1e3) - width - gutter))}px`;
            preview.style.top = `${Math.max(gutter, Math.min(rect.top, (windowRef?.innerHeight || 700) - height - gutter))}px`;
          }
          function renderPreview(card) {
            if (dragging || !preview || !PREVIEW_CONTEXTS.has(card?.dataset?.v2Context)) return;
            const tab = options.getTab?.(card.dataset.v2Tab);
            if (!tab?.isOpen) return;
            const token = ++requestToken, host = (() => {
              try {
                return new URL(tab.url).hostname.replace(/^www\./, "");
              } catch (_error) {
                return "";
              }
            })();
            const screenshot = safeScreenshot(tab.previewScreenshot);
            const canRequest = tab.active === true && (!tab.status || tab.status === "complete");
            preview.innerHTML = `<div class="tfa-v2-hover-preview-head"><span><strong>${escapeHtml(tab.title || host || tr("workbench.unknownPage", "\u672A\u77E5\u9875\u9762"))}</strong><small>${escapeHtml(host)}</small></span></div><div class="tfa-v2-hover-preview-media">${screenshot ? `<img src="${escapeHtml(screenshot)}" alt="${escapeHtml(tr("workbench.previewImageAlt", "\u9875\u9762\u9884\u89C8"))}">` : `<span class="tfa-v2-hover-preview-placeholder"><b>${escapeHtml(tab.title || host)}</b><span>${previewPlaceholder(tab, canRequest)}</span></span>`}</div><div class="tfa-v2-hover-preview-foot"><span>${escapeHtml(tr("workbench.openNow", "\u5F53\u524D\u5DF2\u6253\u5F00"))}</span><span>${escapeHtml(tr("workbench.previewSwitchHint", "\u70B9\u51FB\u5361\u7247\u5207\u6362"))}</span></div>`;
            preview.hidden = false;
            position(card);
            preview.classList.add("is-visible");
            if (!screenshot && canRequest && tab.liveTabId != null) Promise.resolve(options.onRequestPreview?.(tab.liveTabId)).then((source) => {
              const image = safeScreenshot(source);
              if (token !== requestToken || activeCard !== card) return;
              const media = preview.querySelector?.(".tfa-v2-hover-preview-media");
              if (!media) return;
              media.innerHTML = image ? `<img src="${escapeHtml(image)}" alt="${escapeHtml(tr("workbench.previewImageAlt", "\u9875\u9762\u9884\u89C8"))}">` : `<span class="tfa-v2-hover-preview-placeholder"><span>${previewPlaceholder(tab)}</span></span>`;
            }).catch(() => {
              if (token !== requestToken || activeCard !== card) return;
              const media = preview.querySelector?.(".tfa-v2-hover-preview-media");
              if (media) media.innerHTML = `<span class="tfa-v2-hover-preview-placeholder"><span>${previewPlaceholder(tab)}</span></span>`;
            });
          }
          function syncActive() {
            const next = hovered || focused;
            if (next === activeCard) return;
            activeCard = next;
            hidePreview();
            clearLinked();
            if (!next) return;
            link(next);
            if (PREVIEW_CONTEXTS.has(next.dataset.v2Context)) {
              const delay = options.previewDelay == null ? 180 : Math.max(0, Number(options.previewDelay) || 0);
              showTimer = setTimeout(() => renderPreview(next), delay);
            }
          }
          function onPointerOver(event) {
            if (dragging) return;
            const card = cardFrom(event.target);
            if (!card || card.contains?.(event.relatedTarget)) return;
            hovered = card;
            syncActive();
          }
          function onPointerOut(event) {
            const card = cardFrom(event.target);
            if (!card || card !== hovered || card.contains?.(event.relatedTarget)) return;
            hovered = null;
            syncActive();
          }
          function onFocusIn(event) {
            if (dragging) return;
            focused = cardFrom(event.target);
            syncActive();
          }
          function onFocusOut(event) {
            const card = cardFrom(event.target);
            if (!card || card.contains?.(event.relatedTarget)) return;
            focused = null;
            syncActive();
          }
          function onDragStart(event) {
            const epoch = ++dragEpoch;
            dragging = true;
            hovered = null;
            focused = null;
            activeCard = null;
            hidePreview();
            clearLinked();
            scheduleMicrotask(() => {
              if (epoch === dragEpoch && event?.defaultPrevented) dragging = false;
            });
          }
          function onDragEnd() {
            dragEpoch += 1;
            dragging = false;
          }
          root.addEventListener?.("pointerover", onPointerOver);
          root.addEventListener?.("pointerout", onPointerOut);
          root.addEventListener?.("focusin", onFocusIn);
          root.addEventListener?.("focusout", onFocusOut);
          root.addEventListener?.("dragstart", onDragStart);
          root.addEventListener?.("dragend", onDragEnd);
          const dwellTimer = setInterval(updateDwell, 15e3);
          updateDwell();
          return Object.freeze({
            updateDwell,
            hidePreview,
            destroy() {
              clearInterval(dwellTimer);
              dragEpoch += 1;
              dragging = false;
              hidePreview();
              clearLinked();
              ["pointerover", "pointerout", "focusin", "focusout", "dragstart", "dragend"].forEach((type, index) => root.removeEventListener?.(type, [onPointerOver, onPointerOut, onFocusIn, onFocusOut, onDragStart, onDragEnd][index]));
              preview?.remove?.();
            }
          });
        }
        return Object.freeze({ CSS, formatSessionDwell: logicModule.formatSessionDwell, createTabAwarenessView });
      });
    }
  });

  // src/content/v2-browser-tab-sort.js
  var require_v2_browser_tab_sort = __commonJS({
    "src/content/v2-browser-tab-sort.js"(exports, module) {
      (function attachV2BrowserTabSort(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaV2BrowserTabSort = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2BrowserTabSortModule() {
        "use strict";
        function createBrowserTabSort(options = {}) {
          const root = options.root;
          let source = null, sourceCard = null, marker = null, markerGroup = null, destination = null;
          const cardOf = (target) => target?.closest?.('[data-v2-tab][data-v2-context="browser"]') || null;
          const startCardOf = (target) => {
            if (target?.closest?.(".tfa-v2-tab-actions,.tfa-v2-primary-menu")) return null;
            return target?.closest?.(".tfa-v2-tab-main")?.closest?.('[data-v2-tab][data-v2-context="browser"]') || target?.closest?.('[data-v2-tab][data-v2-context="browser"]') || null;
          };
          const groupOf = (target) => target?.closest?.("[data-v2-native-group]") || null;
          const tabOf = (card) => options.getTabs?.().find((tab) => String(tab.id) === String(card?.dataset?.v2Tab)) || null;
          const cards = () => Array.from(root.querySelectorAll?.('[data-v2-tab][data-v2-context="browser"]') || []);
          const dropRectOf = (card) => card?.querySelector?.(".tfa-v2-tab-main")?.getBoundingClientRect?.() || card?.getBoundingClientRect?.();
          function clear() {
            marker?.classList?.remove("is-page-drop-before", "is-page-drop-after");
            markerGroup?.classList?.remove("is-tab-drop-target");
            marker = null;
            markerGroup = null;
            destination = null;
          }
          function onStart(event) {
            sourceCard = startCardOf(event.target);
            source = tabOf(sourceCard);
            if (!sourceCard || !source) {
              sourceCard = null;
              source = null;
              return;
            }
            sourceCard?.classList?.add("is-tab-sort-dragging");
            if (event.dataTransfer) {
              event.dataTransfer.effectAllowed = "move";
              event.dataTransfer.setData?.("application/x-tabflow-tab", String(source.id));
              event.dataTransfer.setData?.("text/plain", String(source.id));
            }
          }
          function onOver(event) {
            const card = cardOf(event.target), target = tabOf(card), group = groupOf(event.target);
            if (!source || !group || target && String(source.id) === String(target.id)) return;
            event.preventDefault?.();
            clear();
            marker = card;
            markerGroup = group;
            group.classList.add("is-tab-drop-target");
            const rect = dropRectOf(card), after = rect ? event.clientX >= rect.left + rect.width / 2 : true;
            card?.classList?.add(after ? "is-page-drop-after" : "is-page-drop-before");
            const groupId = Number(group.dataset.groupId), windowId = Number(group.dataset.windowId);
            const sectionCards = Array.from(group.querySelectorAll?.('[data-v2-tab][data-v2-context="browser"]') || []);
            const sectionTabs = sectionCards.map(tabOf).filter(Boolean).sort((a, b) => a.index - b.index);
            const groupTabs = sectionTabs.length ? sectionTabs : options.getTabs?.().filter((tab) => Number(tab.windowId) === windowId && Number(tab.groupId) === groupId).sort((a, b) => a.index - b.index) || [];
            destination = {
              after,
              groupId,
              windowId,
              index: target?.index ?? (groupTabs.at(-1)?.index ?? -1) + 1,
              beforeTabId: target && !after ? target.id : null,
              afterTabId: target && after ? target.id : !target ? groupTabs.at(-1)?.id ?? null : null,
              placement: target ? "relative" : "end"
            };
            if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
          }
          function onDrop(event) {
            const dropGroup = groupOf(event.target);
            if (!dropGroup) {
              clear();
              source = null;
              return;
            }
            if (source && !destination) onOver(event);
            const card = cardOf(event.target), eventTarget = tabOf(card), drop = destination;
            const anchorId = drop?.beforeTabId ?? drop?.afterTabId;
            const anchorTarget = anchorId == null ? null : options.getTabs?.().find((tab) => String(tab.id) === String(anchorId)) || null;
            const target = eventTarget && String(eventTarget.id) !== String(source?.id) ? eventTarget : anchorTarget;
            if (!source || !drop) {
              clear();
              source = null;
              return;
            }
            event.preventDefault?.();
            event.stopImmediatePropagation?.();
            const moving = source, pendingCard = sourceCard;
            clear();
            source = null;
            pendingCard?.classList?.add("is-tab-move-pending");
            Promise.resolve(options.onMove?.(moving, target, drop)).catch(() => false).finally(() => pendingCard?.classList?.remove("is-tab-move-pending"));
          }
          function onEnd() {
            clear();
            source = null;
            sourceCard?.classList?.remove("is-tab-sort-dragging");
            sourceCard = null;
          }
          root.addEventListener?.("dragstart", onStart);
          root.addEventListener?.("dragover", onOver);
          root.addEventListener?.("drop", onDrop);
          root.addEventListener?.("dragend", onEnd);
          return Object.freeze({ destroy() {
            onEnd();
            root.removeEventListener?.("dragstart", onStart);
            root.removeEventListener?.("dragover", onOver);
            root.removeEventListener?.("drop", onDrop);
            root.removeEventListener?.("dragend", onEnd);
          } });
        }
        return Object.freeze({ createBrowserTabSort });
      });
    }
  });

  // src/content/v2-overflow-controls.js
  var require_v2_overflow_controls = __commonJS({
    "src/content/v2-overflow-controls.js"(exports, module) {
      (function attachV2OverflowControls(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2OverflowControls = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2OverflowControlsModule() {
        "use strict";
        function gridHasHiddenRows(grid) {
          const items = Array.from(grid?.children || []).filter((item) => item?.hidden !== true);
          if (items.length < 2) return false;
          const first = items[0], firstRect = first.getBoundingClientRect?.();
          const firstTop = Number(firstRect?.top), firstBottom = Number(firstRect?.bottom);
          if (Number.isFinite(firstTop) && Number.isFinite(firstBottom) && firstBottom > firstTop) {
            return items.slice(1).some((item) => Number(item.getBoundingClientRect?.()?.top) >= firstBottom - 1);
          }
          const firstOffset = Number(first.offsetTop), firstHeight = Number(first.offsetHeight);
          return Number.isFinite(firstOffset) && Number.isFinite(firstHeight) && firstHeight > 0 && items.slice(1).some((item) => Number(item.offsetTop) >= firstOffset + firstHeight - 1);
        }
        function createOverflowControls(options = {}) {
          const root = options.root, windowRef = options.window || globalThis;
          let frame = null;
          const definitions = [
            ["[data-v2-native-group]", ".tfa-v2-native-group-pages .tfa-v2-tab-grid", ".tfa-v2-native-group-footer"],
            ["[data-v2-task]", ".tfa-v2-task-pages .tfa-v2-tab-grid", ".tfa-v2-task-footer"],
            ["[data-v2-inbox]", ".tfa-v2-inbox-pages .tfa-v2-tab-grid", ".tfa-v2-inbox-footer"]
          ];
          function sync() {
            frame = null;
            definitions.forEach(([ownerSelector, gridSelector, footerSelector]) => root.querySelectorAll(ownerSelector).forEach((owner) => {
              const footer = owner.querySelector?.(footerSelector);
              if (!footer) return;
              const overflow = gridHasHiddenRows(owner.querySelector?.(gridSelector));
              footer.hidden = !overflow;
              owner.classList?.toggle("has-collapsible-rows", overflow);
            }));
          }
          function schedule() {
            if (frame !== null) return;
            frame = (windowRef.requestAnimationFrame || ((callback) => setTimeout(callback, 0)))(sync);
          }
          const ResizeObserverRef = windowRef.ResizeObserver || globalThis.ResizeObserver;
          const observer = typeof ResizeObserverRef === "function" ? new ResizeObserverRef(schedule) : null;
          (options.observe || []).filter(Boolean).forEach((element) => observer?.observe(element));
          return Object.freeze({ schedule, sync, destroy() {
            observer?.disconnect?.();
            if (frame !== null) (windowRef.cancelAnimationFrame || clearTimeout)(frame);
            frame = null;
          } });
        }
        return Object.freeze({ gridHasHiddenRows, createOverflowControls });
      });
    }
  });

  // src/content/v2-native-tab-command-runtime.js
  var require_v2_native_tab_command_runtime = __commonJS({
    "src/content/v2-native-tab-command-runtime.js"(exports, module) {
      (function attachV2NativeTabCommandRuntime(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaV2NativeTabCommandRuntime = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createModule() {
        "use strict";
        function createNativeTabCommandRuntime(options = {}) {
          const run = options.runCommand;
          const refresh = async () => {
            await options.refresh?.();
            options.update?.();
          };
          async function applyGroupIntent(intent, group) {
            if (!intent || typeof intent !== "object") return false;
            let work = null;
            if (intent.type === "tab.activate") work = () => options.activateGroupFirst?.(intent.groupId) || options.activateTab?.(intent.tabId);
            else if (intent.type === "tabs.close") work = () => options.closeGroup?.(intent.groupId);
            else if (intent.type === "tabs.ungroup") work = () => options.ungroupGroup?.(intent.groupId) || options.ungroupTabs?.(intent.tabIds);
            else if (intent.type === "group.update") work = () => options.updateGroup?.(
              intent.groupId,
              intent.patch?.title ?? group?.title ?? "",
              intent.patch?.color ?? group?.color ?? "grey"
            );
            if (!work || !await run?.(work)) return false;
            if (intent.type !== "tab.activate") await refresh();
            return true;
          }
          async function applyWindowIntent(intent) {
            if (!intent || typeof intent !== "object") return false;
            const work = intent.type === "window.group-by-domain" ? () => options.groupByDomain?.(intent.windowId) : intent.type === "window.ungroup-all" ? () => options.ungroupAll?.(intent.windowId) : null;
            if (!work || !await run?.(work)) return false;
            await refresh();
            return true;
          }
          async function reorder(source, target, drop) {
            if (!source || !drop) return false;
            if (typeof options.moveTabRelative === "function") {
              const moved = await run?.(() => options.moveTabRelative(source.id, {
                beforeTabId: drop.beforeTabId ?? null,
                afterTabId: drop.afterTabId ?? null,
                placement: drop.placement || (target ? "relative" : "end"),
                windowId: drop.windowId,
                groupId: drop.groupId
              }));
              if (!moved) return false;
              await refresh();
              return true;
            }
            const rawIndex = Number(target?.index ?? drop.index) + (target && drop.after ? 1 : 0);
            const index = Math.max(0, source.windowId === drop.windowId && Number(source.index) < rawIndex ? rawIndex - 1 : rawIndex);
            let changed = false;
            let requiresFinalMove = source.windowId === drop.windowId;
            const fail = async () => {
              if (changed) await refresh();
              return false;
            };
            if (source.windowId !== drop.windowId) {
              if (!await run?.(() => options.moveTab?.(source.id, index, drop.windowId))) return false;
              changed = true;
            }
            if (Number(source.groupId) !== Number(drop.groupId)) {
              const regrouped = drop.groupId >= 0 ? await run?.(() => options.addToGroup?.([source.id], drop.groupId)) : await run?.(() => options.ungroupTabs?.([source.id]));
              if (!regrouped) return fail();
              changed = true;
              requiresFinalMove = true;
            }
            if (requiresFinalMove && !await run?.(() => options.moveTab?.(source.id, index, drop.windowId))) return fail();
            await refresh();
            return true;
          }
          return Object.freeze({ applyGroupIntent, applyWindowIntent, reorder });
        }
        return Object.freeze({ createNativeTabCommandRuntime });
      });
    }
  });

  // src/content/v2-ai-adjustment-view.js
  var require_v2_ai_adjustment_view = __commonJS({
    "src/content/v2-ai-adjustment-view.js"(exports, module) {
      (function attachV2AiAdjustmentView(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        if (rootScope) rootScope.TfaV2AiAdjustmentView = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2AiAdjustmentViewModule() {
        "use strict";
        const TYPES = Object.freeze([
          "create_ai_task",
          "rename_ai_task",
          "assign_ai_relation",
          "reorder_ai_tasks"
        ]);
        const STATES = Object.freeze(["applied", "undoing", "undone", "conflict", "failed"]);
        const ERROR_CODES = Object.freeze([
          "",
          "AI_PLAN_UNDO_CONFLICT",
          "AI_PLAN_UNDO_UNAVAILABLE",
          "AI_PLAN_NOT_FOUND",
          "AI_REQUEST_FAILED"
        ]);
        const COPY = Object.freeze({
          "zh-CN": Object.freeze({
            summary: "\u672C\u8F6E AI \u8C03\u6574 {count} \u9879",
            view: "\u67E5\u770B",
            hide: "\u6536\u8D77",
            undo: "\u64A4\u9500",
            undoing: "\u6B63\u5728\u64A4\u9500",
            undone: "\u5DF2\u64A4\u9500",
            close: "\u5173\u95ED\u8BE6\u60C5",
            panelTitle: "AI \u8C03\u6574\u8BE6\u60C5",
            before: "\u8C03\u6574\u524D",
            after: "\u8C03\u6574\u540E",
            reason: "\u539F\u56E0",
            create_ai_task: "\u521B\u5EFA\u4EFB\u52A1",
            rename_ai_task: "\u4EFB\u52A1\u6539\u540D",
            assign_ai_relation: "\u9875\u9762\u5F52\u7C7B",
            reorder_ai_tasks: "\u4EFB\u52A1\u6392\u5E8F",
            conflict: "\u65E0\u6CD5\u64A4\u9500\uFF1A\u4F60\u5DF2\u5728 AI \u8C03\u6574\u540E\u624B\u52A8\u4FEE\u6539\u76F8\u5173\u5185\u5BB9\u3002",
            failed: "\u64A4\u9500\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
            empty: "\u6CA1\u6709\u53EF\u663E\u793A\u7684 AI \u8C03\u6574\u3002"
          }),
          en: Object.freeze({
            summary: "AI adjusted {count} items",
            view: "View",
            hide: "Hide",
            undo: "Undo",
            undoing: "Undoing",
            undone: "Undone",
            close: "Close details",
            panelTitle: "AI adjustment details",
            before: "Before",
            after: "After",
            reason: "Why",
            create_ai_task: "Created task",
            rename_ai_task: "Renamed task",
            assign_ai_relation: "Assigned page",
            reorder_ai_tasks: "Reordered tasks",
            conflict: "Cannot undo because you changed related items after the AI adjustment.",
            failed: "Undo failed. Please try again.",
            empty: "No AI adjustments to show."
          })
        });
        const SAFE_TEXT = /^(?!.*(?:\b(?:https?|file|chrome|edge):\/\/|Bearer\s+|\bsk-[A-Za-z0-9_-]{8}|api[-_ ]?key|authorization|cookie|raw[_ ]?events?|behavior[_ ]?events?))[\s\S]*$/i;
        function escapeHtml(value) {
          return String(value == null ? "" : value).replace(/[&<>"']/g, (character) => ({
            "&": "&amp;",
            "<": "&lt;",
            ">": "&gt;",
            '"': "&quot;",
            "'": "&#39;"
          })[character]);
        }
        function fail(message) {
          const error = new TypeError(message);
          error.code = "AI_ADJUSTMENT_INVALID";
          throw error;
        }
        function exact(value, allowed, field) {
          if (!value || typeof value !== "object" || Array.isArray(value)) fail(`${field} must be an object`);
          if (Object.keys(value).some((key) => !allowed.includes(key))) fail(`${field} contains unsafe fields`);
          return value;
        }
        function text(value, field, maximum, optional = false) {
          if (value == null && optional) return "";
          if (typeof value !== "string") fail(`${field} must be text`);
          const normalized = value.trim();
          if (!normalized && !optional || normalized.length > maximum || /[\u0000-\u001f\u007f]/.test(normalized) || !SAFE_TEXT.test(normalized)) fail(`${field} is unsafe`);
          return normalized;
        }
        function normalizeAdjustmentSummary(value) {
          const source = exact(value, ["changeId", "status", "items", "errorCode"], "summary");
          const changeId = text(source.changeId, "changeId", 160);
          if (!/^change-[A-Za-z0-9._:-]+$/.test(changeId)) fail("changeId is invalid");
          if (!STATES.includes(source.status)) fail("status is invalid");
          if (!Array.isArray(source.items) || source.items.length < 1 || source.items.length > 50) fail("items are invalid");
          const items = source.items.map((item, index) => {
            const record = exact(item, ["type", "title", "before", "after", "reason"], `items[${index}]`);
            if (!TYPES.includes(record.type)) fail(`items[${index}].type is invalid`);
            const normalized = {
              type: record.type,
              title: text(record.title, `items[${index}].title`, 160),
              before: text(record.before, `items[${index}].before`, 200, true),
              after: text(record.after, `items[${index}].after`, 200, true),
              reason: text(record.reason, `items[${index}].reason`, 240, true)
            };
            if (!normalized.before && !normalized.after) fail(`items[${index}] needs a safe summary`);
            return Object.freeze(normalized);
          });
          const errorCode = String(source.errorCode || "");
          if (!ERROR_CODES.includes(errorCode)) fail("errorCode is invalid");
          return Object.freeze({ changeId, status: source.status, items: Object.freeze(items), errorCode });
        }
        function translator(locale, translate) {
          const language = String(locale || "").toLowerCase().startsWith("zh") ? "zh-CN" : "en";
          return (key, params = {}) => {
            const fallback = COPY[language][key] || key;
            const translated = typeof translate === "function" ? translate(`ai.adjustment.${key}`, fallback, params) : fallback;
            return String(translated).replace(/\{(\w+)\}/g, (_match, name) => String(params[name] ?? ""));
          };
        }
        function buildAdjustmentMarkup(summaryValue, { locale = "en", t, expanded = false } = {}) {
          const summary = normalizeAdjustmentSummary(summaryValue);
          const tr = translator(locale, t);
          const busy = summary.status === "undoing";
          const undoDisabled = busy || summary.status === "undone";
          const undoLabel = busy ? tr("undoing") : summary.status === "undone" ? tr("undone") : tr("undo");
          const notice = summary.status === "conflict" ? `<p class="tfa-v2-ai-adjustment-notice is-error" role="alert">${escapeHtml(tr("conflict"))}</p>` : summary.status === "failed" ? `<p class="tfa-v2-ai-adjustment-notice is-error" role="alert">${escapeHtml(tr("failed"))}</p>` : summary.status === "undone" ? `<p class="tfa-v2-ai-adjustment-notice is-success" role="status">${escapeHtml(tr("undone"))}</p>` : "";
          const items = summary.items.map((item) => {
            const before = item.before ? `<span><small>${escapeHtml(tr("before"))}</small><strong>${escapeHtml(item.before)}</strong></span>` : "";
            const after = item.after ? `<span><small>${escapeHtml(tr("after"))}</small><strong>${escapeHtml(item.after)}</strong></span>` : "";
            const reason = item.reason ? `<p><small>${escapeHtml(tr("reason"))}</small>${escapeHtml(item.reason)}</p>` : "";
            return `<li class="tfa-v2-ai-adjustment-item"><header><span class="tfa-v2-ai-adjustment-type">${escapeHtml(tr(item.type))}</span><strong title="${escapeHtml(item.title)}">${escapeHtml(item.title)}</strong></header><div class="tfa-v2-ai-adjustment-diff">${before}${after}</div>${reason}</li>`;
          }).join("");
          const panelId = `tfa-v2-ai-adjustment-${escapeHtml(summary.changeId)}`;
          return `<section class="tfa-v2-ai-adjustment is-${escapeHtml(summary.status)}" data-v2-ai-adjustment="${escapeHtml(summary.changeId)}" aria-busy="${busy}"><div class="tfa-v2-ai-adjustment-bar"><button type="button" class="tfa-v2-ai-adjustment-summary" data-v2-ai-adjustment-toggle aria-expanded="${expanded}" aria-controls="${panelId}"><strong>${escapeHtml(tr("summary", { count: summary.items.length }))}</strong><span>${escapeHtml(expanded ? tr("hide") : tr("view"))}</span></button><button type="button" class="tfa-v2-ai-adjustment-undo" data-v2-ai-adjustment-undo${undoDisabled ? " disabled" : ""}>${escapeHtml(undoLabel)}</button></div>${notice}<div class="tfa-v2-ai-adjustment-panel" id="${panelId}" data-v2-ai-adjustment-panel tabindex="-1"${expanded ? "" : " hidden"}><header><strong>${escapeHtml(tr("panelTitle"))}</strong><button type="button" data-v2-ai-adjustment-close>${escapeHtml(tr("close"))}</button></header><ol>${items}</ol></div></section>`;
        }
        const AI_ADJUSTMENT_CSS = `
    .tfa-v2-ai-adjustment{container:aiadjustment / inline-size;display:grid;gap:5px;margin:7px 0;padding:6px;border:1px solid color-mix(in srgb,var(--v2-accent,#6f62d0) 36%,var(--v2-line,#dce1e8));border-radius:9px;color:var(--v2-text,#202631);background:var(--v2-panel,#fff)}
    .tfa-v2-ai-adjustment-bar{min-width:0;display:flex;align-items:center;gap:5px}.tfa-v2-ai-adjustment-summary{min-width:0;min-height:29px;flex:1;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:3px 8px;border:0;border-radius:6px;color:var(--v2-text,#202631);background:var(--v2-accent-soft,#e8e4ff);text-align:left}.tfa-v2-ai-adjustment-summary strong{min-width:0;font-size:10px;overflow-wrap:anywhere}.tfa-v2-ai-adjustment-summary span{flex:0 0 auto;color:var(--v2-accent,#6f62d0);font-size:9px;font-weight:700}.tfa-v2-ai-adjustment-undo{min-height:29px;flex:0 0 auto;padding:3px 9px;border:1px solid var(--v2-line-strong,#cdd4de);border-radius:6px;color:var(--v2-muted,#66717f);background:var(--v2-soft,#f6f8fa);font-size:9px;font-weight:700}.tfa-v2-ai-adjustment-summary:hover,.tfa-v2-ai-adjustment-undo:hover:not(:disabled){color:var(--v2-text,#202631);border-color:color-mix(in srgb,var(--v2-accent,#6f62d0) 48%,var(--v2-line-strong,#cdd4de))}.tfa-v2-ai-adjustment-summary:focus-visible,.tfa-v2-ai-adjustment-undo:focus-visible,.tfa-v2-ai-adjustment-panel button:focus-visible,.tfa-v2-ai-adjustment-panel:focus-visible{outline:2px solid var(--v2-accent,#6f62d0);outline-offset:2px}.tfa-v2-ai-adjustment button:disabled{cursor:not-allowed;opacity:.45}
    .tfa-v2-ai-adjustment-notice{margin:0;padding:4px 7px;border-radius:6px;color:var(--v2-muted,#66717f);background:var(--v2-soft,#f6f8fa);font-size:9px;line-height:1.4;overflow-wrap:anywhere}.tfa-v2-ai-adjustment-notice.is-error{color:var(--v2-danger,#ad4b5a);background:color-mix(in srgb,var(--v2-danger,#ad4b5a) 7%,var(--v2-panel,#fff))}.tfa-v2-ai-adjustment-notice.is-success{color:color-mix(in srgb,#25835f 82%,var(--v2-text,#202631))}
    .tfa-v2-ai-adjustment-panel[hidden]{display:none}.tfa-v2-ai-adjustment-panel{min-width:0;max-height:min(320px,45vh);overflow:auto;border-top:1px solid var(--v2-line,#dce1e8)}.tfa-v2-ai-adjustment-panel>header{min-height:35px;display:flex;align-items:center;gap:8px;padding:5px 2px}.tfa-v2-ai-adjustment-panel>header>strong{font-size:10px}.tfa-v2-ai-adjustment-panel>header>button{min-height:27px;margin-left:auto;padding:2px 7px;border:1px solid var(--v2-line-strong,#cdd4de);border-radius:6px;color:var(--v2-muted,#66717f);background:transparent;font-size:9px}.tfa-v2-ai-adjustment-panel ol{display:grid;gap:5px;margin:0;padding:0;list-style:none}.tfa-v2-ai-adjustment-item{min-width:0;display:grid;gap:5px;padding:7px;border-radius:7px;background:var(--v2-soft,#f6f8fa)}.tfa-v2-ai-adjustment-item>header{min-width:0;display:flex;align-items:center;gap:6px}.tfa-v2-ai-adjustment-item>header>strong{min-width:0;overflow:hidden;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-ai-adjustment-type{flex:0 0 auto;padding:2px 5px;border:1px solid color-mix(in srgb,var(--v2-accent,#6f62d0) 35%,var(--v2-line,#dce1e8));border-radius:5px;color:var(--v2-accent,#6f62d0);background:var(--v2-panel,#fff);font-size:8px;font-weight:700}.tfa-v2-ai-adjustment-diff{min-width:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px}.tfa-v2-ai-adjustment-diff>span{min-width:0;display:grid;gap:2px}.tfa-v2-ai-adjustment-diff small,.tfa-v2-ai-adjustment-item p small{color:var(--v2-faint,#8b95a2);font-size:8px}.tfa-v2-ai-adjustment-diff strong{min-width:0;color:var(--v2-muted,#66717f);font-size:9px;font-weight:600;overflow-wrap:anywhere}.tfa-v2-ai-adjustment-item p{margin:0;color:var(--v2-muted,#66717f);font-size:9px;line-height:1.35;overflow-wrap:anywhere}.tfa-v2-ai-adjustment-item p small{margin-right:5px}
    .tfa-v2-workbench[data-theme="dark"] .tfa-v2-ai-adjustment{background:var(--v2-panel,#11151b)}.tfa-v2-workbench[data-theme="dark"] .tfa-v2-ai-adjustment-notice.is-success{color:#73cba7}
    @container aiadjustment (max-width:420px){.tfa-v2-ai-adjustment-bar{align-items:stretch;flex-wrap:wrap}.tfa-v2-ai-adjustment-summary{flex:1 1 100%}.tfa-v2-ai-adjustment-undo{flex:1 1 100%}.tfa-v2-ai-adjustment-diff{grid-template-columns:1fr}.tfa-v2-ai-adjustment-item>header{align-items:flex-start;flex-direction:column}.tfa-v2-ai-adjustment-item>header>strong{width:100%;white-space:normal;overflow-wrap:anywhere}}
    @media(max-width:800px){.tfa-v2-ai-adjustment-panel{max-height:240px}}
    @media(hover:none){.tfa-v2-ai-adjustment-summary,.tfa-v2-ai-adjustment-undo,.tfa-v2-ai-adjustment-panel>header>button{min-height:32px}}
    @media(prefers-reduced-motion:reduce){.tfa-v2-ai-adjustment *{scroll-behavior:auto!important;transition:none!important;animation:none!important}}
  `;
        function createV2AiAdjustmentView({ root, locale = "en", t, onUndo } = {}) {
          if (!root || typeof root.addEventListener !== "function" || typeof root.removeEventListener !== "function") {
            throw new TypeError("AI adjustment view requires a root element");
          }
          let summary = null;
          let expanded = false;
          let destroyed = false;
          let undoPending = false;
          function render() {
            if (destroyed) return;
            root.innerHTML = summary ? buildAdjustmentMarkup(summary, { locale, t, expanded }) : "";
          }
          function setSummary(value) {
            summary = normalizeAdjustmentSummary(value);
            expanded = false;
            undoPending = false;
            render();
            return summary;
          }
          function clear() {
            summary = null;
            expanded = false;
            undoPending = false;
            render();
          }
          function open() {
            if (summary) {
              expanded = true;
              render();
            }
          }
          function close({ restoreFocus = false } = {}) {
            if (!summary) return;
            expanded = false;
            render();
            if (restoreFocus) root.querySelector?.("[data-v2-ai-adjustment-toggle]")?.focus?.();
          }
          async function undo() {
            if (!summary || undoPending || summary.status === "undone") return false;
            undoPending = true;
            summary = Object.freeze({ ...summary, status: "undoing", errorCode: "" });
            render();
            let result;
            try {
              result = typeof onUndo === "function" ? await onUndo(summary.changeId) : { ok: false };
            } catch (_error) {
              result = { ok: false, errorCode: "AI_REQUEST_FAILED" };
            }
            const success = result?.ok === true;
            const conflict = result?.errorCode === "AI_PLAN_UNDO_CONFLICT";
            summary = Object.freeze({
              ...summary,
              status: success ? "undone" : conflict ? "conflict" : "failed",
              errorCode: success ? "" : conflict ? "AI_PLAN_UNDO_CONFLICT" : "AI_REQUEST_FAILED"
            });
            undoPending = false;
            render();
            return success;
          }
          function onClick(event) {
            if (event.target?.closest?.("[data-v2-ai-adjustment-toggle]")) {
              expanded ? close() : open();
            } else if (event.target?.closest?.("[data-v2-ai-adjustment-close]")) {
              close({ restoreFocus: true });
            } else if (event.target?.closest?.("[data-v2-ai-adjustment-undo]")) {
              void undo();
            }
          }
          function onKeydown(event) {
            if (expanded && event.key === "Escape") {
              event.preventDefault?.();
              close({ restoreFocus: true });
            }
          }
          function destroy() {
            if (destroyed) return;
            destroyed = true;
            root.removeEventListener("click", onClick);
            root.removeEventListener("keydown", onKeydown);
            root.innerHTML = "";
          }
          root.addEventListener("click", onClick);
          root.addEventListener("keydown", onKeydown);
          render();
          return Object.freeze({ setSummary, clear, open, close, undo, destroy });
        }
        return Object.freeze({
          TYPES,
          STATES,
          AI_ADJUSTMENT_CSS,
          normalizeAdjustmentSummary,
          buildAdjustmentMarkup,
          createV2AiAdjustmentView
        });
      });
    }
  });

  // src/content/v2-experimental-task-views.js
  var require_v2_experimental_task_views = __commonJS({
    "src/content/v2-experimental-task-views.js"(exports, module) {
      (function attachV2ExperimentalTaskViews(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2ExperimentalTaskViews = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2ExperimentalTaskViewsModule() {
        "use strict";
        const VIEW_MODES = Object.freeze(["cards", "aggregate", "fishbone"]);
        const CSS = `
    .tfa-v2-task-view-switch{display:flex;gap:2px;padding:2px;border:1px solid var(--v2-line-strong);border-radius:7px;background:var(--v2-soft)}
    .tfa-v2-task-view-switch button{height:25px;padding:0 7px;border:0;border-radius:5px;color:var(--v2-muted);background:transparent;font-size:9px;white-space:nowrap}
    .tfa-v2-task-view-switch button:hover{color:var(--v2-text);background:color-mix(in srgb,var(--v2-accent) 7%,transparent)}
    .tfa-v2-task-view-switch button:focus-visible{outline:2px solid var(--v2-accent);outline-offset:1px}
    .tfa-v2-task-view-switch button.is-active{color:var(--v2-text);background:var(--v2-panel);box-shadow:0 1px 4px rgba(23,28,40,.08)}
    .tfa-v2-experimental-view{min-height:100%;display:grid;align-content:start;gap:12px;padding:2px}
    .tfa-v2-experimental-note{display:flex;align-items:center;gap:8px;padding:8px 10px;border:1px dashed var(--v2-line-strong);border-radius:9px;color:var(--v2-muted);background:var(--v2-soft);font-size:10px;line-height:1.45}
    .tfa-v2-experimental-badge{flex:0 0 auto;padding:2px 6px;border-radius:5px;color:var(--v2-accent);background:color-mix(in srgb,var(--v2-accent) 10%,transparent);font-weight:700}
    .tfa-v2-aggregate{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:14px;padding:14px}
    .tfa-v2-aggregate-task{width:var(--aggregate-size);height:var(--aggregate-size);min-width:88px;min-height:88px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;padding:12px;border:1px solid color-mix(in srgb,var(--task-color) 35%,var(--v2-line));border-radius:50%;color:var(--v2-text);background:color-mix(in srgb,var(--task-color) 9%,var(--v2-panel));text-align:center}
    .tfa-v2-aggregate-task strong{max-width:100%;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-aggregate-task small{color:var(--v2-muted);font-size:9px}
    .tfa-v2-fishbone{position:relative;display:grid;grid-auto-flow:column;grid-auto-columns:minmax(150px,1fr);align-items:center;gap:14px;min-width:max-content;padding:118px 18px}
    .tfa-v2-fishbone::before{content:"";position:absolute;left:18px;right:18px;top:50%;height:2px;background:var(--v2-line-strong)}
    .tfa-v2-fishbone-task{position:relative;width:150px;display:grid;gap:6px;padding:9px;border:1px solid var(--v2-line);border-top:3px solid var(--task-color);border-radius:9px;background:var(--v2-panel);box-shadow:0 5px 14px rgba(23,28,40,.06)}
    .tfa-v2-fishbone-task:nth-child(even){transform:translateY(-82px)}.tfa-v2-fishbone-task:nth-child(odd){transform:translateY(82px)}
    .tfa-v2-fishbone-task::after{content:"";position:absolute;left:50%;width:1px;height:77px;background:var(--v2-line-strong)}
    .tfa-v2-fishbone-task:nth-child(even)::after{top:100%}.tfa-v2-fishbone-task:nth-child(odd)::after{bottom:100%}
    .tfa-v2-fishbone-task strong{overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.tfa-v2-fishbone-task small{color:var(--v2-muted);font-size:9px}
    .tfa-v2-fishbone-pages{display:grid;gap:4px}.tfa-v2-fishbone-page{overflow:hidden;padding:4px 6px;border-radius:5px;color:var(--v2-muted);background:var(--v2-soft);font-size:9px;text-overflow:ellipsis;white-space:nowrap}
    .tfa-v2-fishbone-scroll{overflow:auto hidden;padding-bottom:8px}
    @container taskpane (max-width:560px){.tfa-v2-task-view-switch{width:100%;order:3}.tfa-v2-task-view-switch button{flex:1 1 0}.tfa-v2-aggregate{gap:10px;padding:8px}.tfa-v2-fishbone{padding-left:10px;padding-right:10px}}
    @media(max-width:620px){.tfa-v2-experimental-note{align-items:flex-start}.tfa-v2-aggregate-task{--aggregate-size:96px!important}.tfa-v2-fishbone{grid-auto-columns:140px}.tfa-v2-fishbone-task{width:140px}}
  `;
        const normalizeView = (value) => VIEW_MODES.includes(String(value)) ? String(value) : "cards";
        const sortByOrder = (items) => (Array.isArray(items) ? items : []).map((item, index) => ({ item, index })).sort((left, right) => {
          const leftOrder = Number.isFinite(Number(left.item?.sortOrder)) ? Number(left.item.sortOrder) : left.index;
          const rightOrder = Number.isFinite(Number(right.item?.sortOrder)) ? Number(right.item.sortOrder) : right.index;
          return leftOrder - rightOrder || left.index - right.index;
        }).map(({ item }) => item);
        const pagesOf = (task) => sortByOrder(task?.pages || task?.tabs || []);
        function createExperimentalTaskViews(options = {}) {
          const escapeHtml = options.escapeHtml || ((value) => String(value));
          const tr = typeof options.tr === "function" ? options.tr : (_key, fallback) => fallback;
          const colorOf = typeof options.colorOf === "function" ? options.colorOf : () => "#6f62d0";
          const titleOf = (task) => task?.title || task?.name || tr("task.untitled", "Untitled task");
          const note = () => `<div class="tfa-v2-experimental-note"><span class="tfa-v2-experimental-badge">${escapeHtml(tr("task.view.experimentalBadge", "Experimental"))}</span><span>${escapeHtml(tr("task.view.experimentalHint", "Read-only basic view based on current task relations. More layout detail will be added later."))}</span></div>`;
          const empty = () => `<div class="tfa-v2-empty"><strong>${escapeHtml(tr("task.view.empty", "No task data to visualize"))}</strong><small>${escapeHtml(tr("task.view.emptyHint", "Create or match tasks, then return to this view."))}</small></div>`;
          function renderAggregate(tasks) {
            const ordered = sortByOrder(tasks);
            if (!ordered.length) return `<div class="tfa-v2-experimental-view">${note()}${empty()}</div>`;
            const counts = ordered.map((task) => pagesOf(task).length);
            const max = Math.max(1, ...counts);
            const circles = ordered.map((task, index) => {
              const count = counts[index];
              const size = Math.round(88 + Math.sqrt(count / max) * 68);
              return `<article class="tfa-v2-aggregate-task" style="--task-color:${escapeHtml(colorOf(task))};--aggregate-size:${size}px" title="${escapeHtml(titleOf(task))}"><strong>${escapeHtml(titleOf(task))}</strong><small>${escapeHtml(tr("task.view.pageCount", "{count} pages", { count }))}</small></article>`;
            }).join("");
            return `<div class="tfa-v2-experimental-view">${note()}<div class="tfa-v2-aggregate" aria-label="${escapeHtml(tr("task.view.aggregateAria", "Task aggregation view"))}">${circles}</div></div>`;
          }
          function renderFishbone(tasks) {
            const ordered = sortByOrder(tasks);
            if (!ordered.length) return `<div class="tfa-v2-experimental-view">${note()}${empty()}</div>`;
            const bones = ordered.map((task) => {
              const pages = pagesOf(task);
              const pageMarkup = pages.length ? `<div class="tfa-v2-fishbone-pages">${pages.map((page) => `<span class="tfa-v2-fishbone-page" title="${escapeHtml(page.title || page.url || "")}">${escapeHtml(page.title || page.url || tr("workbench.unknownPage", "Unknown page"))}</span>`).join("")}</div>` : `<small>${escapeHtml(tr("task.view.noPages", "No related pages"))}</small>`;
              return `<article class="tfa-v2-fishbone-task" style="--task-color:${escapeHtml(colorOf(task))}"><strong title="${escapeHtml(titleOf(task))}">${escapeHtml(titleOf(task))}</strong>${pageMarkup}</article>`;
            }).join("");
            return `<div class="tfa-v2-experimental-view">${note()}<div class="tfa-v2-fishbone-scroll"><div class="tfa-v2-fishbone" aria-label="${escapeHtml(tr("task.view.fishboneAria", "Task fishbone view"))}">${bones}</div></div></div>`;
          }
          return Object.freeze({
            render(mode, tasks) {
              return normalizeView(mode) === "fishbone" ? renderFishbone(tasks) : renderAggregate(tasks);
            }
          });
        }
        return Object.freeze({ VIEW_MODES, CSS, normalizeView, sortByOrder, pagesOf, createExperimentalTaskViews });
      });
    }
  });

  // src/content/v2-workbench-renderer.js
  var require_v2_workbench_renderer = __commonJS({
    "src/content/v2-workbench-renderer.js"(exports, module) {
      (function attachV2WorkbenchRenderer(rootScope, factory) {
        const adjustmentModule = typeof module === "object" && module.exports ? require_v2_ai_adjustment_view() : rootScope.TfaV2AiAdjustmentView;
        const experimentalViewsModule = typeof module === "object" && module.exports ? require_v2_experimental_task_views() : rootScope.TfaV2ExperimentalTaskViews;
        const nativeGroupViewModule = typeof module === "object" && module.exports ? require_v2_native_tab_group_view() : rootScope.TfaV2NativeTabGroupView;
        const tabAwarenessViewModule = typeof module === "object" && module.exports ? require_v2_tab_awareness_view() : rootScope.TfaV2TabAwarenessView;
        const browserTabSortModule = typeof module === "object" && module.exports ? require_v2_browser_tab_sort() : rootScope.TfaV2BrowserTabSort;
        const api = factory(adjustmentModule, experimentalViewsModule, nativeGroupViewModule, tabAwarenessViewModule, browserTabSortModule);
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchRenderer = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchRendererModule(adjustmentModule, experimentalViewsModule, nativeGroupViewModule, tabAwarenessViewModule, browserTabSortModule) {
        "use strict";
        const TASK_COLORS = ["#6f62d0", "#3c8f82", "#4e7fc5", "#b47a3c", "#a75a71", "#7d6cad"];
        const DOMAIN_FALLBACKS = { work: "\u5DE5\u4F5C", study: "\u5B66\u4E60", life: "\u751F\u6D3B", interest: "\u5174\u8DA3", admin: "\u4E8B\u52A1", other: "\u5176\u4ED6" };
        const STATUS_FALLBACKS = { active: "\u8FDB\u884C\u4E2D", paused: "\u5DF2\u6682\u505C", done: "\u5DF2\u5B8C\u6210", pending: "\u5F85\u5212\u5206" };
        const hash = (value) => [...String(value || "")].reduce((result, character) => result * 31 + character.charCodeAt(0) | 0, 0);
        const fallbackColor = (value) => TASK_COLORS[Math.abs(hash(value)) % TASK_COLORS.length];
        const safeColor = (value, fallback) => /^#[0-9a-f]{6}$/i.test(String(value || "")) ? value : fallback;
        const pad2 = (value) => String(value).padStart(2, "0");
        function formatRecycleTime(value, now = Date.now(), labels = {}) {
          const raw = String(value == null ? "" : value).trim();
          let timestamp = Number(raw);
          if (Number.isFinite(timestamp) && timestamp > 0 && timestamp < 1e12) timestamp *= 1e3;
          if (!Number.isFinite(timestamp) || timestamp <= 0) timestamp = Date.parse(raw);
          if (!Number.isFinite(timestamp)) {
            const display2 = raw || (labels.recently || "\u521A\u521A");
            return Object.freeze({ display: display2, absolute: raw });
          }
          const date = new Date(timestamp);
          const current = new Date(Number.isFinite(Number(now)) ? Number(now) : Date.now());
          const absolute = `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())}`;
          const minutes = Math.max(0, Math.floor((current.getTime() - date.getTime()) / 6e4));
          let display;
          if (minutes < 1) display = labels.recently || "\u521A\u521A";
          else if (minutes < 60) display = typeof labels.minutesAgo === "function" ? labels.minutesAgo(minutes) : `${minutes} \u5206\u949F\u524D`;
          else if (date.getFullYear() === current.getFullYear() && date.getMonth() === current.getMonth() && date.getDate() === current.getDate()) {
            display = `${labels.today || "\u4ECA\u5929"} ${pad2(date.getHours())}:${pad2(date.getMinutes())}`;
          } else {
            display = `${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}`;
          }
          return Object.freeze({ display, absolute });
        }
        function safeImageUrl(value) {
          const url = String(value || "").trim();
          if (/^data:image\//i.test(url)) return url;
          try {
            const parsed = new URL(url);
            return ["http:", "https:", "chrome-extension:", "moz-extension:"].includes(parsed.protocol) ? url : "";
          } catch (_error) {
            return "";
          }
        }
        function createV2WorkbenchRenderer(options = {}) {
          const {
            root,
            logic,
            template,
            state,
            callbacks,
            tr,
            escapeHtml,
            browserContent,
            taskContent,
            windowOptionsRoot,
            statusSelect,
            domainSelect,
            taskSortSelect,
            recycleContent,
            recycleCount,
            restoreAllButton,
            selectedSuggestionIds,
            selectedBatchSuggestionIds
          } = options;
          const renderEmpty = (titleKey, title, hintKey, hint) => `<div class="tfa-v2-empty"><strong>${escapeHtml(tr(titleKey, title))}</strong><small>${escapeHtml(tr(hintKey, hint))}</small></div>`;
          const domainLabel = (domain) => tr(`domain.${domain}`, DOMAIN_FALLBACKS[domain] || domain);
          const statusLabel = (status) => tr(`task.status.${status}`, STATUS_FALLBACKS[status] || status);
          const OBSERVATION_STATES = /* @__PURE__ */ new Set(["observing", "temporary_query", "possible_misclick", "redirect_or_ad", "intent_drift"]);
          const tabLetter = (tab) => [...logic.hostOf(tab.url) || tab.title || "?"][0].toUpperCase();
          const findTaskPage = (task, id) => (task?.pages || task?.tabs || []).find((page) => String(page.id) === String(id));
          const batch = () => options.getBatchState();
          const adjustmentHost = root.querySelector("[data-v2-ai-adjustment-host]");
          const adjustmentView = adjustmentHost && adjustmentModule?.createV2AiAdjustmentView ? adjustmentModule.createV2AiAdjustmentView({
            root: adjustmentHost,
            locale: options.locale,
            t: tr,
            onUndo: options.onUndoAiPlan
          }) : null;
          if (options.aiAdjustment) adjustmentView?.setSummary(options.aiAdjustment);
          const experimentalViews = experimentalViewsModule?.createExperimentalTaskViews?.({
            escapeHtml,
            tr,
            colorOf: (task) => safeColor(task?.color, fallbackColor(task?.id || task?.title))
          });
          const nativeGroupView = nativeGroupViewModule?.createNativeTabGroupView?.({
            root,
            template,
            tr,
            escapeHtml,
            renderTab,
            onIntent: callbacks.onNativeGroupIntent,
            onWindowIntent: callbacks.onNativeWindowIntent,
            onEditGroup: callbacks.onEditNativeGroup
          });
          function previewTab(id) {
            const direct = state.tabs.find((tab) => String(tab.id) === String(id));
            if (direct) return direct;
            const page = state.tasks.flatMap((task) => task.pages || task.tabs || []).find((tab) => String(tab.id) === String(id)) || state.inboxPages.find((tab) => String(tab.id) === String(id));
            if (!page) return null;
            const live = state.tabs.find((tab) => Number(tab.id) === Number(page.liveTabId)) || state.tabs.find((tab) => page.linkKey && tab.linkKey === page.linkKey);
            return live ? { ...page, ...live, id: page.id, liveTabId: live.id, isOpen: true } : page;
          }
          const tabAwarenessView = tabAwarenessViewModule?.createTabAwarenessView?.({
            root,
            previewContainer: root.querySelector?.(".tfa-v2-workbench") || root,
            tr,
            escapeHtml,
            getTab: previewTab,
            onRequestPreview: options.onRequestTabPreview
          });
          const hidePreviewDuringDrag = () => tabAwarenessView?.hidePreview?.();
          root.addEventListener?.("dragstart", hidePreviewDuringDrag);
          const browserTabSort = browserTabSortModule?.createBrowserTabSort?.({ root, getTabs: () => state.tabs, onMove: callbacks.onReorderBrowserTab });
          function renderIcon(tab) {
            const favicon = safeImageUrl(tab.favIconUrl || tab.faviconUrl || tab.favicon);
            const image = favicon ? `<img src="${escapeHtml(favicon)}" alt="" draggable="false">` : "";
            return `<span class="tfa-v2-site-icon${favicon ? " has-image" : ""}" style="--site-color:${fallbackColor(logic.hostOf(tab.url) || tab.title)}"><b>${escapeHtml(tabLetter(tab))}</b>${image}</span>`;
          }
          function acceptedSuggestionId(evidence) {
            const match = /^accepted:(suggestion-[A-Za-z0-9][A-Za-z0-9._-]{0,159}):[a-z_]+$/.exec(String(evidence || ""));
            return match ? match[1] : "";
          }
          function replacementTasksForPage(page, currentTask) {
            const relatedIds = Array.isArray(page?.relatedTaskIds) && page.relatedTaskIds.length ? page.relatedTaskIds.map(String) : state.tasks.filter((task) => findTaskPage(task, page?.id)).map((task) => String(task.id));
            const uniqueIds = new Set(relatedIds.filter((taskId) => taskId !== String(currentTask?.id)));
            return state.tasks.filter((task) => uniqueIds.has(String(task.id)));
          }
          function renderTab(tab, context, task = null) {
            const domain = logic.hostOf(tab.url) || tr("workbench.unknownPage", "\u672A\u77E5\u9875\u9762");
            const dwellMs = Math.max(0, Number(tab.sessionDwellTotalMs) || 0) + (Number(tab.sessionDwellActiveSince) > 0 ? Math.max(0, Date.now() - Number(tab.sessionDwellActiveSince)) : 0);
            const dwell = tab.sessionDwellTracked ? `<span class="tfa-v2-session-dwell" data-v2-dwell-total="${escapeHtml(tab.sessionDwellTotalMs || 0)}" data-v2-dwell-since="${escapeHtml(tab.sessionDwellActiveSince || "")}" data-v2-dwell-language="${escapeHtml(tab.dwellLanguage || "zh")}">${escapeHtml(tr("workbench.sessionDwell", "\u505C\u7559 {time}", { time: tabAwarenessViewModule.formatSessionDwell(dwellMs, tab.dwellLanguage) }))}</span>` : "";
            const availability = context === "task" ? `<span class="tfa-v2-availability${tab.isOpen ? " is-open" : " is-history"}" role="img" title="${escapeHtml(tr(tab.isOpen ? "workbench.pageOpenNow" : "workbench.pageHistory", tab.isOpen ? "\u6D4F\u89C8\u5668\u4E2D\u5DF2\u6253\u5F00" : "\u5386\u53F2\u9875\u9762\uFF0C\u70B9\u51FB\u91CD\u65B0\u6253\u5F00"))}" aria-label="${escapeHtml(tr(tab.isOpen ? "workbench.pageOpenNow" : "workbench.pageHistory", tab.isOpen ? "\u6D4F\u89C8\u5668\u4E2D\u5DF2\u6253\u5F00" : "\u5386\u53F2\u9875\u9762\uFF0C\u70B9\u51FB\u91CD\u65B0\u6253\u5F00"))}"></span>` : "";
            const smartRelation = ["rule", "ai", "suggested"].includes(String(tab.source || ""));
            const relationSuggestionId = context === "task" ? acceptedSuggestionId(tab.evidence) : "";
            const relationPending = relationSuggestionId && state.pendingSuggestionIds.has(relationSuggestionId);
            const relationUndoLabel = tr("suggestion.aria.undoAccepted", "\u64A4\u9500\u667A\u80FD\u5F52\u7C7B\uFF1A{task}", { task: task?.title || task?.name || tr("task.untitled", "\u672A\u547D\u540D\u4EFB\u52A1") });
            const relationUndo = relationSuggestionId ? `<button type="button" class="tfa-v2-smart-undo" data-v2-undo-suggestion="${escapeHtml(relationSuggestionId)}" data-v2-suggestion-id="${escapeHtml(relationSuggestionId)}" data-v2-task-id="${escapeHtml(task?.id || "")}"${relationPending ? " disabled" : ""} aria-label="${escapeHtml(relationUndoLabel)}" title="${escapeHtml(relationUndoLabel)}">${escapeHtml(tr("suggestion.action.undo", "\u64A4\u9500"))}</button>` : "";
            const relationSource = context === "task" ? `<span class="tfa-v2-source-tag is-${smartRelation ? "smart" : "manual"}">${escapeHtml(tr(smartRelation ? "task.source.smart" : "task.source.manual", smartRelation ? "\u667A\u80FD\u5206\u7C7B" : "\u624B\u52A8\u5206\u7C7B"))}</span>${tab.isPrimary && Array.isArray(tab.relatedTaskIds) && tab.relatedTaskIds.length > 1 ? `<span class="tfa-v2-relation-primary" title="${escapeHtml(tr("task.relation.primaryHint", "\u6B64\u9875\u9762\u7684\u4E3B\u8981\u4EFB\u52A1"))}">${escapeHtml(tr("task.relation.primary", "\u4E3B\u8981\u4EFB\u52A1"))}</span>` : ""}` : "";
            const flags = [
              tab.dockFixed ? `<span class="tfa-v2-pill">${escapeHtml(tr("tab.dockFixed", "\u5DF2\u56FA\u5B9A\u5230\u62D3\u5C55\u575E"))}</span>` : "",
              tab.groupTitle ? `<span class="tfa-v2-pill">${escapeHtml(tab.groupTitle)}</span>` : "",
              tab.sharedTool ? `<span class="tfa-v2-pill is-shared">${escapeHtml(tr("inbox.sharedBadge", "\u5171\u4EAB\u5DE5\u5177 / \u591A\u4EFB\u52A1\u9875"))}</span>` : ""
            ].filter(Boolean).join("");
            const observationState = context === "inbox" && OBSERVATION_STATES.has(String(tab.observationState || "")) ? String(tab.observationState) : "";
            const observation = observationState ? (() => {
              const reasonCode = OBSERVATION_STATES.has(String(tab.reasonCode || "")) ? String(tab.reasonCode) : observationState;
              const label = tr(`inbox.observation.${observationState}.label`, observationState);
              const reason = tr(`inbox.observation.${reasonCode}.reason`, "");
              const accessible = reason ? `${label} \xB7 ${reason}` : label;
              return `<span class="tfa-v2-observation is-${escapeHtml(observationState)}" data-v2-observation-state="${escapeHtml(observationState)}" data-v2-observation-reason="${escapeHtml(reasonCode)}" role="status" aria-label="${escapeHtml(accessible)}" title="${escapeHtml(accessible)}"><b>${escapeHtml(label)}</b>${reason ? `<small>${escapeHtml(reason)}</small>` : ""}</span>`;
            })() : "";
            const taskId = task ? String(task.id) : "";
            const replacementTasks = task && (tab.isPrimary || tab.role === "primary") ? replacementTasksForPage(tab, task) : [];
            const replacementMenu = replacementTasks.length > 1 ? `<div class="tfa-v2-menu tfa-v2-primary-menu" data-v2-primary-menu role="menu" hidden><span class="tfa-v2-menu-label">${escapeHtml(tr("task.chooseNewPrimary", "\u9009\u62E9\u65B0\u7684\u4E3B\u8981\u4EFB\u52A1"))}</span>${replacementTasks.map((candidate) => `<button type="button" data-v2-replacement-task="${escapeHtml(candidate.id)}" data-v2-source-task="${escapeHtml(taskId)}" data-v2-page-id="${escapeHtml(tab.id)}" role="menuitem">${escapeHtml(candidate.title || candidate.name || tr("task.untitled", "\u672A\u547D\u540D\u4EFB\u52A1"))}</button>`).join("")}</div>` : "";
            const secondaryAction = context === "browser" || context === "inbox" ? `<button type="button" class="tfa-v2-tab-action is-danger" data-v2-close-tab="${escapeHtml(tab.id)}" aria-label="${escapeHtml(tr("tab.close", "\u5173\u95ED\u9875\u7B7E"))}" title="${escapeHtml(tr("tab.close", "\u5173\u95ED\u9875\u7B7E"))}">${template.icon("close")}</button>` : context === "task" ? `<button type="button" class="tfa-v2-tab-action is-danger" data-v2-remove-tab="${escapeHtml(tab.id)}" data-v2-task-id="${escapeHtml(taskId)}"${replacementMenu ? ' aria-haspopup="menu" aria-expanded="false"' : ""} aria-label="${escapeHtml(tr("task.removePage", "\u79FB\u51FA\u4EFB\u52A1"))}" title="${escapeHtml(tr("task.removePage", "\u79FB\u51FA\u4EFB\u52A1"))}">${template.icon("remove")}</button>${replacementMenu}` : "";
            return `<article class="tfa-v2-tab${tab.active ? " is-active" : ""}" data-v2-tab="${escapeHtml(tab.id)}" data-v2-link-key="${escapeHtml(tab.linkKey || "")}" data-v2-context="${context}" data-v2-task-id="${escapeHtml(taskId)}">
        <button type="button" class="tfa-v2-tab-main" draggable="true" data-v2-activate-tab="${escapeHtml(tab.id)}" aria-label="${escapeHtml(tr("tab.activate", "\u5207\u6362\u5230 {title}", { title: tab.title || domain }))}">${renderIcon(tab)}<span class="tfa-v2-tab-copy"><strong>${escapeHtml(tab.title || domain)}</strong><span class="tfa-v2-tab-meta">${relationSource}<small>${escapeHtml(domain)}</small>${dwell}</span>${observation}${flags ? `<span class="tfa-v2-tab-flags">${flags}</span>` : ""}</span></button>
        ${availability}<span class="tfa-v2-tab-actions">${relationUndo}<button type="button" class="tfa-v2-tab-action" data-v2-tab-more="${escapeHtml(tab.id)}" data-v2-task-id="${escapeHtml(taskId)}" aria-haspopup="menu" aria-expanded="false" aria-label="${escapeHtml(tr("tab.more", "\u66F4\u591A\u64CD\u4F5C"))}" title="${escapeHtml(tr("tab.more", "\u66F4\u591A\u64CD\u4F5C"))}">${template.icon("more")}</button>${secondaryAction}</span>
      </article>`;
          }
          function renderBrowser(model) {
            root.querySelector("[data-v2-browser-count]").textContent = String(model.visibleTabCount);
            windowOptionsRoot.innerHTML = [
              `<button type="button" data-v2-window="all">${escapeHtml(tr("workbench.allWindows", "\u5168\u90E8\u7A97\u53E3"))}</button>`,
              ...model.windows.map((windowId, index) => `<button type="button" data-v2-window="${escapeHtml(windowId)}">${escapeHtml(tr("workbench.window", "\u7A97\u53E3 {number}", { number: index + 1 }))}</button>`)
            ].join("");
            windowOptionsRoot.querySelectorAll("[data-v2-window]").forEach((button) => button.classList.toggle("is-active", button.dataset.v2Window === state.windowFilter));
            const columnControl = `<label class="tfa-v2-browser-columns" data-v2-browser-columns-control><span>${escapeHtml(tr("workbench.columns", "\u5217\u6570"))}</span><input type="range" min="4" max="6" step="1" value="${escapeHtml(state.browserColumns)}" data-v2-browser-columns aria-label="${escapeHtml(tr("workbench.columnsAria", "\u6BCF\u884C\u9875\u7B7E\u6570\u91CF"))}"><output data-v2-browser-columns-value>${escapeHtml(tr("workbench.columnsValue", "{count} \u5217", { count: state.browserColumns }))}</output></label>`;
            const nativeMarkup = model.nativeTabWindows.length && nativeGroupView ? nativeGroupView.render(model.nativeTabWindows, (windowId) => model.windows.indexOf(String(windowId)) + 1) : "";
            browserContent.innerHTML = nativeMarkup ? nativeMarkup.replace('<span class="tfa-v2-window-actions">', `${columnControl}<span class="tfa-v2-window-actions">`) : renderEmpty("workbench.noTabs", "\u6CA1\u6709\u5339\u914D\u7684\u9875\u7B7E", "workbench.noTabsHint", "\u6362\u4E00\u4E2A\u5173\u952E\u8BCD\u6216\u7A97\u53E3\u8BD5\u8BD5");
          }
          function renderTask(task) {
            const id = String(task.id);
            const taskColor = safeColor(task.color, fallbackColor(id || task.title));
            const title = task.title || task.name || tr("task.untitled", "\u672A\u547D\u540D\u4EFB\u52A1");
            const pages = task.pages || [];
            const taskDomain = task.domainId || task.domain || "other";
            const expanded = state.expandedTaskIds.has(id);
            const manualIds = options.manualTaskOrder();
            const manualIndex = manualIds.indexOf(id);
            const canReorder = options.canManuallyReorderTasks();
            const dragHint = canReorder ? tr("task.dragToReorder", "\u62D6\u52A8\u8C03\u6574\u4EFB\u52A1\u987A\u5E8F") : tr("task.dragDisabledByFilter", "\u5207\u6362\u4E3A\u624B\u52A8\u6392\u5E8F\u5E76\u6E05\u9664\u7B5B\u9009\u540E\u53EF\u62D6\u52A8");
            const domainMenu = logic.TASK_DOMAINS.map((domain) => `<button type="button" data-v2-set-domain="${escapeHtml(domain)}" data-v2-task-id="${escapeHtml(id)}" role="menuitemradio" aria-checked="${domain === taskDomain}" class="${domain === taskDomain ? "is-current" : ""}">${escapeHtml(domainLabel(domain))}</button>`).join("");
            const statusMenu = logic.TASK_STATUSES.map((status) => `<button type="button" data-v2-set-status="${status}" data-v2-task-id="${escapeHtml(id)}" role="menuitemradio" aria-checked="${status === task.status}" class="${status === task.status ? "is-current" : ""}"><span class="tfa-v2-status-dot is-${status}" aria-hidden="true"></span>${escapeHtml(statusLabel(status))}</button>`).join("");
            const titleHint = tr("task.renameHint", "\u70B9\u51FB\u53EF\u4FEE\u6539\u6807\u9898");
            const toggleLabel = expanded ? tr("task.collapsePages", "\u6536\u8D77\u4E3A\u4E00\u884C") : tr("task.expandPages", "\u5C55\u5F00\u5168\u90E8\u9875\u7B7E");
            const pageContent = pages.length ? `<div class="tfa-v2-task-pages" id="tfa-v2-task-pages-${escapeHtml(id)}"><div class="tfa-v2-tab-grid">${pages.map((page) => renderTab(page, "task", task)).join("")}</div></div>` : "";
            const relationSuggestions = pages.filter((page) => page.isPrimary === true).map((page) => {
              const block = suggestionBlockForPage(pageIdOf(page));
              return block?.mode === "multi-associate" ? `<div class="tfa-v2-task-relation-suggestion"><small>${escapeHtml(tr("suggestion.label.relatedPage", "\u9875\u9762\u201C{page}\u201D\u8FD8\u6709\u5173\u8054\u4EFB\u52A1\u5019\u9009", { page: page.title || logic.hostOf(page.url) || tr("workbench.unknownPage", "\u672A\u77E5\u9875\u9762") }))}</small>${renderSuggestionBlock(block)}</div>` : "";
            }).filter(Boolean).join("");
            const footer = pages.length > 1 ? `<footer class="tfa-v2-task-footer"><button type="button" data-v2-task-toggle="${escapeHtml(id)}" aria-expanded="${expanded}" aria-controls="tfa-v2-task-pages-${escapeHtml(id)}" aria-label="${escapeHtml(toggleLabel)}" title="${escapeHtml(toggleLabel)}">${template.icon(expanded ? "chevron-up" : "chevron-down")}</button></footer>` : "";
            return `<section class="tfa-v2-task${expanded ? " is-expanded" : ""}" data-v2-task="${escapeHtml(id)}" style="--task-color:${taskColor}"><header class="tfa-v2-task-header"><button type="button" class="tfa-v2-task-drag-handle" data-v2-task-drag-handle="${escapeHtml(id)}" draggable="${canReorder}" aria-label="${escapeHtml(dragHint)}" title="${escapeHtml(dragHint)}"${canReorder ? "" : " disabled"}>${template.icon("drag")}</button><button type="button" class="tfa-v2-task-title" data-v2-edit-task="${escapeHtml(id)}" aria-label="${escapeHtml(tr("task.renameAria", "\u4FEE\u6539\u4EFB\u52A1\u6807\u9898\uFF1A{title}", { title }))}" title="${escapeHtml(titleHint)}"><strong>${escapeHtml(title)}</strong><small>${escapeHtml(titleHint)}</small></button><div class="tfa-v2-task-tags"><div class="tfa-v2-domain-control"><button type="button" class="tfa-v2-domain-trigger" data-v2-domain-trigger="${escapeHtml(id)}" aria-haspopup="menu" aria-expanded="false">${escapeHtml(domainLabel(taskDomain))}</button><div class="tfa-v2-menu tfa-v2-domain-menu" data-v2-domain-menu role="menu" hidden>${domainMenu}</div></div><div class="tfa-v2-status-control"><button type="button" class="tfa-v2-status-trigger" data-v2-status-trigger="${escapeHtml(id)}" aria-haspopup="menu" aria-expanded="false"><span class="tfa-v2-status-dot is-${escapeHtml(task.status)}" aria-hidden="true"></span>${escapeHtml(statusLabel(task.status))}</button><div class="tfa-v2-menu tfa-v2-status-menu" data-v2-status-menu role="menu" hidden>${statusMenu}</div></div></div><div class="tfa-v2-task-header-actions"><button type="button" class="tfa-v2-task-action" data-v2-open-task="${escapeHtml(id)}">${escapeHtml(tr("task.openAll", "\u6253\u5F00\u5168\u90E8"))}</button><button type="button" class="tfa-v2-task-action is-danger" data-v2-close-task="${escapeHtml(id)}"${task.hasOpenTabs === false ? " disabled" : ""}>${escapeHtml(tr("task.closeAll", "\u5173\u95ED\u5168\u90E8"))}</button><div class="tfa-v2-task-more-wrap"><button type="button" class="tfa-v2-task-action" data-v2-task-more="${escapeHtml(id)}" aria-haspopup="menu" aria-expanded="false">${escapeHtml(tr("task.more", "\u66F4\u591A"))}</button><div class="tfa-v2-menu tfa-v2-task-more-menu" data-v2-task-more-menu role="menu" hidden><button type="button" data-v2-move-task="-1" data-v2-task-id="${escapeHtml(id)}" role="menuitem"${canReorder && manualIndex > 0 ? "" : " disabled"}>${escapeHtml(tr("task.moveUp", "\u4E0A\u79FB\u4EFB\u52A1"))}</button><button type="button" data-v2-move-task="1" data-v2-task-id="${escapeHtml(id)}" role="menuitem"${canReorder && manualIndex < manualIds.length - 1 ? "" : " disabled"}>${escapeHtml(tr("task.moveDown", "\u4E0B\u79FB\u4EFB\u52A1"))}</button><button type="button" class="is-danger" data-v2-dissolve-task="${escapeHtml(id)}" role="menuitem">${escapeHtml(tr("task.dissolve", "\u89E3\u6563\u4EFB\u52A1"))}</button></div></div></div></header>${pageContent}${relationSuggestions}${footer}</section>`;
          }
          const pageIdOf = (page) => String(page?.pageId || page?.id || "");
          const suggestionBlockForPage = (pageId) => state.suggestionBlocks.find((block) => String(block?.pageId) === String(pageId));
          const canonicalSuggestionId = (value) => /^suggestion-[A-Za-z0-9][A-Za-z0-9._-]{0,148}$/.test(String(value || "")) ? String(value) : "";
          function selectedSuggestion(block, candidates = []) {
            const stored = selectedSuggestionIds.get(String(block?.pageId));
            const selected = candidates.find((candidate) => String(candidate.suggestionId) === stored) || candidates[0] || null;
            if (selected) selectedSuggestionIds.set(String(block.pageId), String(selected.suggestionId));
            return selected;
          }
          function visibleSuggestionEntries(inboxPages) {
            return inboxPages.map((page) => suggestionBlockForPage(pageIdOf(page))).filter(Boolean).map((block) => {
              const candidates = Array.isArray(block.candidates) ? block.candidates.slice(0, block.ambiguous ? 3 : 1) : [];
              const candidate = selectedSuggestion(block, candidates);
              const suggestionId = canonicalSuggestionId(candidate?.suggestionId);
              return suggestionId ? { pageId: String(block.pageId), suggestionId } : null;
            }).filter(Boolean);
          }
          function pruneBatchSelection(entries) {
            const visible = new Set(entries.map((entry) => entry.suggestionId));
            [...selectedBatchSuggestionIds].forEach((suggestionId) => {
              if (!visible.has(suggestionId)) selectedBatchSuggestionIds.delete(suggestionId);
            });
            if (!batch().mode) selectedBatchSuggestionIds.clear();
          }
          function renderSuggestionBatchEntry(entryCount) {
            const ui = batch();
            if (!ui.mode && entryCount < 2 || typeof callbacks.onResolveSuggestions !== "function") return "";
            const label = tr("suggestion.batch.enter", "\u6279\u91CF\u5904\u7406");
            return `<button type="button" class="tfa-v2-suggestion-batch-entry${ui.mode ? " is-active" : ""}${ui.pending ? " is-loading" : ""}" data-v2-suggestion-batch-entry aria-pressed="${ui.mode}"${ui.mode || ui.pending ? " disabled" : ""} aria-label="${escapeHtml(label)}" title="${escapeHtml(label)}">${escapeHtml(label)}</button>`;
          }
          function renderSuggestionBatchBar(entries) {
            const ui = batch();
            if (!ui.mode) return "";
            const selectedCount = selectedBatchSuggestionIds.size;
            const countLabel = tr("suggestion.batch.count", "\u5DF2\u9009 {count} \u6761", { count: selectedCount });
            const selectAllLabel = tr("suggestion.batch.selectAll", "\u5168\u9009\u5F53\u524D\u5EFA\u8BAE");
            const acceptLabel = tr("suggestion.batch.accept", "\u6279\u91CF\u52A0\u5165\u4EFB\u52A1");
            const rejectLabel = tr("suggestion.batch.reject", "\u6279\u91CF\u62D2\u7EDD");
            const cancelLabel = tr("suggestion.batch.cancel", "\u53D6\u6D88\u6279\u91CF\u5904\u7406");
            const status = ui.pending ? tr("suggestion.batch.running", "\u6B63\u5728\u5904\u7406 {count} \u6761\u5EFA\u8BAE", { count: selectedCount }) : countLabel;
            const limit = ui.limitReached ? `<span class="tfa-v2-suggestion-batch-limit" role="status">${escapeHtml(tr("suggestion.batch.limit", "\u4E00\u6B21\u6700\u591A\u9009\u62E9 {count} \u6761\u5EFA\u8BAE", { count: options.maxBatchSuggestions }))}</span>` : "";
            const allVisibleSelected = entries.length > 0 && entries.every((entry) => selectedBatchSuggestionIds.has(entry.suggestionId));
            return `<div class="tfa-v2-suggestion-batch-bar is-active${ui.pending ? " is-loading" : ""}" data-v2-suggestion-batch-bar aria-busy="${ui.pending}"><span class="tfa-v2-suggestion-batch-count" role="status" aria-live="polite">${escapeHtml(status)}</span>${limit}<button type="button" class="tfa-v2-suggestion-batch-select-all" data-v2-suggestion-batch-select-all${ui.pending || !entries.length || allVisibleSelected ? " disabled" : ""} aria-label="${escapeHtml(selectAllLabel)}" title="${escapeHtml(selectAllLabel)}">${escapeHtml(selectAllLabel)}</button><button type="button" class="tfa-v2-suggestion-batch-accept" data-v2-suggestion-batch-accept${ui.pending || selectedCount === 0 ? " disabled" : ""} aria-label="${escapeHtml(acceptLabel)}" title="${escapeHtml(acceptLabel)}">${escapeHtml(acceptLabel)}</button><button type="button" class="tfa-v2-suggestion-batch-reject" data-v2-suggestion-batch-reject${ui.pending || selectedCount === 0 ? " disabled" : ""} aria-label="${escapeHtml(rejectLabel)}" title="${escapeHtml(rejectLabel)}">${escapeHtml(rejectLabel)}</button><button type="button" class="tfa-v2-suggestion-batch-cancel" data-v2-suggestion-batch-cancel${ui.pending ? " disabled" : ""} aria-label="${escapeHtml(cancelLabel)}" title="${escapeHtml(cancelLabel)}">${escapeHtml(cancelLabel)}</button></div>`;
          }
          function renderSuggestionBlock(block) {
            const ui = batch();
            const multiAssociate = block?.mode === "multi-associate";
            const candidates = Array.isArray(block?.candidates) ? block.candidates.slice(0, block.ambiguous || multiAssociate ? 3 : 1) : [];
            if (!candidates.length) return "";
            const selected = selectedSuggestion(block, candidates);
            const selectedId = String(selected?.suggestionId || "");
            const anyPending = candidates.some((candidate) => state.pendingSuggestionIds.has(String(candidate.suggestionId)));
            const batchSelected = selectedBatchSuggestionIds.has(selectedId);
            const sourceIsAi = selected?.sourceKey === "suggestion.source.ai";
            const confidenceHigh = selected?.confidenceKey === "suggestion.confidence.high";
            const taskTitle = selected?.taskTitle || tr("task.untitled", "\u672A\u547D\u540D\u4EFB\u52A1");
            const summary = block.mode === "primary-choice" ? tr("suggestion.label.choosePrimary", "\u9009\u62E9\u8FD9\u4E2A\u9875\u9762\u7684\u4E3B\u8981\u4EFB\u52A1") : multiAssociate ? tr("suggestion.label.multiAssociate", "\u53EF\u7EE7\u7EED\u540C\u65F6\u5173\u8054\u4EE5\u4E0B\u4EFB\u52A1") : tr("suggestion.label.addToTask", "\u5EFA\u8BAE\u52A0\u5165\u300C{task}\u300D", { task: taskTitle });
            const radioName = `tfa-v2-suggestion-${String(block.pageId).replace(/[^A-Za-z0-9_-]/g, "-")}`;
            const candidateMarkup = candidates.map((candidate) => {
              const id = String(candidate.suggestionId), isSelected = id === selectedId;
              const title = candidate.taskTitle || tr("task.untitled", "\u672A\u547D\u540D\u4EFB\u52A1");
              const choiceLabel = tr("suggestion.aria.chooseTask", "\u9009\u62E9\u4EFB\u52A1\uFF1A{task}", { task: title });
              const choice = block.ambiguous && !multiAssociate ? `<input type="radio" class="tfa-v2-suggestion-choice" name="${escapeHtml(radioName)}" value="${escapeHtml(id)}" data-v2-suggestion-choice="${escapeHtml(id)}" data-v2-suggestion-id="${escapeHtml(id)}" data-v2-suggestion-page="${escapeHtml(block.pageId)}"${isSelected ? " checked" : ""}${anyPending || ui.pending ? " disabled" : ""} aria-label="${escapeHtml(choiceLabel)}" title="${escapeHtml(choiceLabel)}">` : '<span class="tfa-v2-suggestion-choice" aria-hidden="true"></span>';
              const reasons = (Array.isArray(candidate.reasonKeys) ? candidate.reasonKeys : []).slice(0, 2).map((key) => `<li>${escapeHtml(tr(key, key))}</li>`).join("");
              const inlineActions = multiAssociate ? `<span class="tfa-v2-suggestion-actions is-inline"><button type="button" class="tfa-v2-suggestion-accept" data-v2-suggestion-decision="accept" data-v2-suggestion-page="${escapeHtml(block.pageId)}" data-v2-suggestion-id="${escapeHtml(id)}"${anyPending ? " disabled" : ""}>${escapeHtml(tr("suggestion.action.alsoLink", "\u540C\u65F6\u5173\u8054"))}</button><button type="button" class="tfa-v2-suggestion-reject" data-v2-suggestion-decision="reject" data-v2-suggestion-page="${escapeHtml(block.pageId)}" data-v2-suggestion-id="${escapeHtml(id)}"${anyPending ? " disabled" : ""}>${escapeHtml(tr("suggestion.action.reject", "\u62D2\u7EDD"))}</button></span>` : "";
              const tag = multiAssociate ? "div" : "label";
              return `<${tag} class="tfa-v2-suggestion-candidate${isSelected && !multiAssociate ? " is-selected" : ""}" data-v2-suggestion-candidate="${escapeHtml(id)}">${choice}<span class="tfa-v2-suggestion-copy"><strong title="${escapeHtml(title)}">${escapeHtml(title)}</strong><small>${escapeHtml(domainLabel(candidate.taskDomain || "other"))}</small></span><ul class="tfa-v2-suggestion-reasons" aria-label="${escapeHtml(tr("suggestion.why", "\u4E3A\u4EC0\u4E48\u8FD9\u6837\u5206"))}">${reasons}</ul>${inlineActions}</${tag}>`;
            }).join("");
            const addLabel = tr("suggestion.action.addToTask", "\u52A0\u5165\u4EFB\u52A1");
            const rejectLabel = tr("suggestion.action.reject", "\u62D2\u7EDD");
            const batchSelectLabel = tr("suggestion.batch.select", "\u9009\u62E9\u6B64\u5EFA\u8BAE");
            const batchSelect = ui.mode && !multiAssociate ? `<input type="checkbox" class="tfa-v2-suggestion-batch-select" data-v2-suggestion-batch-select data-v2-suggestion-id="${escapeHtml(selectedId)}" data-v2-suggestion-page="${escapeHtml(block.pageId)}"${batchSelected ? " checked" : ""}${ui.pending || anyPending ? " disabled" : ""} aria-label="${escapeHtml(batchSelectLabel)}" title="${escapeHtml(batchSelectLabel)}">` : "";
            const decisions = multiAssociate ? "" : `<div class="tfa-v2-suggestion-actions"><button type="button" class="tfa-v2-suggestion-accept" data-v2-suggestion-decision="accept" data-v2-suggestion-page="${escapeHtml(block.pageId)}" data-v2-suggestion-id="${escapeHtml(selectedId)}"${anyPending ? " disabled" : ""} aria-label="${escapeHtml(addLabel)}" title="${escapeHtml(addLabel)}">${escapeHtml(addLabel)}</button><button type="button" class="tfa-v2-suggestion-reject" data-v2-suggestion-decision="reject" data-v2-suggestion-page="${escapeHtml(block.pageId)}" data-v2-suggestion-id="${escapeHtml(selectedId)}"${anyPending ? " disabled" : ""} aria-label="${escapeHtml(rejectLabel)}" title="${escapeHtml(rejectLabel)}">${escapeHtml(rejectLabel)}</button></div>`;
            return `<section class="tfa-v2-suggestion${block.ambiguous ? " is-ambiguous" : ""}${multiAssociate ? " is-multi-associate" : ""}${confidenceHigh ? " is-high" : ""}${anyPending ? " is-loading" : ""}${batchSelected ? " is-batch-selected" : ""}" data-v2-suggestion="${escapeHtml(block.pageId)}" aria-busy="${anyPending}"><header class="tfa-v2-suggestion-head">${batchSelect}<span class="tfa-v2-suggestion-source is-${sourceIsAi ? "ai" : "local"}">${escapeHtml(tr(selected.sourceKey, sourceIsAi ? "AI \u5EFA\u8BAE" : "\u672C\u5730\u5EFA\u8BAE"))}</span><span class="tfa-v2-suggestion-confidence${confidenceHigh ? " is-high" : ""}">${escapeHtml(tr(selected.confidenceKey, confidenceHigh ? "\u628A\u63E1\u8F83\u9AD8" : "\u628A\u63E1\u4E2D\u7B49"))}</span><strong class="tfa-v2-suggestion-why" title="${escapeHtml(summary)}">${escapeHtml(summary)}</strong></header><div class="tfa-v2-suggestion-candidates">${candidateMarkup}</div>${decisions}</section>`;
          }
          function renderSuggestionNotice(pageId) {
            const notice = state.suggestionNotices.find((item) => String(item?.pageId) === String(pageId) && item?.decision === "reject");
            if (!notice?.suggestionId) return "";
            const suggestionId = String(notice.suggestionId), pending = state.pendingSuggestionIds.has(suggestionId);
            const undoLabel = tr("suggestion.action.undo", "\u64A4\u9500");
            return `<div class="tfa-v2-suggestion-notice is-success" data-v2-suggestion-notice="${escapeHtml(pageId)}" role="status"><span>${escapeHtml(tr("suggestion.notice.rejected", "\u5DF2\u62D2\u7EDD\u5EFA\u8BAE"))}</span><span aria-hidden="true"> \xB7 </span><button type="button" class="tfa-v2-suggestion-notice-action" data-v2-undo-suggestion="${escapeHtml(suggestionId)}" data-v2-suggestion-id="${escapeHtml(suggestionId)}" data-v2-suggestion-page="${escapeHtml(pageId)}"${pending ? " disabled" : ""} aria-label="${escapeHtml(undoLabel)}" title="${escapeHtml(undoLabel)}">${escapeHtml(undoLabel)}</button></div>`;
          }
          function renderInboxItem(page) {
            const pageId = pageIdOf(page), block = suggestionBlockForPage(pageId);
            return `<div class="tfa-v2-inbox-item" data-v2-inbox-item="${escapeHtml(pageId)}">${renderTab(page, "inbox")}${block ? renderSuggestionBlock(block) : ""}${renderSuggestionNotice(pageId)}</div>`;
          }
          function renderTasks(model) {
            root.querySelector("[data-v2-task-count]").textContent = String(model.visibleTaskCount);
            statusSelect.innerHTML = [`<option value="all">${escapeHtml(tr("workbench.allStatuses", "\u5168\u90E8\u72B6\u6001"))}</option>`, ...logic.TASK_STATUSES.map((status) => `<option value="${status}">${escapeHtml(statusLabel(status))}</option>`)].join("");
            domainSelect.innerHTML = [`<option value="all">${escapeHtml(tr("workbench.allDomains", "\u5168\u90E8\u9886\u57DF"))}</option>`, ...model.domains.map((domain) => `<option value="${escapeHtml(domain)}">${escapeHtml(domainLabel(domain))}</option>`)].join("");
            taskSortSelect.innerHTML = logic.TASK_SORT_MODES.map((mode) => `<option value="${mode}">${escapeHtml(tr(`workbench.taskSort.${mode}`, { manual: "\u624B\u52A8\u6392\u5E8F", recent: "\u6700\u8FD1\u66F4\u65B0", title: "\u540D\u79F0\u6392\u5E8F" }[mode]))}</option>`).join("");
            statusSelect.value = model.filters.statusFilter;
            domainSelect.value = state.domainFilter;
            taskSortSelect.value = model.filters.taskSort;
            root.querySelectorAll("[data-v2-task-view]").forEach((button) => {
              const active = button.dataset.v2TaskView === state.taskView;
              button.classList.toggle("is-active", active);
              button.setAttribute("aria-pressed", String(active));
            });
            if (state.taskView !== "cards" && experimentalViews) {
              taskContent.innerHTML = experimentalViews.render(state.taskView, model.tasks);
              return;
            }
            const taskList = model.tasks.length ? model.tasks.map(renderTask).join("") : renderEmpty("workbench.noTasks", "\u6CA1\u6709\u5339\u914D\u7684\u4EFB\u52A1", "workbench.noTasksHint", "\u8C03\u6574\u641C\u7D22\u3001\u9886\u57DF\u6216\u72B6\u6001\u7B5B\u9009");
            const inboxPages = model.inboxPages || [];
            const batchEntries = visibleSuggestionEntries(inboxPages);
            pruneBatchSelection(batchEntries);
            if (!batchEntries.length && !batch().pending) options.clearBatchWhenEmpty();
            const expanded = state.inboxExpanded;
            const toggleLabel = expanded ? tr("workbench.inboxCollapse", "\u6536\u8D77\u4E3A\u4E00\u884C") : tr("workbench.inboxExpand", "\u5C55\u5F00\u5168\u90E8\u9875\u7B7E");
            const loading = state.suggestionLoading ? `<span class="tfa-v2-suggestion-loading" role="status">${escapeHtml(tr("suggestion.state.loading", "\u6B63\u5728\u5206\u6790"))}</span>` : "";
            const batchEntry = renderSuggestionBatchEntry(batchEntries.length);
            const inbox = `<section class="tfa-v2-inbox${expanded ? " is-expanded" : ""}" data-v2-inbox aria-labelledby="tfa-v2-inbox-title"><header class="tfa-v2-inbox-header"><span class="tfa-v2-inbox-marker" aria-hidden="true"></span><strong id="tfa-v2-inbox-title" tabindex="-1">${escapeHtml(tr("workbench.inboxTitle", "\u5F85\u5212\u5206\u7684\u9875\u7B7E"))}</strong><small>${escapeHtml(tr("workbench.inboxCandidates", "{count} \u4E2A\u5019\u9009", { count: model.visibleInboxCount }))}</small>${loading}${batchEntry}</header>${inboxPages.length ? `<div class="tfa-v2-inbox-pages" id="tfa-v2-inbox-pages"><div class="tfa-v2-tab-grid">${inboxPages.map(renderInboxItem).join("")}</div></div>` : ""}${inboxPages.length > 1 ? `<footer class="tfa-v2-inbox-footer"><button type="button" data-v2-inbox-toggle aria-expanded="${expanded}" aria-controls="tfa-v2-inbox-pages" aria-label="${escapeHtml(toggleLabel)}" title="${escapeHtml(toggleLabel)}">${template.icon(expanded ? "chevron-up" : "chevron-down")}</button></footer>` : ""}</section>`;
            taskContent.innerHTML = `<div class="tfa-v2-task-content-inner"><div class="tfa-v2-task-list">${taskList}</div>${inbox}${renderSuggestionBatchBar(batchEntries)}</div>`;
          }
          function renderRecyclePage(page) {
            const title = page.title || logic.hostOf(page.url) || tr("workbench.unknownPage", "\u672A\u77E5\u9875\u9762");
            const meta = logic.hostOf(page.url) || page.meta || page.url || "";
            return `<div class="tfa-v2-recycle-page">${renderIcon(page)}<span class="tfa-v2-recycle-page-copy"><strong>${escapeHtml(title)}</strong><small>${escapeHtml(meta)}</small></span></div>`;
          }
          function renderRecycle(model) {
            recycleCount.textContent = String(model.trashCount);
            restoreAllButton.disabled = model.trashCount === 0;
            recycleContent.innerHTML = model.trashItems.length ? `<div class="tfa-v2-recycle-list">${model.trashItems.map((item) => {
              const isGroup = item.type !== "tab";
              const color = safeColor(item.color, fallbackColor(item.id || item.title));
              const title = item.title || (isGroup ? tr("task.untitled", "\u672A\u547D\u540D\u4EFB\u52A1") : tr("workbench.unknownPage", "\u672A\u77E5\u9875\u9762"));
              const time = formatRecycleTime(item.closedAt || item.label, Date.now(), {
                recently: tr("recycle.recently", "\u521A\u521A"),
                minutesAgo: (count) => tr("recycle.minutesAgo", "{count} \u5206\u949F\u524D", { count }),
                today: tr("recycle.today", "\u4ECA\u5929")
              });
              const kind = item.type === "group" ? tr("recycle.group", "\u9875\u7B7E\u7EC4") : tr("recycle.task", "\u4EFB\u52A1\u7EC4");
              const pageSummary = item.pages.slice(0, 4).map(renderRecyclePage).join("");
              const moreCount = Math.max(0, item.pages.length - 4);
              const main = isGroup ? `<section class="tfa-v2-recycle-task"><header class="tfa-v2-recycle-task-header"><span class="tfa-v2-recycle-task-copy"><span class="tfa-v2-recycle-task-title"><strong>${escapeHtml(title)}</strong><span class="tfa-v2-recycle-tag">${escapeHtml(kind)}</span><span class="tfa-v2-recycle-tag is-domain">${escapeHtml(domainLabel(item.domainId))}</span><span class="tfa-v2-recycle-tag">${escapeHtml(statusLabel(item.status))}</span></span><small>${escapeHtml(tr("workbench.taskPages", "{count} \u4E2A\u76F8\u5173\u9875\u9762", { count: item.pages.length }))}</small></span></header>${item.pages.length ? `<div class="tfa-v2-recycle-pages">${pageSummary}${moreCount ? `<span class="tfa-v2-recycle-more">+${moreCount}</span>` : ""}</div>` : ""}</section>` : `<div class="tfa-v2-recycle-tab">${renderIcon(item.record)}<span class="tfa-v2-recycle-copy"><strong>${escapeHtml(title)}</strong><span>${escapeHtml(item.meta || tr("recycle.closedTab", "\u5DF2\u5173\u95ED\u9875\u7B7E"))}</span></span></div>`;
              return `<article class="tfa-v2-recycle-card ${isGroup ? "is-group" : "is-page"}" data-v2-trash-item="${escapeHtml(item.id)}" style="--trash-color:${color}"><span class="tfa-v2-recycle-time" title="${escapeHtml(time.absolute)}" aria-label="${escapeHtml(time.absolute)}"><strong>${escapeHtml(time.display)}</strong></span><div class="tfa-v2-recycle-main">${main}</div><span class="tfa-v2-recycle-actions"><button type="button" class="tfa-v2-recycle-action is-restore" data-v2-restore-trash="${escapeHtml(item.id)}">${template.icon("restore")}${escapeHtml(tr("recycle.restore", "\u6062\u590D"))}</button><button type="button" class="tfa-v2-recycle-action is-delete" data-v2-delete-trash="${escapeHtml(item.id)}" aria-label="${escapeHtml(tr("recycle.deletePermanently", "\u6C38\u4E45\u5220\u9664"))}" title="${escapeHtml(tr("recycle.deletePermanently", "\u6C38\u4E45\u5220\u9664"))}">${template.icon("trash")}${escapeHtml(tr("recycle.delete", "\u5220\u9664"))}</button></span></article>`;
            }).join("")}</div>` : renderEmpty("recycle.empty", "\u56DE\u6536\u7AD9\u4E3A\u7A7A", "recycle.emptyHint", "\u5173\u95ED\u7684\u9875\u7B7E\u3001\u9875\u7B7E\u7EC4\u4E0E\u4EFB\u52A1\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC");
          }
          return Object.freeze({
            renderBrowser,
            renderTasks,
            renderRecycle,
            replacementTasksForPage,
            suggestionBlockForPage,
            canonicalSuggestionId,
            selectedSuggestion,
            visibleSuggestionEntries,
            setAiAdjustment(value) {
              return value ? adjustmentView?.setSummary(value) : adjustmentView?.clear();
            },
            destroy() {
              root.removeEventListener?.("dragstart", hidePreviewDuringDrag);
              adjustmentView?.destroy();
              nativeGroupView?.destroy();
              tabAwarenessView?.destroy();
              browserTabSort?.destroy();
            }
          });
        }
        return Object.freeze({
          AI_ADJUSTMENT_CSS: adjustmentModule?.AI_ADJUSTMENT_CSS || "",
          EXPERIMENTAL_TASK_VIEWS_CSS: experimentalViewsModule?.CSS || "",
          NATIVE_TAB_GROUP_CSS: nativeGroupViewModule?.CSS || "",
          TAB_AWARENESS_CSS: tabAwarenessViewModule?.CSS || "",
          formatRecycleTime,
          createV2WorkbenchRenderer
        });
      });
    }
  });

  // src/content/v2-workbench-view.js
  var require_v2_workbench_view = __commonJS({
    "src/content/v2-workbench-view.js"(exports, module) {
      (function attachV2WorkbenchView(rootScope, factory) {
        const focusRuntimeModule = typeof module === "object" && module.exports ? require_v2_workbench_focus_runtime() : rootScope.TfaV2WorkbenchFocusRuntime;
        const rendererModule = typeof module === "object" && module.exports ? require_v2_workbench_renderer() : rootScope.TfaV2WorkbenchRenderer;
        const relationMenuModule = typeof module === "object" && module.exports ? require_v2_task_relation_menu() : rootScope.TfaV2TaskRelationMenu;
        const overflowControlsModule = typeof module === "object" && module.exports ? require_v2_overflow_controls() : rootScope.TfaV2OverflowControls;
        const api = factory(rootScope, focusRuntimeModule, rendererModule, relationMenuModule, overflowControlsModule);
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchView = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchView(rootScope, focusRuntimeModule, rendererModule, relationMenuModule, overflowControlsModule) {
        "use strict";
        const DOMAIN_FALLBACKS = { work: "\u5DE5\u4F5C", study: "\u5B66\u4E60", life: "\u751F\u6D3B", interest: "\u5174\u8DA3", admin: "\u4E8B\u52A1", other: "\u5176\u4ED6" };
        const normalizeBrowserColumns = (value) => [4, 5, 6].includes(Number(value)) ? Number(value) : 4;
        function taskDropTargetFromEvent(event) {
          const direct = event?.target?.closest?.("[data-v2-task]");
          if (direct) return direct;
          const path = typeof event?.composedPath === "function" ? event.composedPath() : [];
          return path.find((element) => element?.matches?.("[data-v2-task]")) || null;
        }
        function mountV2Workbench(options = {}) {
          const root = options.root;
          if (!root || typeof root.querySelector !== "function") throw new TypeError("mountV2Workbench requires a DOM root");
          const logic = options.logic || rootScope.TfaV2WorkbenchLogic;
          const template = options.template || rootScope.TfaV2WorkbenchTemplate;
          const resizerModule = options.resizer || rootScope.TfaV2WorkbenchResizer;
          const menuModule = options.menu || rootScope.TfaV2WorkbenchMenu;
          const focusModule = options.focusRuntime || focusRuntimeModule;
          const rendererFactoryModule = options.renderer || rendererModule;
          if (!logic || !template || !resizerModule || !menuModule || !focusModule?.createV2WorkbenchFocusRuntime || !rendererFactoryModule?.createV2WorkbenchRenderer) {
            throw new Error("V2 workbench dependencies must be loaded before the view");
          }
          const surfaceRoot = root.getRootNode?.() || null;
          const legacyColumnInput = () => surfaceRoot?.getElementById?.("columnRange") || null;
          const legacyPanel = () => surfaceRoot?.getElementById?.("panel") || null;
          const callbacks = {
            onActivateTab: options.onActivateTab,
            onCloseTab: options.onCloseTab,
            onClose: options.onClose,
            onTheme: options.onTheme,
            onSettings: options.onSettings,
            onCreateTask: options.onCreateTask,
            onRenameTask: options.onRenameTask,
            onUndoTaskChange: options.onUndoTaskChange,
            onRemoveTabFromTask: options.onRemoveTabFromTask,
            onOpenTaskTabs: options.onOpenTaskTabs,
            onCloseTaskTabs: options.onCloseTaskTabs,
            onAssignTabToTask: options.onAssignTabToTask,
            onChangeTabTaskRelation: options.onChangeTabTaskRelation,
            onSetInboxPreference: options.onSetInboxPreference,
            onToggleDockSite: options.onToggleDockSite,
            onSetTaskDomain: options.onSetTaskDomain,
            onSetTaskStatus: options.onSetTaskStatus,
            onDissolveTask: options.onDissolveTask,
            onRestoreTrashItem: options.onRestoreTrashItem,
            onDeleteTrashItem: options.onDeleteTrashItem,
            onRestoreAllTrash: options.onRestoreAllTrash,
            onLayoutChange: options.onLayoutChange,
            onSplitRatioChange: options.onSplitRatioChange,
            onFilterChange: options.onFilterChange,
            onBrowserColumnsChange: options.onBrowserColumnsChange,
            onReorderTasks: options.onReorderTasks,
            onReorderTaskPages: options.onReorderTaskPages,
            onResolveSuggestion: options.onResolveSuggestion,
            onResolveSuggestions: options.onResolveSuggestions,
            onUndoSuggestion: options.onUndoSuggestion,
            onUndoAiPlan: options.onUndoAiPlan,
            onNativeGroupIntent: options.onNativeGroupIntent,
            onNativeWindowIntent: options.onNativeWindowIntent,
            onEditNativeGroup: options.onEditNativeGroup,
            onReorderBrowserTab: options.onReorderBrowserTab
          };
          const state = {
            tabs: Array.isArray(options.tabs) ? options.tabs : [],
            tasks: Array.isArray(options.tasks) ? options.tasks : [],
            inboxPages: Array.isArray(options.inboxPages) ? options.inboxPages : [],
            suggestionBlocks: Array.isArray(options.suggestionBlocks) ? options.suggestionBlocks : [],
            suggestionNotices: Array.isArray(options.suggestionNotices) ? options.suggestionNotices : [],
            suggestionLoading: options.suggestionLoading === true || options.suggestionsLoading === true,
            pendingSuggestionIds: new Set(options.pendingSuggestionIds || []),
            canUndo: options.canUndo === true,
            trashItems: Array.isArray(options.trashItems) ? options.trashItems : [],
            layout: logic.normalizeLayout(options.layout),
            theme: options.theme === "dark" ? "dark" : "light",
            query: String(options.query || ""),
            windowFilter: String(options.windowFilter || "all"),
            domainFilter: String(options.domainFilter || "all"),
            statusFilter: String(options.statusFilter || "all"),
            taskSort: logic.normalizeTaskSort(options.taskSort),
            taskView: options.taskView === "aggregate" || options.taskView === "fishbone" ? options.taskView : "cards",
            browserColumns: normalizeBrowserColumns(options.browserColumns ?? legacyPanel()?.dataset?.columns ?? legacyColumnInput()?.value),
            inboxExpanded: options.inboxExpanded === true,
            expandedTaskIds: new Set(options.expandedTaskIds || [])
          };
          const translate = typeof options.t === "function" ? options.t : () => "";
          let draggedTab = null, draggedTask = null, draggedElement = null;
          let suggestionBatchMode = false, suggestionBatchPending = false, suggestionBatchLimitReached = false, undoPending = false;
          const pendingPageOrderTasks = /* @__PURE__ */ new Set(), selectedSuggestionIds = /* @__PURE__ */ new Map(), selectedBatchSuggestionIds = /* @__PURE__ */ new Set();
          const MAX_BATCH_SUGGESTIONS = 50;
          function tr(key, fallback, params = {}) {
            const translated = translate(key, params);
            const base = translated && translated !== key ? translated : fallback;
            return String(base).replace(/\{(\w+)\}/g, (_match, name) => String(params[name] == null ? "" : params[name]));
          }
          const escapeHtml = template.escapeHtml;
          root.innerHTML = template.buildWorkbenchShell({ t: translate, theme: state.theme, canUndo: state.canUndo, extraCss: `${rendererFactoryModule.AI_ADJUSTMENT_CSS || ""}${rendererFactoryModule.EXPERIMENTAL_TASK_VIEWS_CSS || ""}${rendererFactoryModule.NATIVE_TAB_GROUP_CSS || ""}${rendererFactoryModule.TAB_AWARENESS_CSS || ""}${relationMenuModule?.CSS || ""}` });
          const shell = root.querySelector(".tfa-v2-workbench"), workspace = root.querySelector("[data-v2-workspace]"), queryInput = root.querySelector("[data-v2-query]");
          const browserContent = root.querySelector("[data-v2-browser-content]"), taskContent = root.querySelector("[data-v2-task-content]"), divider = root.querySelector("[data-v2-divider]"), windowOptionsRoot = root.querySelector("[data-v2-window-options]");
          const statusSelect = root.querySelector("[data-v2-status-filter]"), domainSelect = root.querySelector("[data-v2-domain-filter]"), taskSortSelect = root.querySelector("[data-v2-task-sort]");
          const recycleContent = root.querySelector("[data-v2-recycle-content]");
          const recycleCount = root.querySelector("[data-v2-recycle-count]"), restoreAllButton = root.querySelector("[data-v2-restore-all]");
          const tabMenu = root.querySelector("[data-v2-tab-menu]"), dockSiteButton = root.querySelector("[data-v2-toggle-dock-site]");
          const ownerDocument = root.ownerDocument || root.host && root.host.ownerDocument || null;
          const EventConstructor = options.window?.Event || ownerDocument?.defaultView?.Event || rootScope.Event;
          function applyBrowserColumns(value, persist = false) {
            state.browserColumns = normalizeBrowserColumns(value);
            shell.style?.setProperty?.("--v2-browser-columns", String(state.browserColumns));
            shell.dataset.browserColumns = String(state.browserColumns);
            const control = root.querySelector?.("[data-v2-browser-columns]");
            if (control) control.value = String(state.browserColumns);
            const output = root.querySelector?.("[data-v2-browser-columns-value]");
            if (output) output.textContent = tr("workbench.columnsValue", "{count} \u5217", { count: state.browserColumns });
            if (!persist) return state.browserColumns;
            const legacy = legacyColumnInput();
            if (legacy && typeof EventConstructor === "function") {
              legacy.value = String(state.browserColumns);
              legacy.dispatchEvent(new EventConstructor("input", { bubbles: true }));
            } else callbacks.onBrowserColumnsChange?.(state.browserColumns);
            return state.browserColumns;
          }
          const MutationObserverConstructor = options.window?.MutationObserver || ownerDocument?.defaultView?.MutationObserver;
          const columnPreferenceObserver = typeof MutationObserverConstructor === "function" && legacyPanel() ? new MutationObserverConstructor(() => applyBrowserColumns(legacyPanel()?.dataset?.columns)) : null;
          columnPreferenceObserver?.observe?.(legacyPanel(), { attributes: true, attributeFilter: ["data-columns"] });
          const overflowControls = overflowControlsModule?.createOverflowControls({ root, window: options.window, observe: [browserContent, taskContent] });
          const menuController = menuModule.createWorkbenchMenuController({ root, ownerDocument });
          const relationMenu = relationMenuModule.createTaskRelationMenu({ menu: tabMenu, tr, escapeHtml });
          const resizer = resizerModule.mountWorkbenchResizer({
            workspace,
            divider,
            logic,
            window: options.window,
            browserPane: root.querySelector(".tfa-v2-browser-pane"),
            taskPane: root.querySelector(".tfa-v2-task-pane"),
            recyclePane: root.querySelector(".tfa-v2-recycle-pane"),
            layout: state.layout,
            ratio: options.splitRatio,
            onRatioChange: callbacks.onSplitRatioChange,
            onLayoutRequest: (layout) => changeLayout(layout)
          });
          const focusRuntime = focusModule.createV2WorkbenchFocusRuntime({
            root,
            queryInput,
            getPendingSuggestionIds: () => state.pendingSuggestionIds,
            isBatchPending: () => suggestionBatchPending
          });
          const scrollActivity = focusModule.createV2WorkbenchScrollActivity?.({ root, window: options.window });
          const rememberFocus = (...elements) => focusRuntime.remember(...elements), rememberAdjacentTab = (button) => focusRuntime.rememberAdjacentTab(button);
          const rememberAdjacentTask = (button) => focusRuntime.rememberAdjacentTask(button), rememberAdjacentTrash = (button) => focusRuntime.rememberAdjacentTrash(button);
          const findTaskPage = (task, id) => (task?.pages || task?.tabs || []).find((page) => String(page.id) === String(id));
          const manualTaskOrder = () => logic.sortTasks(state.tasks, "manual").map((task) => String(task.id));
          const canManuallyReorderTasks = () => state.taskSort === "manual" && !state.query.trim() && state.domainFilter === "all" && state.statusFilter === "all";
          function focusSearch() {
            if (state.layout === "recycle") return false;
            queryInput.focus();
            queryInput.select();
            return true;
          }
          function changeLayout(layout) {
            state.layout = logic.normalizeLayout(layout);
            render();
            callbacks.onLayoutChange?.(state.layout);
          }
          function requestTaskMove(id, offset) {
            const ids = manualTaskOrder(), from = ids.indexOf(String(id)), to = from + offset;
            if (!canManuallyReorderTasks() || from < 0 || to < 0 || to >= ids.length || typeof callbacks.onReorderTasks !== "function") return;
            [ids[from], ids[to]] = [ids[to], ids[from]];
            callbacks.onReorderTasks(ids);
          }
          const renderer = rendererFactoryModule.createV2WorkbenchRenderer({
            root,
            logic,
            template,
            state,
            callbacks,
            tr,
            escapeHtml,
            browserContent,
            taskContent,
            windowOptionsRoot,
            statusSelect,
            domainSelect,
            taskSortSelect,
            recycleContent,
            recycleCount,
            restoreAllButton,
            selectedSuggestionIds,
            selectedBatchSuggestionIds,
            manualTaskOrder,
            canManuallyReorderTasks,
            maxBatchSuggestions: MAX_BATCH_SUGGESTIONS,
            getBatchState: () => ({ mode: suggestionBatchMode, pending: suggestionBatchPending, limitReached: suggestionBatchLimitReached }),
            clearBatchWhenEmpty() {
              suggestionBatchMode = false;
              selectedBatchSuggestionIds.clear();
            },
            locale: options.locale,
            aiAdjustment: options.aiAdjustment,
            onUndoAiPlan: callbacks.onUndoAiPlan,
            onRequestTabPreview: options.onRequestTabPreview
          });
          const replacementTasksForPage = (page, task) => renderer.replacementTasksForPage(page, task);
          const suggestionBlockForPage = (pageId) => renderer.suggestionBlockForPage(pageId);
          const canonicalSuggestionId = (value) => renderer.canonicalSuggestionId(value);
          const selectedSuggestion = (block, candidates) => renderer.selectedSuggestion(block, candidates);
          const visibleSuggestionEntries = (pages) => renderer.visibleSuggestionEntries(pages);
          const renderBrowser = (model) => renderer.renderBrowser(model);
          const renderTasks = (model) => renderer.renderTasks(model);
          const renderRecycle = (model) => renderer.renderRecycle(model);
          const currentModel = () => logic.buildWorkbenchModel(state);
          function render() {
            menuController.close();
            const model = currentModel();
            shell.dataset.theme = state.theme;
            shell.dataset.layout = model.layout;
            workspace.dataset.layout = model.layout;
            root.querySelector('[data-v2-action="undo-task-change"]').disabled = !state.canUndo || undoPending;
            resizer.update({ layout: model.layout });
            queryInput.value = state.query;
            root.querySelector("[data-v2-global-count]").textContent = tr("workbench.globalCount", "{tabs} \u4E2A\u9875\u7B7E \xB7 {tasks} \u4E2A\u4EFB\u52A1", { tabs: model.tabCount, tasks: model.taskCount });
            root.querySelectorAll("[data-v2-layout]").forEach((button) => button.classList.toggle("is-active", button.dataset.v2Layout === model.layout));
            renderBrowser(model);
            renderTasks(model);
            root.querySelectorAll("[data-v2-tab]").forEach((card) => card.setAttribute("draggable", "true"));
            root.querySelectorAll(".tfa-v2-tab-main").forEach((button) => button.setAttribute("draggable", "true"));
            if (model.layout === "recycle") renderRecycle(model);
            else recycleContent.innerHTML = "";
            focusRuntime.restore();
            overflowControls?.schedule();
          }
          function notifyFilterChange() {
            if (typeof callbacks.onFilterChange === "function") callbacks.onFilterChange({
              query: state.query,
              windowFilter: state.windowFilter,
              domainFilter: state.domainFilter,
              statusFilter: state.statusFilter,
              taskSort: state.taskSort
            });
          }
          function findTab(id) {
            return state.tabs.find((tab) => String(tab.id) === String(id)) || state.inboxPages.find((tab) => String(tab.id) === String(id)) || state.tasks.flatMap((task) => task.tabs || task.pages || []).find((tab) => String(tab.id) === String(id));
          }
          const findTask = (id) => state.tasks.find((task) => String(task.id) === String(id));
          const findTrashItem = (id) => currentModel().trashItems.find((item) => item.id === String(id));
          const activate = (id) => {
            const tab = findTab(id);
            if (tab && typeof callbacks.onActivateTab === "function") callbacks.onActivateTab(tab);
          };
          const orderChanged = (left, right) => Array.isArray(right) && right.some((id, index) => id !== left[index]);
          function submitPageOrder(task, ids) {
            const taskId = String(task?.id || "");
            if (!taskId || pendingPageOrderTasks.has(taskId) || typeof callbacks.onReorderTaskPages !== "function") return false;
            pendingPageOrderTasks.add(taskId);
            Promise.resolve().then(() => callbacks.onReorderTaskPages(task, ids)).then((ok) => {
              if (ok === false) render();
            }, () => render()).finally(() => pendingPageOrderTasks.delete(taskId));
            return true;
          }
          function openTabActionMenu(trigger, tab) {
            const owner = trigger.closest("[data-v2-tab]");
            const task = owner?.dataset.v2Context === "task" ? findTask(owner.dataset.v2TaskId) : null, inbox = owner?.dataset.v2Context === "inbox";
            relationMenu.prepare(tab, state.tasks, task);
            tabMenu.querySelectorAll("[data-v2-inbox-action]").forEach((button) => {
              button.hidden = !inbox;
              button.dataset.v2InboxPage = tab.pageId || tab.id;
              button.dataset.v2InboxUrl = tab.url || "";
            });
            dockSiteButton.dataset.v2ToggleDockSite = String(tab.id);
            dockSiteButton.textContent = tab.dockFixed ? tr("tab.removeFromDock", "\u4ECE\u7F51\u9875\u62D3\u5C55\u575E\u53D6\u6D88\u56FA\u5B9A") : tr("tab.addToDock", "\u56FA\u5B9A\u5230\u7F51\u9875\u62D3\u5C55\u575E");
            if (!menuController.toggle(trigger, tabMenu, owner, dockSiteButton)) return;
            menuController.position(trigger, tabMenu, shell);
          }
          function currentVisibleSuggestionEntries() {
            return visibleSuggestionEntries(currentModel().inboxPages || []);
          }
          function selectedBatchItems() {
            const seen = /* @__PURE__ */ new Set();
            return currentVisibleSuggestionEntries().reduce((result, entry) => {
              if (result.length >= MAX_BATCH_SUGGESTIONS || !selectedBatchSuggestionIds.has(entry.suggestionId) || state.pendingSuggestionIds.has(entry.suggestionId) || seen.has(entry.suggestionId)) return result;
              seen.add(entry.suggestionId);
              result.push(entry.suggestionId);
              return result;
            }, []);
          }
          function completeSuggestionBatch(items, summary) {
            const results = summary && Array.isArray(summary.results) ? summary.results : [];
            const resultById = new Map(results.map((result) => [canonicalSuggestionId(result?.suggestionId), result]));
            const failed = items.filter((suggestionId) => resultById.get(suggestionId)?.ok !== true);
            suggestionBatchPending = false;
            selectedBatchSuggestionIds.clear();
            failed.forEach((suggestionId) => selectedBatchSuggestionIds.add(suggestionId));
            suggestionBatchLimitReached = false;
            if (failed.length) focusRuntime.setBatchFocus({ type: "failure", suggestionId: failed[0] });
            else {
              suggestionBatchMode = false;
              focusRuntime.setBatchFocus({ type: "entry" });
            }
            render();
          }
          function submitSuggestionBatch(decision) {
            if (suggestionBatchPending || !["accept", "reject"].includes(decision) || typeof callbacks.onResolveSuggestions !== "function") return;
            const items = selectedBatchItems();
            if (!items.length) return;
            suggestionBatchPending = true;
            suggestionBatchLimitReached = false;
            render();
            Promise.resolve().then(() => callbacks.onResolveSuggestions(items, decision)).then(
              (summary) => completeSuggestionBatch(items, summary),
              () => completeSuggestionBatch(items, false)
            );
          }
          function onClick(event) {
            const taskViewButton = event.target.closest("[data-v2-task-view]");
            if (taskViewButton) {
              state.taskView = ["aggregate", "fishbone"].includes(taskViewButton.dataset.v2TaskView) ? taskViewButton.dataset.v2TaskView : "cards";
              render();
              return;
            }
            const layoutButton = event.target.closest("[data-v2-layout]");
            if (layoutButton) {
              changeLayout(layoutButton.dataset.v2Layout);
              return;
            }
            const restoreTrashButton = event.target.closest("[data-v2-restore-trash]");
            if (restoreTrashButton) {
              const item = findTrashItem(restoreTrashButton.dataset.v2RestoreTrash);
              rememberAdjacentTrash(restoreTrashButton);
              if (item && typeof callbacks.onRestoreTrashItem === "function") callbacks.onRestoreTrashItem(item.source);
              return;
            }
            const deleteTrashButton = event.target.closest("[data-v2-delete-trash]");
            if (deleteTrashButton) {
              const item = findTrashItem(deleteTrashButton.dataset.v2DeleteTrash);
              rememberAdjacentTrash(deleteTrashButton);
              if (item && typeof callbacks.onDeleteTrashItem === "function") callbacks.onDeleteTrashItem(item.source);
              return;
            }
            if (event.target.closest("[data-v2-restore-all]")) {
              rememberFocus(root.querySelector('[data-v2-layout="recycle"]'));
              if (state.trashItems.length && typeof callbacks.onRestoreAllTrash === "function") callbacks.onRestoreAllTrash([...state.trashItems]);
              return;
            }
            const windowButton = event.target.closest("[data-v2-window]");
            if (windowButton) {
              state.windowFilter = windowButton.dataset.v2Window;
              render();
              notifyFilterChange();
              return;
            }
            const inboxToggle = event.target.closest("[data-v2-inbox-toggle]");
            if (inboxToggle) {
              state.inboxExpanded = !state.inboxExpanded;
              rememberFocus(inboxToggle);
              render();
              return;
            }
            const suggestionBatchEntry = event.target.closest("[data-v2-suggestion-batch-entry]");
            if (suggestionBatchEntry) {
              if (suggestionBatchEntry.disabled || typeof callbacks.onResolveSuggestions !== "function") return;
              suggestionBatchMode = true;
              suggestionBatchLimitReached = false;
              selectedBatchSuggestionIds.clear();
              render();
              root.querySelector("[data-v2-suggestion-batch-select]")?.focus();
              return;
            }
            const suggestionBatchSelectAll = event.target.closest("[data-v2-suggestion-batch-select-all]");
            if (suggestionBatchSelectAll) {
              if (suggestionBatchPending || suggestionBatchSelectAll.disabled) return;
              const seen = /* @__PURE__ */ new Set();
              const available = currentVisibleSuggestionEntries().filter((entry) => {
                if (state.pendingSuggestionIds.has(entry.suggestionId) || seen.has(entry.suggestionId)) return false;
                seen.add(entry.suggestionId);
                return true;
              });
              selectedBatchSuggestionIds.clear();
              available.slice(0, MAX_BATCH_SUGGESTIONS).forEach((entry) => selectedBatchSuggestionIds.add(entry.suggestionId));
              suggestionBatchLimitReached = available.length > MAX_BATCH_SUGGESTIONS;
              rememberFocus(suggestionBatchSelectAll);
              render();
              return;
            }
            if (event.target.closest("[data-v2-suggestion-batch-accept]")) {
              submitSuggestionBatch("accept");
              return;
            }
            if (event.target.closest("[data-v2-suggestion-batch-reject]")) {
              submitSuggestionBatch("reject");
              return;
            }
            const suggestionBatchCancel = event.target.closest("[data-v2-suggestion-batch-cancel]");
            if (suggestionBatchCancel) {
              if (suggestionBatchPending || suggestionBatchCancel.disabled) return;
              suggestionBatchMode = false;
              suggestionBatchLimitReached = false;
              selectedBatchSuggestionIds.clear();
              focusRuntime.setBatchFocus({ type: "entry" });
              render();
              return;
            }
            const suggestionDecision = event.target.closest("[data-v2-suggestion-decision]");
            if (suggestionDecision) {
              const suggestionId = String(suggestionDecision.dataset.v2SuggestionId || "");
              const decision = suggestionDecision.dataset.v2SuggestionDecision;
              const pageId = String(suggestionDecision.dataset.v2SuggestionPage || "");
              if (suggestionDecision.disabled || !suggestionId || !["accept", "reject"].includes(decision) || state.pendingSuggestionIds.has(suggestionId) || typeof callbacks.onResolveSuggestion !== "function") return;
              focusRuntime.setSuggestionIntent({ type: decision, suggestionId, pageId });
              callbacks.onResolveSuggestion(suggestionId, decision);
              return;
            }
            const undoSuggestionButton = event.target.closest("[data-v2-undo-suggestion]");
            if (undoSuggestionButton) {
              const suggestionId = String(undoSuggestionButton.dataset.v2UndoSuggestion || "");
              const pageId = String(undoSuggestionButton.dataset.v2SuggestionPage || undoSuggestionButton.closest("[data-v2-tab]")?.dataset.v2Tab || "");
              if (undoSuggestionButton.disabled || !suggestionId || state.pendingSuggestionIds.has(suggestionId) || typeof callbacks.onUndoSuggestion !== "function") return;
              focusRuntime.setSuggestionIntent({
                type: undoSuggestionButton.closest('[data-v2-context="task"]') ? "undo-accepted" : "undo-reject",
                suggestionId,
                pageId
              });
              callbacks.onUndoSuggestion(suggestionId);
              return;
            }
            const taskToggle = event.target.closest("[data-v2-task-toggle]");
            if (taskToggle) {
              const taskId = String(taskToggle.dataset.v2TaskToggle);
              if (state.expandedTaskIds.has(taskId)) state.expandedTaskIds.delete(taskId);
              else state.expandedTaskIds.add(taskId);
              rememberFocus(taskToggle);
              render();
              return;
            }
            const editTaskButton = event.target.closest("[data-v2-edit-task]");
            if (editTaskButton) {
              const task = findTask(editTaskButton.dataset.v2EditTask);
              if (task && typeof callbacks.onRenameTask === "function") callbacks.onRenameTask(task);
              return;
            }
            const closeTabButton = event.target.closest("[data-v2-close-tab]");
            if (closeTabButton) {
              const tab = findTab(closeTabButton.dataset.v2CloseTab);
              rememberAdjacentTab(closeTabButton);
              if (tab && typeof callbacks.onCloseTab === "function") callbacks.onCloseTab(tab);
              return;
            }
            const removeTabButton = event.target.closest("[data-v2-remove-tab]");
            if (removeTabButton) {
              const task = findTask(removeTabButton.dataset.v2TaskId);
              const tab = findTaskPage(task, removeTabButton.dataset.v2RemoveTab);
              if (!tab || !task || typeof callbacks.onRemoveTabFromTask !== "function") return;
              const replacements = replacementTasksForPage(tab, task);
              const requiresReplacement = tab.isPrimary || tab.role === "primary";
              if (requiresReplacement && replacements.length > 1) {
                const menu = removeTabButton.parentElement.querySelector("[data-v2-primary-menu]");
                const owner = removeTabButton.closest("[data-v2-task]");
                if (menu && menuController.toggle(removeTabButton, menu, owner)) menuController.position(removeTabButton, menu, taskContent, "end");
                return;
              }
              rememberAdjacentTab(removeTabButton);
              callbacks.onRemoveTabFromTask(tab, task, requiresReplacement ? replacements[0]?.id : void 0);
              return;
            }
            const replacementTaskButton = event.target.closest("[data-v2-replacement-task]");
            if (replacementTaskButton) {
              const task = findTask(replacementTaskButton.dataset.v2SourceTask);
              const tab = findTaskPage(task, replacementTaskButton.dataset.v2PageId);
              const replacementTask = findTask(replacementTaskButton.dataset.v2ReplacementTask);
              rememberAdjacentTab(replacementTaskButton);
              menuController.close(true);
              if (tab && task && replacementTask && typeof callbacks.onRemoveTabFromTask === "function") {
                callbacks.onRemoveTabFromTask(tab, task, replacementTask.id);
              }
              return;
            }
            const tabMoreButton = event.target.closest("[data-v2-tab-more]");
            if (tabMoreButton) {
              const tab = findTab(tabMoreButton.dataset.v2TabMore);
              if (tab) openTabActionMenu(tabMoreButton, tab);
              return;
            }
            if (relationMenu.handleNavigation(event.target)) return;
            const relationAction = relationMenu.actionFor(event.target);
            if (relationAction) {
              rememberFocus(menuController.current()?.trigger, queryInput);
              menuController.close(true);
              callbacks.onChangeTabTaskRelation?.(relationAction);
              return;
            }
            const dockSiteToggle = event.target.closest("[data-v2-toggle-dock-site]");
            if (dockSiteToggle) {
              const tab = findTab(dockSiteToggle.dataset.v2ToggleDockSite);
              rememberFocus(menuController.current()?.trigger, queryInput);
              menuController.close(true);
              if (tab && typeof callbacks.onToggleDockSite === "function") callbacks.onToggleDockSite(tab);
              return;
            }
            const inboxAction = event.target.closest("[data-v2-inbox-action]");
            if (inboxAction) {
              const action = inboxAction.dataset.v2InboxAction, tab = findTab(inboxAction.dataset.v2InboxPage);
              rememberFocus(menuController.current()?.trigger, queryInput);
              menuController.close(true);
              if (tab && ["ignore-page", "mark-shared", "exclude-site"].includes(action) && typeof callbacks.onSetInboxPreference === "function") callbacks.onSetInboxPreference(action, tab);
              return;
            }
            const domainOption = event.target.closest("[data-v2-set-domain]");
            if (domainOption) {
              const task = findTask(domainOption.dataset.v2TaskId);
              const domain = domainOption.dataset.v2SetDomain;
              rememberFocus(menuController.current()?.trigger, domainSelect);
              menuController.close(true);
              if (task && Object.hasOwn(DOMAIN_FALLBACKS, domain) && typeof callbacks.onSetTaskDomain === "function") callbacks.onSetTaskDomain(task, domain);
              return;
            }
            const statusOption = event.target.closest("[data-v2-set-status]");
            if (statusOption) {
              const task = findTask(statusOption.dataset.v2TaskId);
              const status = statusOption.dataset.v2SetStatus;
              rememberFocus(menuController.current()?.trigger, statusSelect);
              menuController.close(true);
              if (task && logic.TASK_STATUSES.includes(status) && typeof callbacks.onSetTaskStatus === "function") callbacks.onSetTaskStatus(task, status);
              return;
            }
            const dissolveButton = event.target.closest("[data-v2-dissolve-task]");
            if (dissolveButton) {
              const task = findTask(dissolveButton.dataset.v2DissolveTask);
              rememberAdjacentTask(dissolveButton);
              menuController.close(true);
              if (task && typeof callbacks.onDissolveTask === "function") callbacks.onDissolveTask(task);
              return;
            }
            const moveTaskButton = event.target.closest("[data-v2-move-task]");
            if (moveTaskButton) {
              menuController.close(true);
              requestTaskMove(moveTaskButton.dataset.v2TaskId, Number(moveTaskButton.dataset.v2MoveTask));
              return;
            }
            const domainTrigger = event.target.closest("[data-v2-domain-trigger]");
            if (domainTrigger) {
              const owner = domainTrigger.closest("[data-v2-task]");
              const menu = domainTrigger.parentElement.querySelector("[data-v2-domain-menu]");
              if (menuController.toggle(domainTrigger, menu, owner, menu.querySelector('[aria-checked="true"]'))) {
                menuController.position(domainTrigger, menu, taskContent);
              }
              return;
            }
            const statusTrigger = event.target.closest("[data-v2-status-trigger]");
            if (statusTrigger) {
              const owner = statusTrigger.closest("[data-v2-task]");
              const menu = statusTrigger.parentElement.querySelector("[data-v2-status-menu]");
              if (menuController.toggle(statusTrigger, menu, owner, menu.querySelector('[aria-checked="true"]'))) {
                menuController.position(statusTrigger, menu, taskContent);
              }
              return;
            }
            const openTaskButton = event.target.closest("[data-v2-open-task]");
            if (openTaskButton) {
              const task = findTask(openTaskButton.dataset.v2OpenTask);
              rememberFocus(openTaskButton, queryInput);
              if (task && typeof callbacks.onOpenTaskTabs === "function") callbacks.onOpenTaskTabs(task);
              return;
            }
            const closeTaskButton = event.target.closest("[data-v2-close-task]");
            if (closeTaskButton) {
              const task = findTask(closeTaskButton.dataset.v2CloseTask);
              rememberFocus(closeTaskButton, queryInput);
              if (task && typeof callbacks.onCloseTaskTabs === "function") callbacks.onCloseTaskTabs(task);
              return;
            }
            const taskMoreButton = event.target.closest("[data-v2-task-more]");
            if (taskMoreButton) {
              const owner = taskMoreButton.closest("[data-v2-task]");
              const menu = taskMoreButton.parentElement.querySelector("[data-v2-task-more-menu]");
              if (menuController.toggle(taskMoreButton, menu, owner)) menuController.position(taskMoreButton, menu, taskContent, "end");
              return;
            }
            if (event.target.closest('[data-v2-action="close"]')) {
              if (typeof callbacks.onClose === "function") callbacks.onClose();
              return;
            }
            const themeButton = event.target.closest('[data-v2-action="theme"]');
            if (themeButton) {
              if (typeof callbacks.onTheme === "function") callbacks.onTheme(themeButton);
              return;
            }
            const settingsButton = event.target.closest('[data-v2-action="settings"]');
            if (settingsButton) {
              if (typeof callbacks.onSettings === "function") callbacks.onSettings(settingsButton);
              return;
            }
            if (event.target.closest('[data-v2-action="new-task"]')) {
              if (typeof callbacks.onCreateTask === "function") callbacks.onCreateTask();
              return;
            }
            const undoTaskChangeButton = event.target.closest('[data-v2-action="undo-task-change"]');
            if (undoTaskChangeButton) {
              if (undoTaskChangeButton.disabled || typeof callbacks.onUndoTaskChange !== "function") return;
              rememberFocus(undoTaskChangeButton, root.querySelector('[data-v2-action="new-task"]'), statusSelect);
              undoPending = true;
              undoTaskChangeButton.disabled = true;
              Promise.resolve().then(() => callbacks.onUndoTaskChange()).then(() => {
                undoPending = false;
                const currentButton = root.querySelector('[data-v2-action="undo-task-change"]');
                if (currentButton) currentButton.disabled = !state.canUndo;
              }, () => {
                undoPending = false;
                const currentButton = root.querySelector('[data-v2-action="undo-task-change"]');
                if (currentButton) currentButton.disabled = !state.canUndo;
              });
              return;
            }
            const activateButton = event.target.closest("[data-v2-activate-tab]");
            if (activateButton) activate(activateButton.dataset.v2ActivateTab);
          }
          function onInput(event) {
            if (event.target.matches("[data-v2-browser-columns]")) {
              applyBrowserColumns(event.target.value, true);
              return;
            }
            if (!event.target.matches("[data-v2-query]")) return;
            state.query = event.target.value;
            render();
            queryInput.focus();
            queryInput.setSelectionRange(state.query.length, state.query.length);
            notifyFilterChange();
          }
          function onKeyDown(event) {
            if ((event.ctrlKey || event.metaKey) && String(event.key).toLowerCase() === "k") {
              event.preventDefault();
              focusSearch();
              return;
            }
            if (event.key !== "Escape" || !event.target.matches?.("[data-v2-query]") || !state.query) return;
            event.preventDefault();
            state.query = "";
            queryInput.value = "";
            render();
            notifyFilterChange();
          }
          function onChange(event) {
            if (event.target.matches("[data-v2-suggestion-batch-select]")) {
              const suggestionId = canonicalSuggestionId(event.target.dataset.v2SuggestionId);
              if (!suggestionBatchMode || suggestionBatchPending || event.target.disabled || !suggestionId) return;
              if (event.target.checked) {
                if (selectedBatchSuggestionIds.size >= MAX_BATCH_SUGGESTIONS) {
                  event.target.checked = false;
                  suggestionBatchLimitReached = true;
                } else selectedBatchSuggestionIds.add(suggestionId);
              } else selectedBatchSuggestionIds.delete(suggestionId);
              rememberFocus(event.target);
              render();
              return;
            }
            if (event.target.matches("[data-v2-suggestion-choice]")) {
              const pageId = String(event.target.dataset.v2SuggestionPage || "");
              const suggestionId = String(event.target.dataset.v2SuggestionChoice || "");
              if (pageId && suggestionId) {
                const block = suggestionBlockForPage(pageId);
                const previousId = canonicalSuggestionId(selectedSuggestion(block, Array.isArray(block?.candidates) ? block.candidates : [])?.suggestionId);
                const wasBatchSelected = selectedBatchSuggestionIds.delete(previousId);
                selectedSuggestionIds.set(pageId, suggestionId);
                const nextId = canonicalSuggestionId(suggestionId);
                if (wasBatchSelected && nextId && selectedBatchSuggestionIds.size < MAX_BATCH_SUGGESTIONS) selectedBatchSuggestionIds.add(nextId);
                rememberFocus(event.target);
                render();
              }
              return;
            }
            if (event.target.matches("[data-v2-status-filter]")) state.statusFilter = event.target.value;
            else if (event.target.matches("[data-v2-domain-filter]")) state.domainFilter = event.target.value;
            else if (event.target.matches("[data-v2-task-sort]")) state.taskSort = logic.normalizeTaskSort(event.target.value);
            else return;
            render();
            notifyFilterChange();
          }
          const onImageError = (event) => {
            if (event.target.matches(".tfa-v2-site-icon img")) event.target.hidden = true;
          };
          function clearDragState() {
            root.querySelectorAll(".is-drop-target,.is-task-drop-before,.is-task-drop-after,.is-page-drop-before,.is-page-drop-after,.is-page-drop-end,.is-relation-remove-target").forEach((element) => element.classList.remove("is-drop-target", "is-task-drop-before", "is-task-drop-after", "is-page-drop-before", "is-page-drop-after", "is-page-drop-end", "is-relation-remove-target"));
            if (draggedElement) draggedElement.classList.remove("is-dragging", "is-task-dragging");
            draggedTab = null;
            draggedTask = null;
            draggedElement = null;
          }
          function onDragStart(event) {
            const taskHandle = event.target.closest("[data-v2-task-drag-handle]");
            if (taskHandle) {
              const task = findTask(taskHandle.dataset.v2TaskDragHandle), card2 = taskHandle.closest("[data-v2-task]");
              if (!task || !card2 || !canManuallyReorderTasks()) {
                event.preventDefault();
                return;
              }
              draggedTask = { id: String(task.id) };
              draggedElement = card2;
              card2.classList.add("is-task-dragging");
              if (event.dataTransfer) {
                event.dataTransfer.effectAllowed = "move";
                event.dataTransfer.setData("text/plain", String(task.id));
              }
              return;
            }
            if (event.target.closest(".tfa-v2-tab-actions,.tfa-v2-primary-menu")) {
              event.preventDefault();
              return;
            }
            const dragMain = event.target.closest(".tfa-v2-tab-main"), card = dragMain?.closest("[data-v2-tab]") || event.target.closest("[data-v2-tab]");
            if (!card) {
              event.preventDefault();
              return;
            }
            if (card.dataset.v2Context === "task" && pendingPageOrderTasks.has(card.dataset.v2TaskId)) {
              event.preventDefault();
              return;
            }
            const tab = findTab(card.dataset.v2Tab);
            if (!tab) {
              event.preventDefault();
              return;
            }
            draggedTab = { tab, context: card.dataset.v2Context || "", sourceTaskId: card.dataset.v2TaskId || "", pageId: String(card.dataset.v2Tab) };
            draggedElement = card;
            card.classList.add("is-dragging");
            if (event.dataTransfer) {
              event.dataTransfer.effectAllowed = "copyMove";
              event.dataTransfer.setData("text/plain", String(tab.id));
            }
          }
          function pageDropAfter(card, event) {
            const rect = card.getBoundingClientRect(), styles = options.window?.getComputedStyle?.(card.parentElement) || rootScope.getComputedStyle?.(card.parentElement), columns = String(styles?.gridTemplateColumns || "").trim().split(/\s+/).filter(Boolean).length;
            return columns === 1 ? event.clientY >= rect.top + rect.height / 2 : event.clientX >= rect.left + rect.width / 2;
          }
          function onDragOver(event) {
            const taskElement = taskDropTargetFromEvent(event);
            if (draggedTask) {
              if (!taskElement || taskElement.dataset.v2Task === draggedTask.id) return;
              event.preventDefault();
              const before = event.clientY < taskElement.getBoundingClientRect().top + taskElement.getBoundingClientRect().height / 2;
              root.querySelectorAll(".is-task-drop-before,.is-task-drop-after").forEach((element) => element.classList.remove("is-task-drop-before", "is-task-drop-after"));
              taskElement.classList.add(before ? "is-task-drop-before" : "is-task-drop-after");
              if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
              return;
            }
            if (draggedTab?.context === "task" && taskElement?.dataset.v2Task === draggedTab.sourceTaskId) {
              const grid = event.target.closest(".tfa-v2-task-pages .tfa-v2-tab-grid"), target = event.target.closest('[data-v2-tab][data-v2-context="task"]');
              if (!grid || target?.dataset.v2Tab === draggedTab.pageId) return;
              event.preventDefault();
              root.querySelectorAll(".is-page-drop-before,.is-page-drop-after,.is-page-drop-end").forEach((element) => element.classList.remove("is-page-drop-before", "is-page-drop-after", "is-page-drop-end"));
              if (target) target.classList.add(pageDropAfter(target, event) ? "is-page-drop-after" : "is-page-drop-before");
              else grid.classList.add("is-page-drop-end");
              if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
              return;
            }
            if (draggedTab?.context === "task" && !taskElement) {
              const relationTarget = event.target.closest("[data-v2-browser-content],[data-v2-inbox]");
              if (relationTarget) {
                event.preventDefault();
                root.querySelectorAll(".is-relation-remove-target").forEach((element) => element.classList.toggle("is-relation-remove-target", element === relationTarget));
                if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
                return;
              }
            }
            if (!draggedTab || !taskElement || taskElement.dataset.v2Task === draggedTab.sourceTaskId) return;
            event.preventDefault();
            root.querySelectorAll(".is-drop-target").forEach((element) => element.classList.toggle("is-drop-target", element === taskElement));
            if (event.dataTransfer) event.dataTransfer.dropEffect = "copy";
          }
          function onDragLeave(event) {
            const taskElement = taskDropTargetFromEvent(event);
            if (!taskElement || taskElement.contains(event.relatedTarget)) return;
            taskElement.classList.remove("is-drop-target", "is-task-drop-before", "is-task-drop-after");
            taskElement.querySelectorAll(".is-page-drop-before,.is-page-drop-after,.is-page-drop-end").forEach((element) => element.classList.remove("is-page-drop-before", "is-page-drop-after", "is-page-drop-end"));
          }
          async function onDrop(event) {
            const taskElement = taskDropTargetFromEvent(event);
            if (draggedTask) {
              if (!taskElement || taskElement.dataset.v2Task === draggedTask.id) {
                clearDragState();
                return;
              }
              event.preventDefault();
              const original = manualTaskOrder(), ids = original.filter((id) => id !== draggedTask.id), targetIndex = ids.indexOf(taskElement.dataset.v2Task), before = taskElement.classList.contains("is-task-drop-before");
              ids.splice(Math.max(0, targetIndex + (before ? 0 : 1)), 0, draggedTask.id);
              const sourceElement = draggedElement, changed = ids.some((id, index) => id !== original[index]);
              if (changed) taskElement.parentElement.insertBefore(sourceElement, before ? taskElement : taskElement.nextSibling);
              clearDragState();
              if (changed && typeof callbacks.onReorderTasks === "function") callbacks.onReorderTasks(ids);
              return;
            }
            if (draggedTab?.context === "task" && !taskElement && event.target.closest("[data-v2-browser-content],[data-v2-inbox]")) {
              event.preventDefault();
              const task2 = findTask(draggedTab.sourceTaskId), tab = findTaskPage(task2, draggedTab.pageId), replacements = replacementTasksForPage(tab, task2), requiresReplacement = tab && (tab.isPrimary || tab.role === "primary"), trigger = draggedElement?.querySelector?.("[data-v2-remove-tab]"), menu = trigger?.parentElement?.querySelector?.("[data-v2-primary-menu]"), owner = trigger?.closest?.("[data-v2-task]");
              clearDragState();
              if (requiresReplacement && replacements.length > 1) {
                if (trigger && menu && menuController.toggle(trigger, menu, owner)) menuController.position(trigger, menu, taskContent, "end");
                return;
              }
              if (tab && task2 && typeof callbacks.onRemoveTabFromTask === "function") callbacks.onRemoveTabFromTask(tab, task2, requiresReplacement ? replacements[0]?.id : void 0);
              return;
            }
            if (!draggedTab || !taskElement) return;
            event.preventDefault();
            if (draggedTab.context === "task" && taskElement.dataset.v2Task === draggedTab.sourceTaskId) {
              const task2 = findTask(draggedTab.sourceTaskId), grid = event.target.closest(".tfa-v2-task-pages .tfa-v2-tab-grid"), target = event.target.closest('[data-v2-tab][data-v2-context="task"]');
              if (!grid) {
                clearDragState();
                return;
              }
              const after = target?.classList.contains("is-page-drop-after") === true, original = logic.taskPageIds(task2), ids = logic.reorderTaskPageIds(task2, draggedTab.pageId, target?.dataset.v2Tab ?? null, after), sourceElement = draggedElement, changed = orderChanged(original, ids);
              if (changed && target) grid.insertBefore(sourceElement, after ? target.nextSibling : target);
              else if (changed) grid.appendChild(sourceElement);
              clearDragState();
              if (changed && !submitPageOrder(task2, ids)) render();
              return;
            }
            if (taskElement.dataset.v2Task === draggedTab.sourceTaskId) {
              clearDragState();
              return;
            }
            const task = findTask(taskElement.dataset.v2Task);
            const sourceTask = draggedTab.context === "task" ? findTask(draggedTab.sourceTaskId) : null;
            if (task && sourceTask && typeof callbacks.onChangeTabTaskRelation === "function") {
              const trigger = draggedElement?.querySelector?.("[data-v2-tab-more]");
              relationMenu.showDropChoice(draggedTab.tab, state.tasks, sourceTask, task);
              if (trigger && menuController.toggle(trigger, tabMenu, draggedElement, tabMenu.querySelector("[data-v2-relation-target]"))) menuController.position(trigger, tabMenu, shell);
            } else if (task && typeof callbacks.onAssignTabToTask === "function") {
              const assignment = Promise.resolve(callbacks.onAssignTabToTask(draggedTab.tab, task));
              clearDragState();
              if (await assignment === false) render();
              return;
            }
            clearDragState();
          }
          root.addEventListener("click", onClick);
          root.addEventListener("input", onInput);
          root.addEventListener("keydown", onKeyDown);
          root.addEventListener("change", onChange);
          root.addEventListener("error", onImageError, true);
          root.addEventListener("dragstart", onDragStart);
          root.addEventListener("dragover", onDragOver);
          root.addEventListener("dragleave", onDragLeave);
          root.addEventListener("drop", onDrop);
          root.addEventListener("dragend", clearDragState);
          applyBrowserColumns(state.browserColumns);
          render();
          return Object.freeze({
            focusSearch,
            update(next = {}) {
              if (Array.isArray(next.tabs)) state.tabs = next.tabs;
              if (Array.isArray(next.tasks)) state.tasks = next.tasks;
              if (Array.isArray(next.inboxPages)) state.inboxPages = next.inboxPages;
              if (Array.isArray(next.suggestionBlocks)) state.suggestionBlocks = next.suggestionBlocks;
              if (Array.isArray(next.suggestionNotices)) state.suggestionNotices = next.suggestionNotices;
              if (Object.hasOwn(next, "suggestionLoading")) state.suggestionLoading = next.suggestionLoading === true;
              else if (Object.hasOwn(next, "suggestionsLoading")) state.suggestionLoading = next.suggestionsLoading === true;
              if (Array.isArray(next.pendingSuggestionIds) || next.pendingSuggestionIds instanceof Set) {
                state.pendingSuggestionIds = new Set(next.pendingSuggestionIds);
              }
              if (Object.hasOwn(next, "canUndo")) state.canUndo = next.canUndo === true;
              if (Array.isArray(next.trashItems)) state.trashItems = next.trashItems;
              if (Object.hasOwn(next, "layout")) state.layout = logic.normalizeLayout(next.layout);
              if (Object.hasOwn(next, "theme")) state.theme = next.theme === "dark" ? "dark" : "light";
              if (Object.hasOwn(next, "query")) state.query = String(next.query || "");
              if (Object.hasOwn(next, "windowFilter")) state.windowFilter = String(next.windowFilter || "all");
              if (Object.hasOwn(next, "domainFilter")) state.domainFilter = String(next.domainFilter || "all");
              if (Object.hasOwn(next, "statusFilter")) state.statusFilter = String(next.statusFilter || "all");
              if (Object.hasOwn(next, "taskSort")) state.taskSort = logic.normalizeTaskSort(next.taskSort);
              if (Object.hasOwn(next, "taskView")) state.taskView = next.taskView === "aggregate" || next.taskView === "fishbone" ? next.taskView : "cards";
              if (Object.hasOwn(next, "browserColumns")) applyBrowserColumns(next.browserColumns);
              if (Object.hasOwn(next, "splitRatio")) resizer.update({ ratio: next.splitRatio });
              render();
            },
            getState() {
              return { ...state, tabs: [...state.tabs], tasks: [...state.tasks], inboxPages: [...state.inboxPages], suggestionBlocks: [...state.suggestionBlocks], suggestionNotices: [...state.suggestionNotices], pendingSuggestionIds: [...state.pendingSuggestionIds], suggestionBatchMode, suggestionBatchPending, selectedBatchSuggestionIds: [...selectedBatchSuggestionIds], trashItems: [...state.trashItems] };
            },
            setAiAdjustment(value) {
              return renderer.setAiAdjustment(value);
            },
            destroy() {
              overflowControls?.destroy();
              columnPreferenceObserver?.disconnect?.();
              root.removeEventListener("click", onClick);
              root.removeEventListener("input", onInput);
              root.removeEventListener("keydown", onKeyDown);
              root.removeEventListener("change", onChange);
              root.removeEventListener("error", onImageError, true);
              root.removeEventListener("dragstart", onDragStart);
              root.removeEventListener("dragover", onDragOver);
              root.removeEventListener("dragleave", onDragLeave);
              root.removeEventListener("drop", onDrop);
              root.removeEventListener("dragend", clearDragState);
              resizer.destroy();
              menuController.destroy();
              relationMenu.destroy();
              renderer.destroy();
              selectedSuggestionIds.clear();
              selectedBatchSuggestionIds.clear();
              suggestionBatchMode = false;
              suggestionBatchPending = false;
              scrollActivity?.destroy();
              focusRuntime.clear();
              clearDragState();
              root.innerHTML = "";
            }
          });
        }
        return Object.freeze({ mountV2Workbench, taskDropTargetFromEvent });
      });
    }
  });

  // src/content/v2-workbench-suggestion-runtime.js
  var require_v2_workbench_suggestion_runtime = __commonJS({
    "src/content/v2-workbench-suggestion-runtime.js"(exports, module) {
      (function attachV2WorkbenchSuggestionRuntime(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchSuggestionRuntime = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchSuggestionRuntimeModule() {
        "use strict";
        function createV2WorkbenchSuggestionRuntime(options = {}) {
          const taskApi = options.taskApi || {};
          const translator = () => options.getTranslator?.() || ((key) => key);
          let controller = null;
          let blocks = Object.freeze([]);
          let notices = Object.freeze([]);
          let loading = false;
          let pendingSuggestionIds = Object.freeze([]);
          let contextDirty = false;
          let skipNextOrganization = false;
          let destroyed = false;
          function state() {
            return {
              suggestionBlocks: blocks,
              suggestionNotices: notices,
              suggestionLoading: loading,
              suggestionsLoading: loading,
              pendingSuggestionIds
            };
          }
          function pullState(nextBlocks) {
            if (!controller) return;
            const next = controller.getState();
            blocks = Object.freeze(Array.isArray(nextBlocks) ? nextBlocks.slice() : next.blocks.slice());
            loading = next.loading === true;
            pendingSuggestionIds = Object.freeze(next.pendingSuggestionIds.slice());
          }
          function errorKey(error) {
            const code = String(error?.code || "").toUpperCase();
            if (code.includes("EXPIRED") || code.includes("STALE") || code.includes("SUPERSEDED")) return "suggestion.error.expired";
            if (code.includes("CONFLICT")) return "suggestion.error.conflict";
            return "suggestion.error.failed";
          }
          function showError(error) {
            options.showToast?.(translator()(errorKey(error)), "error", 2200);
          }
          function message(key, params = {}) {
            return String(translator()(key)).replace(/\{(\w+)\}/g, (_match, name) => String(params[name] == null ? "" : params[name]));
          }
          function pageEntityId(page = {}) {
            const value = String(page.pageId || page.id || "").trim();
            return value.startsWith("page-") ? value : "";
          }
          function context(inboxPages = [], tasks = []) {
            const pageIds = [];
            const seen = /* @__PURE__ */ new Set();
            const primaryTaskPages = tasks.flatMap((task) => task?.pages || task?.tabs || []).filter((page) => page?.isPrimary === true);
            for (const page of [...inboxPages, ...primaryTaskPages]) {
              if (page?.suppressSuggestions === true) continue;
              const id = pageEntityId(page);
              if (id && !seen.has(id)) {
                seen.add(id);
                pageIds.push(id);
              }
            }
            return {
              pages: pageIds.map((id) => ({ id })),
              tasks: tasks.map((task) => ({
                id: String(task.id || ""),
                title: String(task.title || task.name || ""),
                domain: String(task.domainId || task.domain || "other")
              })).filter((task) => task.id),
              pageIds
            };
          }
          function refreshContext(inboxPages, tasks) {
            if (!contextDirty) return Promise.resolve(false);
            contextDirty = false;
            if (!controller || destroyed || options.isDestroyed?.()) return Promise.resolve(false);
            const snapshot = context(inboxPages, tasks);
            let operation;
            try {
              operation = controller.setContext(snapshot);
            } catch (error) {
              showError(error);
              return Promise.resolve(false);
            }
            pullState();
            options.onUpdate?.();
            const settled = Promise.resolve(operation).finally(() => {
              if (destroyed || options.isDestroyed?.()) return;
              pullState();
              options.onUpdate?.();
            });
            if (skipNextOrganization) skipNextOrganization = false;
            else if (typeof taskApi.organizeSuggestions === "function" && snapshot.pageIds.length) {
              void settled.then(async () => {
                if (destroyed || options.isDestroyed?.()) return;
                let result;
                try {
                  result = await taskApi.organizeSuggestions(snapshot.pageIds, options.getLocale?.());
                } catch (_error) {
                  return;
                }
                if (result?.adjustment) options.onAdjustment?.(result.adjustment);
                if (Number(result?.updated) > 0 || result?.updated === true || result?.planApplied === true) {
                  skipNextOrganization = true;
                  await options.onOrganizationUpdated?.(result);
                }
              });
            }
            return settled;
          }
          function candidate(suggestionId) {
            for (const block of blocks) {
              const item = (block.candidates || []).find((entry) => entry.suggestionId === suggestionId);
              if (item) return { pageId: block.pageId, taskId: item.taskId };
            }
            return null;
          }
          function recordNotice(meta, suggestionId, decision) {
            if (!meta?.pageId) return;
            const notice = Object.freeze({
              pageId: meta.pageId,
              suggestionId,
              decision,
              ...meta.taskId ? { taskId: meta.taskId } : {}
            });
            notices = Object.freeze([
              ...notices.filter((item) => item.suggestionId !== suggestionId && item.pageId !== meta.pageId),
              notice
            ]);
          }
          async function resolveSuggestion(suggestionId, decision) {
            if (!controller) return false;
            const meta = candidate(suggestionId);
            let operation;
            try {
              operation = controller.resolveSuggestion(suggestionId, decision);
            } catch (error) {
              showError(error);
              return false;
            }
            pullState();
            options.onUpdate?.();
            let resolved;
            try {
              resolved = await operation;
            } catch (error) {
              showError(error);
              pullState();
              options.onUpdate?.();
              return false;
            }
            pullState();
            if (resolved === false) {
              options.onUpdate?.();
              return false;
            }
            if (decision === "accept") {
              try {
                await options.loadWorkbenchData?.();
              } catch (error) {
                showError(error);
                options.onUpdate?.();
                return false;
              }
            }
            recordNotice(meta, suggestionId, decision);
            options.onUpdate?.();
            return true;
          }
          async function resolveSuggestions(suggestionIds, decision) {
            if (!controller?.resolveMany) return false;
            const metaById = new Map((Array.isArray(suggestionIds) ? suggestionIds : []).map((id) => [String(id), candidate(String(id))]));
            let operation;
            try {
              operation = controller.resolveMany(suggestionIds, decision);
            } catch (error) {
              showError(error);
              return false;
            }
            pullState();
            options.onUpdate?.();
            let summary;
            try {
              summary = await operation;
            } catch (error) {
              showError(error);
              pullState();
              options.onUpdate?.();
              return false;
            }
            pullState();
            const succeeded = (summary?.results || []).filter((result) => result?.ok === true);
            if (decision === "accept" && succeeded.length) {
              try {
                await options.loadWorkbenchData?.();
              } catch (error) {
                showError(error);
                options.onUpdate?.();
                return summary;
              }
            }
            succeeded.forEach((result) => recordNotice(metaById.get(result.suggestionId), result.suggestionId, decision));
            options.onUpdate?.();
            if (summary?.total > 0) {
              const partial = Number(summary.failed) > 0;
              options.showToast?.(message(
                partial ? "toast.suggestionBatchPartial" : "toast.suggestionBatchSuccess",
                partial ? { succeeded: Number(summary.succeeded) || 0, failed: Number(summary.failed) || 0 } : { count: Number(summary.succeeded) || 0 }
              ), partial ? "info" : "success", 2200);
            }
            return summary;
          }
          async function undoSuggestion(suggestionId) {
            if (!controller) return false;
            let operation;
            try {
              operation = controller.undoSuggestion(suggestionId);
            } catch (error) {
              showError(error);
              return false;
            }
            pullState();
            options.onUpdate?.();
            let undone;
            try {
              undone = await operation;
            } catch (error) {
              showError(error);
              pullState();
              options.onUpdate?.();
              return false;
            }
            pullState();
            if (undone === false) {
              options.onUpdate?.();
              return false;
            }
            notices = Object.freeze(notices.filter((item) => item.suggestionId !== suggestionId));
            try {
              await options.loadWorkbenchData?.();
            } catch (error) {
              showError(error);
              options.onUpdate?.();
              return false;
            }
            options.onUpdate?.();
            return true;
          }
          function markContextDirty() {
            contextDirty = true;
          }
          function destroy() {
            if (destroyed) return false;
            destroyed = true;
            controller?.destroy();
            controller = null;
            blocks = Object.freeze([]);
            pendingSuggestionIds = Object.freeze([]);
            loading = false;
            contextDirty = false;
            skipNextOrganization = false;
            return true;
          }
          const ready = ["refreshSuggestions", "listSuggestions", "resolveSuggestion", "undoSuggestion"].every((name) => typeof taskApi[name] === "function");
          if (options.suggestionControllerModule?.createV2SuggestionController && typeof options.suggestionViewLogic?.buildSuggestionViewBlocks === "function" && ready) {
            controller = options.suggestionControllerModule.createV2SuggestionController({
              taskApi,
              buildSuggestionViewBlocks: options.suggestionViewLogic.buildSuggestionViewBlocks,
              onChange(nextBlocks) {
                pullState(nextBlocks);
                options.onUpdate?.();
              },
              onError(error) {
                pullState();
                showError(error);
                options.onUpdate?.();
              }
            });
          }
          return Object.freeze({
            getState: state,
            markContextDirty,
            refreshContext,
            resolveSuggestion,
            resolveSuggestions,
            undoSuggestion,
            destroy
          });
        }
        return Object.freeze({ createV2WorkbenchSuggestionRuntime });
      });
    }
  });

  // src/content/v2-inbox-observation-refresh.js
  var require_v2_inbox_observation_refresh = __commonJS({
    "src/content/v2-inbox-observation-refresh.js"(exports, module) {
      (function attachInboxObservationRefresh(rootScope, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2InboxObservationRefresh = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createInboxObservationRefreshModule() {
        "use strict";
        function createInboxObservationRefreshScheduler(options = {}) {
          const now = options.now || Date.now;
          const setTimer = options.setTimeout || setTimeout;
          const clearTimer = options.clearTimeout || clearTimeout;
          let timer = null;
          function cancel() {
            if (timer == null) return false;
            clearTimer(timer);
            timer = null;
            return true;
          }
          function schedule(pages = []) {
            cancel();
            const current = Number(now());
            const deadlines = pages.filter((page) => page?.observationState === "observing").map((page) => Number(page.observeUntil)).filter((deadline) => Number.isFinite(deadline) && deadline > current);
            if (!deadlines.length) return false;
            const delay = Math.min(2147483647, Math.max(1, Math.min(...deadlines) - current + 1));
            timer = setTimer(() => {
              timer = null;
              Promise.resolve(options.onDue?.()).catch(() => {
              });
            }, delay);
            return true;
          }
          return Object.freeze({ schedule, cancel, destroy: cancel });
        }
        return Object.freeze({ createInboxObservationRefreshScheduler });
      });
    }
  });

  // src/content/v2-workbench-runtime.js
  var require_v2_workbench_runtime = __commonJS({
    "src/content/v2-workbench-runtime.js"(exports, module) {
      (function attachV2WorkbenchRuntime(rootScope, factory) {
        const suggestionRuntimeModule = typeof module === "object" && module.exports ? require_v2_workbench_suggestion_runtime() : rootScope.TfaV2WorkbenchSuggestionRuntime;
        const layoutPreferencesModule = typeof module === "object" && module.exports ? require_v2_workbench_layout_preferences() : rootScope.TfaV2WorkbenchLayoutPreferences;
        const tabAwarenessLogic = typeof module === "object" && module.exports ? require_v2_tab_awareness_logic() : rootScope.TfaV2TabAwarenessLogic;
        const nativeTabCommandModule = typeof module === "object" && module.exports ? require_v2_native_tab_command_runtime() : rootScope.TfaV2NativeTabCommandRuntime;
        const inboxObservationRefreshModule = typeof module === "object" && module.exports ? require_v2_inbox_observation_refresh() : rootScope.TfaV2InboxObservationRefresh;
        const api = factory(rootScope, suggestionRuntimeModule, layoutPreferencesModule, tabAwarenessLogic, nativeTabCommandModule, inboxObservationRefreshModule);
        if (typeof module === "object" && module.exports) module.exports = api;
        rootScope.TfaV2WorkbenchRuntime = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createV2WorkbenchRuntimeModule(rootScope, suggestionRuntimeModule, layoutPreferencesModule, tabAwarenessLogic, nativeTabCommandModule, inboxObservationRefreshModule) {
        "use strict";
        function createV2WorkbenchRuntime(options = {}) {
          const viewModule = options.view || rootScope.TfaV2WorkbenchView;
          const i18n = options.i18n || rootScope.TfaI18n;
          const browserAdapterModule = options.browserAdapter || rootScope.TfaBrowserAdapter;
          const taskDialogModule = options.taskDialog || rootScope.TfaV2TaskDialog;
          const trashCoordinatorModule = options.trashCoordinatorModule || rootScope.TfaV2TaskTrashCoordinator;
          const suggestionViewLogic = options.suggestionViewLogic || rootScope.TfaV2SuggestionViewLogic;
          const suggestionControllerModule = options.suggestionControllerModule || rootScope.TfaV2SuggestionController;
          const workbenchSuggestionModule = options.suggestionRuntimeModule || suggestionRuntimeModule;
          if (!viewModule || !i18n || !browserAdapterModule || !taskDialogModule || !trashCoordinatorModule || !workbenchSuggestionModule?.createV2WorkbenchSuggestionRuntime || !inboxObservationRefreshModule?.createInboxObservationRefreshScheduler || !options.taskApi) {
            throw new Error("V2 workbench dependencies are unavailable");
          }
          const documentRef = options.document || rootScope.document;
          const windowRef = options.window || rootScope.window;
          const browser = browserAdapterModule.createBrowserAdapter({ root: { chrome: options.chrome || rootScope.chrome }, userAgent: windowRef?.navigator?.userAgent });
          const taskApi = options.taskApi;
          const layoutPreferences = options.layoutPreferences || layoutPreferencesModule.createLayoutPreferences({ storage: browser.storage?.local });
          const dwellTracker = tabAwarenessLogic.createSessionDwellTracker({ now: options.now || Date.now });
          const taskTrashCoordinator = options.taskTrashCoordinator || trashCoordinatorModule.createV2TaskTrashCoordinator({
            addTaskToTrash: (...args) => options.addTaskToTrash?.(...args),
            updateTaskTrashOperation: (...args) => options.updateTaskTrashOperation?.(...args),
            getTaskTrashOperations: (...args) => options.getTaskTrashOperations?.(...args),
            deleteTask: (...args) => taskApi.deleteTask(...args),
            restoreTask: (...args) => taskApi.restoreTask(...args),
            undoLast: (...args) => taskApi.undoLast(...args)
          });
          let tasks = [];
          let inboxPages = [];
          let canUndo = false;
          let trashItems = [];
          let currentLayout = "split";
          let currentSplitRatio = layoutPreferencesModule.DEFAULT_PREFERENCES.splitRatio;
          let translator = i18n.createTranslator("zh"), locale = "zh-CN";
          let aiAdjustment = null;
          let view = null;
          let mountRoot = null;
          let attachedShadowRoot = null;
          let previousPanelVisibility = "";
          let destroyed = false;
          let inboxRequestId = 0;
          let inboxRefreshPromise = null;
          let taskDialog = null;
          let editingTaskId = "";
          let languageListenerAttached = false, languageRevision = 0, lifecycleEpoch = 0;
          const observationRefresh = inboxObservationRefreshModule.createInboxObservationRefreshScheduler({ now: options.now || Date.now, setTimeout: options.setTimeout || windowRef?.setTimeout?.bind(windowRef), clearTimeout: options.clearTimeout || windowRef?.clearTimeout?.bind(windowRef), onDue: () => refreshInbox() });
          const suggestionRuntime = workbenchSuggestionModule.createV2WorkbenchSuggestionRuntime({
            taskApi,
            suggestionControllerModule,
            suggestionViewLogic,
            getTranslator: () => translator,
            getLocale: () => locale,
            showToast: (...args) => options.showToast?.(...args),
            onUpdate: () => update(),
            loadWorkbenchData: () => loadWorkbenchData(),
            onAdjustment(value) {
              aiAdjustment = value;
              view?.setAiAdjustment?.(value);
            },
            async onOrganizationUpdated() {
              await loadWorkbenchData();
              update();
            },
            isDestroyed: () => destroyed
          });
          function normalizedUrl(value) {
            const raw = String(value || "").trim();
            if (!raw) return "";
            try {
              return new URL(raw).href;
            } catch (_error) {
              return raw;
            }
          }
          function commandSucceeded(response) {
            return response === true || Boolean(response && !response.error && response.ok === true);
          }
          function commandError(response) {
            return response && (response.error || response.message) ? String(response.error || response.message) : "";
          }
          function operationError(result, fallbackKey = "toast.taskChangeFailed") {
            return result?.error?.message || String(result?.error || translator(fallbackKey));
          }
          function pageRecord(tab = {}) {
            const rawId = tab.id, tabId = Number(tab.tabId ?? tab.liveTabId ?? (Number.isInteger(rawId) ? rawId : null));
            const canonicalPageId = [tab.pageId, rawId].find((value) => typeof value === "string" && value.startsWith("page-")) || "";
            const { id: _browserTabId, pageId: _pageIdAlias, ...page } = tab;
            return {
              ...page,
              ...canonicalPageId ? { id: canonicalPageId } : {},
              tabId: Number.isInteger(tabId) ? tabId : null,
              favicon: tab.favicon || tab.favIconUrl || tab.faviconUrl || "",
              source: "manual"
            };
          }
          function dockFixed(url) {
            try {
              return Boolean(options.isDockSiteFixed?.(url));
            } catch (_error) {
              return false;
            }
          }
          function pageForView(page = {}, includePreview = false) {
            const live = currentTabForPage(page), linkKey = tabAwarenessLogic.pageLinkKey(page.url), dwell = dwellTracker.read(linkKey);
            return {
              ...page,
              dockFixed: dockFixed(page.url),
              linkKey,
              isOpen: Boolean(live),
              active: live?.active === true,
              liveTabId: live?.id ?? null,
              sessionDwellTotalMs: dwell.totalMs,
              sessionDwellActiveSince: dwell.activeSince,
              sessionDwellTracked: dwell.tracked,
              dwellLanguage: locale === "en" ? "en" : "zh",
              previewScreenshot: includePreview && live ? options.getTabPreview?.(live.id) || "" : ""
            };
          }
          function taskForView(task = {}) {
            const result = { ...task };
            if (Array.isArray(task.pages)) result.pages = task.pages.map((page) => pageForView(page));
            if (Array.isArray(task.tabs)) result.tabs = task.tabs.map((page) => pageForView(page));
            result.hasOpenTabs = (task.pages || task.tabs || []).some((page) => Boolean(currentTabForPage(page)));
            return result;
          }
          function viewState() {
            const browserTabs = options.getTabs?.() || [];
            dwellTracker.sync(browserTabs);
            return {
              tabs: browserTabs.map((page) => pageForView(page, true)),
              tasks: tasks.map(taskForView),
              inboxPages: inboxPages.map((page) => pageForView(page))
            };
          }
          function notify(key, type = "success") {
            options.showToast?.(translator(key), type, 1800);
          }
          function projectTaskData(response = {}) {
            if (response.legacy === true || !Array.isArray(response.pages) && !Array.isArray(response.relations)) {
              return Array.isArray(response.tasks) ? response.tasks : [];
            }
            const pages = new Map((response.pages || []).map((page) => [page.id, page]));
            const relationsByTask = /* @__PURE__ */ new Map();
            const relationsByPage = /* @__PURE__ */ new Map();
            for (const relation of response.relations || []) {
              const taskRelations = relationsByTask.get(relation.taskId) || [];
              taskRelations.push(relation);
              relationsByTask.set(relation.taskId, taskRelations);
              const pageRelations = relationsByPage.get(relation.pageId) || [];
              pageRelations.push(relation);
              relationsByPage.set(relation.pageId, pageRelations);
            }
            return [...response.tasks || []].sort((left, right) => Number(left.sortOrder) - Number(right.sortOrder) || String(left.id).localeCompare(String(right.id))).map((task) => ({
              ...task,
              pages: [...relationsByTask.get(task.id) || []].sort((left, right) => Number(left.sortOrder) - Number(right.sortOrder) || String(left.id).localeCompare(String(right.id))).map((relation) => {
                const page = pages.get(relation.pageId);
                if (!page) return null;
                return {
                  id: page.id,
                  pageId: page.id,
                  title: page.title,
                  url: page.restoreUrl,
                  favicon: page.faviconUrl || "",
                  source: relation.source || "manual",
                  role: relation.role,
                  isPrimary: relation.isPrimary === true,
                  relationId: relation.id,
                  manualLocked: relation.manualLocked === true,
                  confidence: relation.confidence,
                  evidence: String(relation.evidence || ""),
                  sortOrder: relation.sortOrder,
                  relatedTaskIds: (relationsByPage.get(page.id) || []).map((item) => item.taskId)
                };
              }).filter(Boolean)
            }));
          }
          async function loadTaskData() {
            const response = await taskApi.list();
            if (!response || response.ok === false || response.error) throw new Error(commandError(response) || "Task data unavailable");
            tasks = projectTaskData(response);
            canUndo = response.canUndo === true;
            suggestionRuntime.markContextDirty();
            return tasks;
          }
          async function loadInboxData() {
            if (typeof taskApi.listInbox !== "function") {
              inboxPages = [];
              return inboxPages;
            }
            const requestId = ++inboxRequestId;
            const response = await taskApi.listInbox();
            if (!response || response.ok === false || response.error || !Array.isArray(response.pages)) {
              throw new Error(commandError(response) || "Unassigned tabs unavailable");
            }
            if (requestId === inboxRequestId) {
              inboxPages = response.pages;
              observationRefresh.schedule(inboxPages);
              suggestionRuntime.markContextDirty();
            }
            return response.pages;
          }
          async function loadWorkbenchData() {
            await loadTaskData();
            await loadInboxData().catch(() => inboxPages);
            return { tasks, inboxPages };
          }
          async function refreshTaskData() {
            if (destroyed) return false;
            await loadWorkbenchData();
            update();
            return true;
          }
          function refreshInbox() {
            if (destroyed) return Promise.resolve(false);
            if (inboxRefreshPromise) return inboxRefreshPromise;
            inboxRefreshPromise = loadInboxData().then(() => {
              update();
              return true;
            }).catch(() => false).finally(() => {
              inboxRefreshPromise = null;
            });
            return inboxRefreshPromise;
          }
          async function persistTaskChange(work, successKey) {
            try {
              const response = await work();
              if (response && response.ok === false) throw new Error(commandError(response) || "Task change failed");
              await loadTaskData();
              await loadInboxData().catch(() => inboxPages);
              update();
              if (successKey) notify(successKey);
              return true;
            } catch (error) {
              options.showToast?.(error?.message || translator("toast.taskChangeFailed"), "error", 2200);
              return false;
            }
          }
          async function runTabCommand(work, errorKey = "toast.tabCommandFailed") {
            try {
              const response = await work();
              if (commandSucceeded(response)) return true;
              options.showToast?.(commandError(response) || translator(errorKey), "error", 2200);
            } catch (error) {
              options.showToast?.(error?.message || translator(errorKey), "error", 2200);
            }
            return false;
          }
          const nativeTabCommands = nativeTabCommandModule.createNativeTabCommandRuntime({ ...options, runCommand: runTabCommand, update });
          function validTrashResponse(response) {
            return Boolean(response && !response.error && Array.isArray(response.trash));
          }
          async function loadTrash({ quiet = false } = {}) {
            try {
              const response = await options.getTrash?.();
              if (!validTrashResponse(response)) throw new Error(commandError(response) || translator("toast.trashLoadFailed"));
              trashItems = response.trash;
              update();
              return true;
            } catch (error) {
              if (!quiet) options.showToast?.(error?.message || translator("toast.trashLoadFailed"), "error", 2200);
              return false;
            }
          }
          async function deleteTrashItem(item, { confirm = true, quiet = false } = {}) {
            if (!item?.id) return false;
            if (confirm && windowRef.confirm?.(translator("task.confirmDeleteTrash")) !== true) return false;
            const ok = await runTabCommand(() => options.deleteTrashItem?.(item.id, { itemType: item.type }), "toast.trashActionFailed");
            if (!ok) return false;
            trashItems = trashItems.filter((entry) => String(entry.id) !== String(item.id));
            update();
            if (!quiet) notify("toast.trashDeleted");
            return true;
          }
          async function restoreTrashItem(item, { quiet = false, restoreBatchId = "" } = {}) {
            if (!item?.id) return false;
            if (item.type === "task") {
              const result = await taskTrashCoordinator.restore(item);
              if (!result.ok) {
                options.showToast?.(operationError(result, "toast.trashActionFailed"), result.uncertain ? "info" : "error", 2200);
                if (result.uncertain) notify("toast.taskOperationPending", "info");
                await loadTrash({ quiet: true });
                return false;
              }
              await loadWorkbenchData();
              if (result.legacyCleanupRequired) {
                let removed = false;
                try {
                  removed = commandSucceeded(await options.deleteTrashItem?.(item.id, { itemType: item.type }));
                } catch (_error) {
                  removed = false;
                }
                if (!removed) {
                  await loadTrash({ quiet: true });
                  update();
                  if (!quiet) notify("toast.taskTrashCleanupPending", "info");
                  return result.restored === true;
                }
              }
              await loadTrash({ quiet: true });
              if (["consumed", "already-restored"].includes(result.outcome)) return false;
              if (result.cleanupPending && !quiet) notify("toast.taskTrashCleanupPending", "info");
            } else {
              const restored = await runTabCommand(() => options.restoreTrashItem?.(item.id, { restoreBatchId }), "toast.trashActionFailed");
              if (!restored) return false;
              await options.refresh?.();
            }
            trashItems = trashItems.filter((entry) => String(entry.id) !== String(item.id));
            update();
            if (!quiet) notify(item.type === "task" ? "toast.taskRestored" : "toast.trashRestored");
            return true;
          }
          async function restoreAllTrash(items = trashItems) {
            const targets = [...Array.isArray(items) ? items : trashItems];
            const restoreBatchId = `restore-batch-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
            let restored = 0;
            for (const item of targets) if (await restoreTrashItem(item, { quiet: true, restoreBatchId })) restored += 1;
            if (restored) notify("toast.trashRestoreAll");
            return restored === targets.length;
          }
          function currentTabForPage(page = {}) {
            const currentTabs = options.getTabs?.() || [];
            const pageUrl = normalizedUrl(page.url);
            if (!pageUrl) return null;
            const storedTabId = Number(page.tabId == null ? page.id : page.tabId);
            const exactLiveTab = Number.isInteger(storedTabId) ? currentTabs.find((tab) => Number(tab.id) === storedTabId && normalizedUrl(tab.url) === pageUrl) : null;
            return exactLiveTab || currentTabs.find((tab) => normalizedUrl(tab.url) === pageUrl) || null;
          }
          function currentTabsForTask(task) {
            const currentTabs = options.getTabs?.() || [];
            const pageUrls = new Set((task.pages || []).map((page) => normalizedUrl(page.url)).filter(Boolean));
            return currentTabs.filter((tab) => pageUrls.has(normalizedUrl(tab.url)));
          }
          async function activateOrOpenPage(page) {
            const liveTab = currentTabForPage(page);
            if (liveTab) return runTabCommand(() => options.activateTab?.(liveTab.id));
            const url = normalizedUrl(page?.url);
            if (url) return runTabCommand(() => options.openTab?.(url, true));
            options.showToast?.(translator("toast.tabNotOpen"), "error", 2200);
            return false;
          }
          async function openTaskPages(task) {
            const currentTabs = options.getTabs?.() || [];
            const openUrls = new Set(currentTabs.map((tab) => normalizedUrl(tab.url)).filter(Boolean));
            const missing = [];
            for (const page of task.pages || []) {
              const url = normalizedUrl(page.url);
              if (!url || openUrls.has(url)) continue;
              openUrls.add(url);
              missing.push({ ...page, url });
            }
            for (const page of missing) {
              if (!await runTabCommand(() => options.openTab?.(page.url, false), "toast.taskOpenFailed")) return false;
            }
            const firstOpen = currentTabsForTask(task)[0];
            if (!missing.length && firstOpen && !await runTabCommand(() => options.activateTab?.(firstOpen.id), "toast.taskOpenFailed")) return false;
            await options.refresh?.();
            update();
            notify(missing.length ? "toast.taskOpened" : "toast.taskAlreadyOpen", missing.length ? "success" : "info");
            return true;
          }
          async function closeTaskPages(task) {
            const tabIds = currentTabsForTask(task).map((tab) => Number(tab.id)).filter(Number.isInteger);
            if (!tabIds.length) {
              notify("toast.taskNoOpenTabs", "info");
              return;
            }
            if (!await runTabCommand(() => options.closeTabs?.(tabIds), "toast.taskCloseFailed")) return false;
            await options.refresh?.();
            update();
            notify("toast.taskTabsClosed");
            return true;
          }
          async function undoAiPlan(changeId) {
            if (typeof taskApi.undoAiPlan !== "function") return { ok: false, errorCode: "AI_PLAN_UNDO_UNAVAILABLE" };
            let result;
            try {
              result = await taskApi.undoAiPlan(changeId);
            } catch (_error) {
              return { ok: false, errorCode: "AI_REQUEST_FAILED" };
            }
            if (result?.ok === true) {
              await loadWorkbenchData();
              update();
            }
            return result;
          }
          function selectedTheme() {
            const theme = options.getTheme?.();
            return ["snow", "paper", "pro", "light"].includes(theme) ? "light" : "dark";
          }
          function applyLanguage(manual) {
            const language = i18n.resolveLanguage({
              manual,
              browserLanguage: browser.i18n?.getUILanguage?.(),
              navigatorLanguage: windowRef?.navigator?.language
            });
            locale = language === "zh" ? "zh-CN" : "en";
            translator = i18n.createTranslator(language);
          }
          function remountForLanguage() {
            if (destroyed || !view) return update();
            const panel = options.getRoot?.()?.getElementById?.("panel");
            taskDialog?.destroy();
            taskDialog = null;
            view.destroy();
            view = null;
            mountRoot?.remove?.();
            mountRoot = null;
            attachedShadowRoot = null;
            if (panel) panel.style.visibility = previousPanelVisibility;
            return update();
          }
          function handleLanguageChange(changes, areaName) {
            const change = areaName === "sync" ? changes?.[i18n.LANGUAGE_STORAGE_KEY] : null;
            if (!change || destroyed) return;
            languageRevision += 1;
            applyLanguage(change.newValue);
            remountForLanguage();
          }
          function attach() {
            if (destroyed) return false;
            const shadowRoot = options.getRoot?.();
            const overlay = shadowRoot?.getElementById?.("overlay");
            const panel = shadowRoot?.getElementById?.("panel");
            if (!shadowRoot || !overlay || !panel) return false;
            if (view && mountRoot?.isConnected && attachedShadowRoot === shadowRoot) return true;
            taskDialog?.destroy();
            taskDialog = null;
            view?.destroy();
            mountRoot?.remove?.();
            mountRoot = documentRef.createElement("div");
            mountRoot.id = "tfaV2WorkbenchHost";
            mountRoot.style.cssText = "position:absolute;inset:clamp(12px,2.5vw,48px);z-index:65;pointer-events:inherit;min-width:0;min-height:0;";
            overlay.appendChild(mountRoot);
            previousPanelVisibility = panel.style.visibility;
            panel.style.visibility = "hidden";
            try {
              const projected = viewState();
              view = viewModule.mountV2Workbench({
                root: mountRoot,
                tabs: projected.tabs,
                tasks: projected.tasks,
                inboxPages: projected.inboxPages,
                ...suggestionRuntime.getState(),
                locale,
                aiAdjustment,
                canUndo,
                trashItems,
                layout: currentLayout,
                splitRatio: currentSplitRatio,
                theme: selectedTheme(),
                t: translator,
                onActivateTab: (tab) => activateOrOpenPage(tab),
                onCloseTab: async (tab) => {
                  const liveTab = currentTabForPage(tab);
                  if (!liveTab) {
                    options.showToast?.(translator("toast.tabNotOpen"), "error", 2200);
                    return false;
                  }
                  if (!await runTabCommand(() => options.closeTab?.(liveTab.id))) return false;
                  await options.refresh?.();
                  update();
                  return true;
                },
                onClose: () => options.close?.(),
                onTheme: () => options.toggleTheme?.(),
                onSettings: (trigger) => options.openSettings?.(trigger),
                onResolveSuggestion: (suggestionId, decision) => suggestionRuntime.resolveSuggestion(suggestionId, decision),
                onResolveSuggestions: (suggestionIds, decision) => suggestionRuntime.resolveSuggestions(suggestionIds, decision),
                onUndoSuggestion: (suggestionId) => suggestionRuntime.undoSuggestion(suggestionId),
                onUndoAiPlan: (changeId) => undoAiPlan(changeId),
                onSetInboxPreference: async (action, page) => {
                  try {
                    const response = await taskApi.setInboxPreference?.(action, page.pageId || page.id, page.url);
                    if (response?.ok === false) throw new Error(response.error || translator("toast.inboxPreferenceFailed"));
                    await loadInboxData();
                    update();
                    return true;
                  } catch (error) {
                    options.showToast?.(error?.message || translator("toast.inboxPreferenceFailed"), "error", 2200);
                    return false;
                  }
                },
                onNativeGroupIntent: nativeTabCommands.applyGroupIntent,
                onNativeWindowIntent: nativeTabCommands.applyWindowIntent,
                onReorderBrowserTab: nativeTabCommands.reorder,
                onEditNativeGroup: (group) => options.editNativeGroup?.(group),
                onRequestTabPreview: (tabId) => options.requestTabPreview?.(tabId),
                onAssignTabToTask: (tab, task) => persistTaskChange(
                  () => taskApi.addRelation(task.id, pageRecord(tab), { role: "core" }),
                  "toast.taskAssigned"
                ),
                onChangeTabTaskRelation: (action) => {
                  const targetTaskId = String(action?.targetTask?.id || "");
                  const sourceTaskId = String(action?.sourceTask?.id || "");
                  const pageId = String(action?.pageId || action?.tab?.pageId || "");
                  if (action?.type === "move" && sourceTaskId && targetTaskId && pageId) {
                    return persistTaskChange(
                      () => taskApi.moveRelation(sourceTaskId, targetTaskId, pageId),
                      "toast.taskRelationMoved"
                    );
                  }
                  if (action?.type === "primary" && targetTaskId && pageId) {
                    return persistTaskChange(
                      () => taskApi.setPrimaryRelation(targetTaskId, pageId),
                      "toast.taskPrimaryChanged"
                    );
                  }
                  if (["assign", "share"].includes(action?.type) && targetTaskId && action?.tab) {
                    return persistTaskChange(
                      () => taskApi.addRelation(targetTaskId, pageRecord(action.tab), {
                        role: action.type === "share" ? "shared" : "core",
                        ...action.type === "share" ? { isPrimary: false } : {}
                      }),
                      action.type === "share" ? "toast.taskRelationShared" : "toast.taskAssigned"
                    );
                  }
                  return Promise.resolve(false);
                },
                onRemoveTabFromTask: (tab, task, replacementTaskId) => persistTaskChange(
                  () => {
                    const pageId = tab.pageId || tab.id;
                    const alternatives = (tab.relatedTaskIds || []).filter((taskId) => taskId !== task.id);
                    const resolvedReplacementTaskId = replacementTaskId !== void 0 ? replacementTaskId : tab.isPrimary && alternatives.length === 1 ? alternatives[0] : "";
                    return taskApi.removeRelation(task.id, pageId, resolvedReplacementTaskId);
                  },
                  "toast.taskRemoved"
                ),
                onUndoTaskChange: async () => {
                  const result = await taskTrashCoordinator.undo();
                  if (!result.ok) {
                    options.showToast?.(operationError(result), "error", 2200);
                    return false;
                  }
                  await loadWorkbenchData();
                  await loadTrash({ quiet: true });
                  update();
                  notify("toast.taskChangeUndone");
                  if (result.compensationPending) notify("toast.taskOperationPending", "info");
                  return true;
                },
                onSetTaskStatus: (task, status) => persistTaskChange(
                  () => taskApi.updateTask(task.id, { status }),
                  "toast.taskStatusChanged"
                ),
                onSetTaskDomain: (task, domain) => persistTaskChange(
                  () => taskApi.updateTask(task.id, { domain }),
                  "toast.taskDomainChanged"
                ),
                onReorderTasks: async (orderedTaskIds) => {
                  const saved = await persistTaskChange(() => taskApi.reorderTasks(orderedTaskIds), "toast.taskReordered");
                  if (!saved) {
                    await loadTaskData().catch(() => null);
                    update();
                  }
                  return saved;
                },
                onReorderTaskPages: async (task, orderedPageIds) => {
                  const saved = await persistTaskChange(
                    () => taskApi.reorderRelations(task.id, orderedPageIds),
                    "toast.taskPagesReordered"
                  );
                  if (!saved) {
                    await loadTaskData().catch(() => null);
                    update();
                  }
                  return saved;
                },
                onDissolveTask: async (task) => {
                  if (windowRef.confirm?.(translator("task.confirmDissolve")) !== true) return Promise.resolve(false);
                  const replacements = Object.fromEntries((task.pages || []).map((page) => [page, (page.relatedTaskIds || []).filter((taskId) => taskId !== task.id)]).filter(([page, alternatives]) => page.isPrimary && alternatives.length === 1).map(([page, alternatives]) => [page.pageId || page.id, alternatives[0]]));
                  const result = await taskTrashCoordinator.dissolve(task, replacements);
                  await loadWorkbenchData().catch(() => null);
                  await loadTrash({ quiet: true });
                  update();
                  if (!result.ok) {
                    options.showToast?.(operationError(result, "toast.trashActionFailed"), result.uncertain ? "info" : "error", 2200);
                    if (result.uncertain || result.compensationPending) notify("toast.taskOperationPending", "info");
                    return false;
                  }
                  if (result.outcome === "undone") return false;
                  notify("toast.taskDissolved");
                  if (!result.trashReady) notify("toast.taskOperationPending", "info");
                  return true;
                },
                onRestoreTrashItem: (item) => restoreTrashItem(item),
                onDeleteTrashItem: (item) => deleteTrashItem(item),
                onRestoreAllTrash: (items) => restoreAllTrash(items),
                onLayoutChange: (layout) => {
                  currentLayout = layoutPreferencesModule.normalizeLayout(layout);
                  options.onLayoutChange?.(layout);
                  void layoutPreferences.save({ splitRatio: currentSplitRatio, layout: currentLayout });
                  if (currentLayout === "recycle") loadTrash();
                },
                onSplitRatioChange: (splitRatio) => {
                  currentSplitRatio = layoutPreferencesModule.normalizeSplitRatio(splitRatio);
                  void layoutPreferences.save({ splitRatio: currentSplitRatio, layout: currentLayout });
                },
                onToggleDockSite: async (tab) => {
                  const changed = await options.toggleDockSite?.(tab);
                  if (changed) update();
                  return Boolean(changed);
                },
                onOpenTaskTabs: (task) => openTaskPages(task),
                onCloseTaskTabs: (task) => closeTaskPages(task),
                onCreateTask: async () => {
                  editingTaskId = "";
                  taskDialog?.open({ title: "", domain: "work", mode: "create" });
                },
                onRenameTask: (task) => {
                  editingTaskId = String(task?.id || "");
                  taskDialog?.open({
                    title: task?.title || task?.name || "",
                    domain: task?.domainId || task?.domain || "other",
                    mode: "rename"
                  });
                }
              });
              if (taskDialogModule?.createV2TaskDialog) {
                taskDialog = taskDialogModule.createV2TaskDialog({
                  document: documentRef,
                  root: mountRoot,
                  t: translator,
                  onSubmit: async ({ title, domain, mode }) => {
                    if (mode === "rename") await loadTaskData();
                    const task = mode === "rename" ? tasks.find((item) => String(item.id) === editingTaskId) : null;
                    if (mode === "rename" && !task) {
                      update();
                      throw new Error(translator("toast.taskMissing"));
                    }
                    const saved = task ? await persistTaskChange(() => taskApi.updateTask(task.id, { title, domain }), "toast.taskRenamed") : await persistTaskChange(() => taskApi.createTask({ title, domain }), "toast.taskCreated");
                    if (!saved) throw new Error(translator("toast.taskChangeFailed"));
                    editingTaskId = "";
                  }
                });
              }
              attachedShadowRoot = shadowRoot;
              return true;
            } catch (_error) {
              taskDialog?.destroy();
              taskDialog = null;
              view?.destroy();
              panel.style.visibility = previousPanelVisibility;
              mountRoot.remove?.();
              mountRoot = null;
              view = null;
              attachedShadowRoot = null;
              return false;
            }
          }
          function update() {
            if (destroyed) return false;
            if (!attach()) return false;
            const projected = viewState();
            view.update({
              tabs: projected.tabs,
              tasks: projected.tasks,
              inboxPages: projected.inboxPages,
              trashItems,
              canUndo,
              ...suggestionRuntime.getState(),
              layout: currentLayout,
              theme: selectedTheme(),
              t: translator
            });
            void suggestionRuntime.refreshContext(inboxPages, tasks);
            return true;
          }
          async function start() {
            const epoch = ++lifecycleEpoch, revision = languageRevision;
            if (!languageListenerAttached && browser.storage?.onChanged?.addListener) {
              browser.storage.onChanged.addListener(handleLanguageChange);
              languageListenerAttached = true;
            }
            const layoutPreference = await layoutPreferences.load();
            if (destroyed || epoch !== lifecycleEpoch) return false;
            currentSplitRatio = layoutPreference.splitRatio;
            currentLayout = layoutPreferencesModule.normalizeLayout(layoutPreference.layout);
            const saved = await browser.storage.sync.get(i18n.LANGUAGE_STORAGE_KEY).catch(() => ({}));
            if (destroyed || epoch !== lifecycleEpoch) return false;
            if (revision === languageRevision) applyLanguage(saved?.[i18n.LANGUAGE_STORAGE_KEY]);
            await loadWorkbenchData();
            if (typeof options.getTaskTrashOperations === "function") {
              const reconciliation = await taskTrashCoordinator.reconcile(tasks);
              if (reconciliation.ok && reconciliation.results.some((item) => item.outcome !== "skipped")) {
                await loadWorkbenchData();
                await loadTrash({ quiet: true });
              }
            }
            return options.getRoot?.() ? update() : true;
          }
          function destroy() {
            if (destroyed) return false;
            destroyed = true;
            lifecycleEpoch += 1;
            languageRevision += 1;
            observationRefresh.destroy();
            if (languageListenerAttached) browser.storage?.onChanged?.removeListener?.(handleLanguageChange);
            languageListenerAttached = false;
            suggestionRuntime.destroy();
            dwellTracker.clear();
            taskDialog?.destroy();
            view?.destroy();
            const shadowRoot = options.getRoot?.();
            const panel = shadowRoot?.getElementById?.("panel");
            if (panel) panel.style.visibility = previousPanelVisibility;
            mountRoot?.remove?.();
            view = null;
            taskDialog = null;
            mountRoot = null;
            attachedShadowRoot = null;
            return true;
          }
          return Object.freeze({
            start,
            attach,
            update,
            destroy,
            loadTrash,
            refreshInbox,
            refreshTaskData,
            focusSearch: () => view?.focusSearch?.() || false,
            listTasks: () => tasks.map((task) => ({ ...task })),
            listInbox: () => inboxPages.map((page) => ({ ...page })),
            listTrash: () => trashItems.map((item) => ({ ...item }))
          });
        }
        return Object.freeze({ createV2WorkbenchRuntime });
      });
    }
  });

  // src/content/tab-actions.js
  var require_tab_actions = __commonJS({
    "src/content/tab-actions.js"(exports, module) {
      (function(root, factory) {
        const api = factory();
        const commonJs = typeof module === "object" && module.exports;
        if (commonJs) module.exports = api;
        if (typeof window === "object") window.TfaTabActions = api;
        else if (!commonJs) root.TfaTabActions = api;
      })(typeof globalThis !== "undefined" ? globalThis : exports, function() {
        "use strict";
        const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/;
        function suggestionId(value) {
          const normalized = String(value == null ? "" : value).trim();
          if (!normalized.startsWith("suggestion-") || !SAFE_ID.test(normalized)) {
            throw new TypeError("Invalid suggestionId");
          }
          return normalized;
        }
        function changeId(value) {
          const normalized = String(value == null ? "" : value).trim();
          if (!normalized.startsWith("change-") || !SAFE_ID.test(normalized)) throw new TypeError("Invalid changeId");
          return normalized;
        }
        function pageIds(value) {
          if (!Array.isArray(value)) throw new TypeError("pageIds must be an array");
          const seen = /* @__PURE__ */ new Set();
          return value.reduce((result, item) => {
            if (typeof item !== "string") throw new TypeError("pageIds must contain only page ids");
            const normalized = item.trim();
            if (!normalized.startsWith("page-") || !SAFE_ID.test(normalized)) {
              throw new TypeError("Invalid pageId");
            }
            if (!seen.has(normalized)) {
              seen.add(normalized);
              result.push(normalized);
            }
            return result;
          }, []);
        }
        function suggestionDecision(value) {
          if (value !== "accept" && value !== "reject") throw new TypeError("Invalid suggestion decision");
          return value;
        }
        function createTabActions(deps = {}) {
          const send = typeof deps.send === "function" ? deps.send : async () => ({ error: "unavailable" });
          let destroyed = false;
          const request = (message) => destroyed ? Promise.resolve({ error: "destroyed" }) : send(message);
          const api = {
            getAllTabs: () => request({ type: "GET_ALL_TABS" }),
            getAllScreenshots: () => request({ type: "GET_ALL_SCREENSHOTS" }),
            getHotBookmarks: () => request({ type: "GET_HOT_BOOKMARKS" }),
            getRecentlyClosed: () => request({ type: "GET_RECENTLY_CLOSED" }),
            consumeRecentlyClosedItem: (itemId, url) => request({ type: "CONSUME_RECENTLY_CLOSED_ITEM", itemId, url }),
            getTrash: (options = {}) => request(options.includeTasks === true ? { type: "GET_TRASH", includeTasks: true } : { type: "GET_TRASH" }),
            addTaskToTrash: (task, operationToken = "", options = {}) => request(options?.prepared === true ? { type: "ADD_TASK_TO_TRASH", task, operationToken, prepared: true } : operationToken ? { type: "ADD_TASK_TO_TRASH", task, operationKey: operationToken } : { type: "ADD_TASK_TO_TRASH", task }),
            updateTaskTrashOperation: (operationToken, phase, id) => request({
              type: "UPDATE_TASK_TRASH_OPERATION",
              operationToken,
              phase,
              ...id ? { id } : {}
            }),
            getTaskTrashOperations: () => request({ type: "GET_TASK_TRASH_OPERATIONS" }),
            clearTrash: () => request({ type: "CLEAR_TRASH" }),
            restoreTrashItem: (id, options = {}) => request(options.restoreBatchId ? { type: "RESTORE_TRASH_ITEM", id, restoreBatchId: String(options.restoreBatchId) } : { type: "RESTORE_TRASH_ITEM", id }),
            deleteTrashItem: (id, options = {}) => request(options.itemType ? { type: "DELETE_TRASH_ITEM", id, itemType: options.itemType } : { type: "DELETE_TRASH_ITEM", id }),
            closeGroup: (groupId) => request({ type: "CLOSE_GROUP", groupId }),
            addToGroup: (tabIds, groupId) => request({ type: "ADD_TO_GROUP", tabIds, groupId }),
            updateGroup: (groupId, title, color) => request({ type: "UPDATE_GROUP", groupId, title, color }),
            ungroupTabs: (tabIds) => request({ type: "UNGROUP_TABS", tabIds }),
            groupTabs: (tabIds, title, color) => request({ type: "GROUP_TABS", tabIds, title, color }),
            groupByDomain: (windowId) => request(Number.isInteger(Number(windowId)) ? { type: "GROUP_BY_DOMAIN", windowId: Number(windowId) } : { type: "GROUP_BY_DOMAIN" }),
            ungroupAll: (windowId) => request(Number.isInteger(Number(windowId)) ? { type: "UNGROUP_ALL", windowId: Number(windowId) } : { type: "UNGROUP_ALL" }),
            closeTabs: (tabIds) => request({ type: "CLOSE_TABS", tabIds }),
            pinTab: (tabId, pinned) => request({ type: "PIN_TAB", tabId, pinned }),
            duplicateTab: (tabId) => request({ type: "DUPLICATE_TAB", tabId }),
            switchTab: (tabId) => request({ type: "SWITCH_TAB", tabId }),
            moveTab: (tabId, index, windowId) => request({ type: "MOVE_TAB", tabId, index, windowId }),
            moveTabRelative: (tabId, target = {}) => request({
              type: "MOVE_TAB_RELATIVE",
              tabId,
              beforeTabId: target.beforeTabId ?? null,
              afterTabId: target.afterTabId ?? null,
              placement: target.placement || "relative",
              windowId: target.windowId,
              groupId: target.groupId
            }),
            toggleDockSite: (site) => request({ type: "DOCK_TOGGLE_SITE", site }),
            pinAsBookmark: (tabId) => request({ type: "PIN_AS_BOOKMARK", tabId }),
            newTab: (url, active = true) => request({ type: "NEW_TAB", url, active }),
            restoreSession: (sessionId) => request({ type: "RESTORE_SESSION", sessionId }),
            listTaskData: () => request({ type: "V2_TASK_LIST" }),
            listInboxPages: () => request({ type: "V2_INBOX_LIST" }),
            setInboxPreference: (action, pageId, url) => request({ type: "V2_INBOX_PREFERENCE_SET", action, pageId, url }),
            createTask: (task) => request({ type: "V2_TASK_CREATE", task }),
            updateTask: (taskId, patch) => request({ type: "V2_TASK_UPDATE", taskId, patch }),
            reorderTasks: (orderedTaskIds) => request({ type: "V2_TASK_REORDER", orderedTaskIds }),
            deleteTask: (taskId, replacementTaskIdsByPage = {}, operationToken = "") => request({
              type: "V2_TASK_DELETE",
              taskId,
              replacementTaskIdsByPage,
              ...operationToken ? { operationToken } : {}
            }),
            addTaskRelation: (taskId, page, options = {}) => request({ type: "V2_RELATION_ADD", taskId, page, ...options }),
            setPrimaryTaskRelation: (taskId, pageId) => request({ type: "V2_RELATION_ADD", taskId, pageId, isPrimary: true }),
            removeTaskRelation: (taskId, pageId, replacementTaskId = "") => request({ type: "V2_RELATION_REMOVE", taskId, pageId, ...replacementTaskId ? { replacementTaskId } : {} }),
            moveTaskRelation: (sourceTaskId, targetTaskId, pageId) => request({ type: "V2_RELATION_MOVE", sourceTaskId, targetTaskId, pageId }),
            reorderTaskRelations: (taskId, orderedPageIds) => request({ type: "V2_RELATION_REORDER", taskId, orderedPageIds }),
            restoreTaskData: (task, restoreToken = "") => request({ type: "V2_TASK_RESTORE", task, restoreToken }),
            undoLastTaskChange: () => request({ type: "V2_TASK_UNDO_LAST" }),
            clearTaskData: () => request({ type: "V2_TASK_DATA_CLEAR" }),
            refreshSuggestions: (ids) => request({ type: "V2_SUGGESTION_REFRESH", pageIds: pageIds(ids) }),
            listSuggestions: (ids) => request({ type: "V2_SUGGESTION_LIST", pageIds: pageIds(ids) }),
            organizeSuggestions: (ids, locale = "en") => request({
              type: "V2_SUGGESTION_ORGANIZE",
              pageIds: pageIds(ids),
              locale: locale === "zh-CN" ? "zh-CN" : "en"
            }),
            resolveSuggestion: (id, decision) => request({
              type: "V2_SUGGESTION_RESOLVE",
              suggestionId: suggestionId(id),
              decision: suggestionDecision(decision)
            }),
            undoSuggestion: (id) => request({ type: "V2_SUGGESTION_UNDO", suggestionId: suggestionId(id) }),
            undoAiPlan: (id) => request({ type: "V2_AI_PLAN_UNDO", changeId: changeId(id) })
          };
          function destroy() {
            if (destroyed) return false;
            destroyed = true;
            return true;
          }
          function inspect() {
            return { destroyed };
          }
          return Object.freeze({ ...api, destroy, inspect });
        }
        return { createTabActions };
      });
    }
  });

  // src/content/v2-task-api.js
  var require_v2_task_api = __commonJS({
    "src/content/v2-task-api.js"(exports, module) {
      (function attachV2TaskApi(root, factory) {
        const api = factory();
        const commonJs = typeof module === "object" && module.exports;
        if (commonJs) module.exports = api;
        if (typeof window === "object") window.TfaV2TaskApi = api;
        else if (!commonJs) root.TfaV2TaskApi = api;
      })(typeof globalThis !== "undefined" ? globalThis : exports, function createV2TaskApiModule() {
        "use strict";
        function createV2TaskApi(tabActions) {
          return Object.freeze({
            list: () => tabActions.listTaskData(),
            listInbox: () => tabActions.listInboxPages(),
            setInboxPreference: (action, pageId, url) => tabActions.setInboxPreference(action, pageId, url),
            createTask: (task) => tabActions.createTask(task),
            updateTask: (taskId, patch) => tabActions.updateTask(taskId, patch),
            reorderTasks: (orderedTaskIds) => tabActions.reorderTasks(orderedTaskIds),
            deleteTask: (taskId, replacements, operationToken) => tabActions.deleteTask(taskId, replacements, operationToken),
            addRelation: (taskId, page, relationOptions) => tabActions.addTaskRelation(taskId, page, relationOptions),
            setPrimaryRelation: (taskId, pageId) => tabActions.setPrimaryTaskRelation(taskId, pageId),
            removeRelation: (taskId, pageId, replacementTaskId) => tabActions.removeTaskRelation(taskId, pageId, replacementTaskId),
            moveRelation: (sourceTaskId, targetTaskId, pageId) => tabActions.moveTaskRelation(sourceTaskId, targetTaskId, pageId),
            reorderRelations: (taskId, orderedPageIds) => tabActions.reorderTaskRelations(taskId, orderedPageIds),
            restoreTask: (task, restoreToken) => tabActions.restoreTaskData(task, restoreToken),
            undoLast: () => tabActions.undoLastTaskChange(),
            clearData: () => tabActions.clearTaskData(),
            refreshSuggestions: (pageIds) => tabActions.refreshSuggestions(pageIds),
            listSuggestions: (pageIds) => tabActions.listSuggestions(pageIds),
            organizeSuggestions: (pageIds, locale) => tabActions.organizeSuggestions(pageIds, locale),
            resolveSuggestion: (suggestionId, decision) => tabActions.resolveSuggestion(suggestionId, decision),
            undoSuggestion: (suggestionId) => tabActions.undoSuggestion(suggestionId),
            undoAiPlan: (changeId) => tabActions.undoAiPlan(changeId)
          });
        }
        return Object.freeze({ createV2TaskApi });
      });
    }
  });

  // src/content/content-feature-shared-shell.js
  var require_content_feature_shared_shell = __commonJS({
    "src/content/content-feature-shared-shell.js"(exports, module) {
      (function attachContentFeatureSharedShell(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaContentFeatureSharedShell = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createContentFeatureSharedShellModule() {
        "use strict";
        const FEATURE_NAMES = Object.freeze(["web_dock", "workspace"]);
        const WORKSPACE_PORTS = Object.freeze([
          "overlayVisible",
          "pauseOverlaySession",
          "resumeOverlaySession",
          "renderTabs",
          "updateCount",
          "closeAllMenus"
        ]);
        function createContentFeatureSharedShell(options = {}) {
          const documentRef = options.document;
          const buildHost = options.buildHost;
          const current = typeof options.current === "function" ? options.current : () => true;
          if (!documentRef || typeof buildHost !== "function") {
            throw new Error("shared shell requires document and buildHost");
          }
          const references = /* @__PURE__ */ new Map();
          let context = null;
          let workspacePorts = null;
          let destroyed = false;
          function validFeature(name) {
            return FEATURE_NAMES.includes(String(name || ""));
          }
          function connected(candidate = context) {
            return Boolean(candidate?.host && candidate.host.isConnected !== false);
          }
          function normalizeContext(candidate) {
            if (!candidate?.host || !candidate.root || !candidate.els || typeof candidate.els !== "object") {
              throw new Error("buildHost must return host, root, and els");
            }
            return { host: candidate.host, root: candidate.root, els: candidate.els };
          }
          function removeHost(candidate = context) {
            const host = candidate?.host;
            if (!host) return;
            try {
              if (typeof host.remove === "function") host.remove();
              else host.parentNode?.removeChild?.(host);
            } catch (_error) {
            }
          }
          function ensure() {
            if (destroyed || current() === false) return null;
            if (connected()) return context;
            const previous = context;
            const next = normalizeContext(buildHost({ document: documentRef, previous }));
            context = next;
            if (previous && previous.host !== next.host) removeHost(previous);
            return context;
          }
          function recover() {
            return connected() ? context : ensure();
          }
          function retainFeature(name) {
            const feature = String(name || "");
            if (destroyed || !validFeature(feature)) return null;
            references.set(feature, (references.get(feature) || 0) + 1);
            try {
              return ensure();
            } catch (error) {
              releaseFeature(feature);
              throw error;
            }
          }
          function releaseFeature(name) {
            const feature = String(name || "");
            const count = references.get(feature) || 0;
            if (!count) return false;
            if (count > 1) references.set(feature, count - 1);
            else references.delete(feature);
            if (references.size === 0) {
              removeHost();
              context = null;
            }
            return true;
          }
          function attachWorkspacePorts(ports = {}) {
            if (destroyed || !ports || typeof ports !== "object") return () => false;
            const record = Object.fromEntries(WORKSPACE_PORTS.map((name) => [
              name,
              typeof ports[name] === "function" ? ports[name] : null
            ]));
            workspacePorts = record;
            let attached = true;
            return () => {
              if (!attached || workspacePorts !== record) return false;
              attached = false;
              workspacePorts = null;
              return true;
            };
          }
          function callWorkspacePort(name, ...args) {
            const port = workspacePorts && workspacePorts[name];
            return typeof port === "function" ? port(...args) : void 0;
          }
          const workspaceBridge = Object.freeze({
            overlayVisible: () => Boolean(callWorkspacePort("overlayVisible")),
            pauseOverlaySession: () => callWorkspacePort("pauseOverlaySession"),
            resumeOverlaySession: () => callWorkspacePort("resumeOverlaySession"),
            renderTabs: () => callWorkspacePort("renderTabs"),
            updateCount: () => callWorkspacePort("updateCount"),
            closeAllMenus: () => callWorkspacePort("closeAllMenus")
          });
          function getContext() {
            return context ? { host: context.host, root: context.root, els: context.els } : null;
          }
          function inspect() {
            return {
              destroyed,
              connected: connected(),
              features: Object.fromEntries(references),
              workspaceAttached: Boolean(workspacePorts)
            };
          }
          function attachToOwner(owner) {
            if (destroyed || !owner || owner.featureHost !== true) return false;
            if (owner.sharedShell && owner.sharedShell !== api) return false;
            owner.sharedShell = api;
            return true;
          }
          function destroy() {
            if (destroyed) return false;
            destroyed = true;
            references.clear();
            workspacePorts = null;
            removeHost();
            context = null;
            return true;
          }
          const api = Object.freeze({
            ensure,
            recover,
            retainFeature,
            releaseFeature,
            attachWorkspacePorts,
            workspaceBridge,
            getContext,
            attachToOwner,
            inspect,
            destroy
          });
          return api;
        }
        return Object.freeze({ FEATURE_NAMES, WORKSPACE_PORTS, createContentFeatureSharedShell });
      });
    }
  });

  // src/content/workspace-feature-initializer.js
  var require_workspace_feature_initializer = __commonJS({
    "src/content/workspace-feature-initializer.js"(exports, module) {
      (function attachWorkspaceFeatureInitializer(root, factory) {
        const api = factory();
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaWorkspaceFeatureInitializer = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createWorkspaceFeatureInitializerModule() {
        "use strict";
        const SHARED_SHELL_IDS = Object.freeze([
          "overlay",
          "panel",
          "toastContainer",
          "webDockShell",
          "webDockTrigger",
          "webDockTrack",
          "webDockAdd",
          "webDockSearch",
          "webDockSettings",
          "webDockRecent",
          "webDockRecentPanel",
          "webDockRecentStatus",
          "webDockRecentList",
          "webDockRecentCount",
          "btnSettings",
          "btnMember",
          "body"
        ]);
        function createWorkspaceFeatureInitializer(options = {}) {
          const windowRef = options.window, documentRef = options.document, chromeApi = options.chrome;
          const identity = options.identity || {}, owner = options.owner;
          const overlayTemplate = options.overlayTemplate, shellModule = options.sharedShellModule;
          const v2Module = options.v2WorkbenchRuntime, taskApiModule = options.taskApiModule;
          const tabActionsModule = options.tabActionsModule;
          if (!windowRef || !documentRef || !chromeApi || !owner?.featureHost || !overlayTemplate?.buildOverlay || !shellModule?.createContentFeatureSharedShell || !v2Module?.createV2WorkbenchRuntime || !taskApiModule?.createV2TaskApi || !tabActionsModule?.createTabActions) {
            throw new Error("workspace initializer dependencies unavailable");
          }
          const fingerprint = String(identity.fingerprint || `legacy:${identity.version || "unknown"}`);
          if (String(owner.fingerprint || "") !== fingerprint) throw new Error("workspace owner fingerprint mismatch");
          const hostId = `tfa-host-${chromeApi.runtime?.id || "extension"}`;
          let tabs = [], retained = false, destroyed = false, visible = false, sticky = false, startPromise = null, runtime = null, detachWorkspacePorts = null;
          let dockConfig = { enabled: false, sites: [] }, theme = "light", themePreference = "system";
          let themeRevision = 0, themeEpoch = 0;
          let pendingInitialIntent = null, shortcutPressedAt = null, shortcutHoldThreshold = 2e3;
          let earlyRevealedIntentType = "";
          let themeListenersAttached = false;
          let lastTaskChangeToken = "", lastTaskChangeEpoch = 0;
          let taskRefreshPending = false, taskRefreshWork = null;
          const previews = /* @__PURE__ */ new Map();
          const previewRequests = /* @__PURE__ */ new Map();
          let previewRequestEpoch = 0;
          const fetchFn = options.fetch || globalThis.fetch;
          const send = (message) => new Promise((resolve) => {
            try {
              chromeApi.runtime.sendMessage(message, (response) => resolve(response || {}));
            } catch (error) {
              resolve({ ok: false, error: error?.message || "send failed" });
            }
          });
          function scheduleTaskRefresh(epoch = 0) {
            lastTaskChangeEpoch = Math.max(lastTaskChangeEpoch, Number(epoch) || 0);
            taskRefreshPending = true;
            if (taskRefreshWork || !runtime?.refreshTaskData) return taskRefreshWork;
            taskRefreshWork = (async () => {
              await Promise.resolve();
              while (taskRefreshPending && !destroyed) {
                taskRefreshPending = false;
                await runtime.refreshTaskData();
              }
            })().catch(() => false).finally(() => {
              taskRefreshWork = null;
            });
            return taskRefreshWork;
          }
          function onTaskDataChanged(message, _sender, sendResponse) {
            if (message?.type !== "V2_TASK_DATA_CHANGED" || destroyed) return false;
            const token = String(message.token || "");
            const epoch = Number(message.epoch ?? message.revision) || 0;
            if (token && token === lastTaskChangeToken || epoch && epoch <= lastTaskChangeEpoch) {
              sendResponse?.({ ok: true, duplicate: true, epoch: lastTaskChangeEpoch });
              return false;
            }
            if (token) lastTaskChangeToken = token;
            void scheduleTaskRefresh(epoch);
            sendResponse?.({ ok: true, refreshed: Boolean(runtime?.refreshTaskData), epoch });
            return false;
          }
          chromeApi.runtime.onMessage?.addListener?.(onTaskDataChanged);
          const tabActions = tabActionsModule.createTabActions({ send });
          const requestFeature = options.requestFeature || owner.featureHostApi?.requestFeature || ((name, intent) => send({ type: "TFA_LOAD_CONTENT_FEATURE", feature: name, intent }));
          const comparableUrl = (value) => {
            try {
              const url = new URL(String(value || ""));
              url.hash = "";
              return url.href;
            } catch (_error) {
              return String(value || "").trim();
            }
          };
          const isDockSiteFixed = (url) => new Set((dockConfig.sites || []).map((site) => comparableUrl(site.url))).has(comparableUrl(url));
          const colorScheme = windowRef.matchMedia?.("(prefers-color-scheme: dark)") || null;
          function normalizeThemePreference(value) {
            const normalized = String(value || "").trim().toLowerCase();
            if (["system", "light", "dark"].includes(normalized)) return { value: normalized, migrated: false };
            if (["snow", "paper", "pro"].includes(normalized)) return { value: "light", migrated: true };
            if (["noir", "ocean", "space", "crypto"].includes(normalized)) return { value: "dark", migrated: true };
            return { value: "system", migrated: false };
          }
          function applyTheme(next = themePreference) {
            themePreference = normalizeThemePreference(next).value;
            theme = themePreference === "system" ? colorScheme?.matches ? "dark" : "light" : themePreference;
            const context = shell.getContext();
            if (context?.host && !context.root?.getElementById?.("tfa-theme-override")) {
              context.host.dataset.theme = theme;
              context.host.dataset.themePreference = themePreference;
            }
            runtime?.update();
            return theme;
          }
          async function loadPreferences() {
            const epoch = themeEpoch, revision = themeRevision;
            try {
              const stored = await chromeApi.storage.sync.get(["tfa_theme", "tfa_web_dock"]);
              if (destroyed || epoch !== themeEpoch) return;
              dockConfig = stored.tfa_web_dock || dockConfig;
              if (revision !== themeRevision) return;
              const normalized = normalizeThemePreference(stored.tfa_theme);
              applyTheme(normalized.value);
              if (normalized.migrated && !destroyed && epoch === themeEpoch && revision === themeRevision) await chromeApi.storage.sync.set({ tfa_theme: normalized.value });
            } catch (_error) {
            }
          }
          async function toggleTheme() {
            const next = theme === "dark" ? "light" : "dark";
            themeRevision += 1;
            applyTheme(next);
            try {
              await chromeApi.storage.sync.set({ tfa_theme: next });
            } catch (_error) {
            }
            return true;
          }
          function onThemeStorageChange(changes, area) {
            if (area === "sync" && changes?.tfa_theme) {
              themeRevision += 1;
              applyTheme(changes.tfa_theme.newValue);
            }
          }
          function onColorSchemeChange() {
            if (themePreference === "system") applyTheme("system");
          }
          function attachThemeListeners() {
            if (themeListenersAttached) return;
            chromeApi.storage.onChanged?.addListener?.(onThemeStorageChange);
            colorScheme?.addEventListener?.("change", onColorSchemeChange);
            if (!colorScheme?.addEventListener) colorScheme?.addListener?.(onColorSchemeChange);
            themeListenersAttached = true;
          }
          function detachThemeListeners() {
            if (!themeListenersAttached) return;
            chromeApi.storage.onChanged?.removeListener?.(onThemeStorageChange);
            colorScheme?.removeEventListener?.("change", onColorSchemeChange);
            if (!colorScheme?.removeEventListener) colorScheme?.removeListener?.(onColorSchemeChange);
            themeListenersAttached = false;
          }
          async function toggleDockSite(tab) {
            return requestFeature("web_dock", { type: "toggle-site", site: tab });
          }
          const safePreviewSource = (value) => /^data:image\/[a-z0-9.+-]+;base64,/i.test(String(value || "")) ? String(value) : "";
          const previewUrlFor = (tabId) => String(tabs.find((tab) => Number(tab.id) === Number(tabId))?.url || "");
          const waitForPreview = (milliseconds) => new Promise((resolve) => (options.setTimeout || windowRef.setTimeout || setTimeout)(resolve, milliseconds));
          function readPreview(tabId) {
            const id = Number(tabId), cached = previews.get(id), currentUrl = previewUrlFor(id);
            if (!cached || !currentUrl || cached.url && cached.url !== currentUrl) {
              if (cached) previews.delete(id);
              return "";
            }
            return cached.src;
          }
          function rememberPreview(tabId, source, url = "") {
            const id = Number(tabId), safe = safePreviewSource(source), currentUrl = previewUrlFor(id);
            const exactUrl = String(url || currentUrl || "");
            if (!Number.isInteger(id) || !safe || !currentUrl || exactUrl && exactUrl !== currentUrl) return "";
            previews.set(id, { src: safe, url: currentUrl });
            return safe;
          }
          function reconcilePreviews() {
            for (const [tabId, cached] of previews) {
              const currentUrl = previewUrlFor(tabId);
              if (!currentUrl || cached.url && cached.url !== currentUrl) previews.delete(tabId);
            }
          }
          function seedPreviews(entries = {}, urls = {}) {
            for (const [tabId, source] of Object.entries(entries || {})) {
              rememberPreview(Number(tabId), source, urls?.[tabId] || previewUrlFor(tabId));
            }
          }
          async function warmPreviewCache() {
            const epoch = previewRequestEpoch;
            const [all, current] = await Promise.all([
              send({ type: "GET_ALL_SCREENSHOTS" }),
              send({ type: "CAPTURE_CURRENT_TAB" })
            ]);
            if (destroyed || epoch !== previewRequestEpoch) return false;
            seedPreviews(all?.screenshots, all?.previewUrls);
            rememberPreview(current?.tabId, current?.screenshot, current?.url);
            return true;
          }
          async function requestTabPreview(tabId) {
            const id = Number(tabId), cached = readPreview(id);
            if (cached) return cached;
            if (!Number.isInteger(id) || !previewUrlFor(id)) return "";
            if (previewRequests.has(id)) return previewRequests.get(id);
            const epoch = previewRequestEpoch, expectedUrl = previewUrlFor(id);
            const operation = (async () => {
              for (const delayMs of [0, 180, 420]) {
                if (delayMs) await waitForPreview(delayMs);
                if (destroyed || epoch !== previewRequestEpoch || previewUrlFor(id) !== expectedUrl) return "";
                const response = await send({ type: "GET_TAB_PREVIEW", tabId: id });
                if (destroyed || epoch !== previewRequestEpoch || previewUrlFor(id) !== expectedUrl) return "";
                const responseUrl = String(response?.url || expectedUrl);
                const source = response?.preview?.screenshot || response?.preview?.src || "";
                const safe = rememberPreview(id, source, responseUrl);
                if (safe) return safe;
                if (response?.preview?.unavailableReason === "restricted") return "";
              }
              return "";
            })().finally(() => {
              if (previewRequests.get(id) === operation) previewRequests.delete(id);
            });
            previewRequests.set(id, operation);
            return operation;
          }
          function openSettings(trigger) {
            return requestFeature("web_dock", { type: "open-settings", section: trigger?.section || "activation" });
          }
          function buildHost({ previous }) {
            const reusable = previous?.host?.isConnected !== false && previous?.root?.getElementById?.("overlay");
            if (reusable) return previous;
            const existing = documentRef.getElementById?.(hostId);
            existing?.remove?.();
            const host = documentRef.createElement("div");
            host.id = hostId;
            host.setAttribute("data-tfa-host", "true");
            host.setAttribute("data-tfa-owner", chromeApi.runtime?.id || "extension");
            host.setAttribute("data-tfa-instance", owner.instanceId);
            host.style.cssText = "all:initial;position:fixed;inset:0;z-index:2147483647;pointer-events:none;";
            if (owner.surfaceMode === "newtab") host.setAttribute("data-tfa-surface", "newtab");
            const root = host.attachShadow({ mode: "open" });
            overlayTemplate.buildOverlay({ root, version: identity.version });
            documentRef.documentElement.appendChild(host);
            return {
              host,
              root,
              els: Object.fromEntries(SHARED_SHELL_IDS.map((id) => [id, root.getElementById(id)]))
            };
          }
          const shell = owner.sharedShell || shellModule.createContentFeatureSharedShell({
            document: documentRef,
            buildHost,
            current: () => !destroyed && windowRef.__TFA_OWNER__ === owner
          });
          if (!owner.sharedShell && !shell.attachToOwner(owner)) throw new Error("workspace shared shell owner conflict");
          async function ensureStyles(context) {
            if (context.root.getElementById?.("tfa-full-styles")) return true;
            try {
              const response = await fetchFn(chromeApi.runtime.getURL("styles.css"));
              const css = response.ok ? await response.text() : "";
              if (!css || destroyed) return false;
              const style = documentRef.createElement("style");
              style.id = "tfa-full-styles";
              style.textContent = css;
              context.root.prepend(style);
              return true;
            } catch (_error) {
              return false;
            }
          }
          function setVisible(next, nextSticky = next) {
            const context = shell.getContext();
            if (!context?.els?.overlay) return false;
            const anchoredNewTab = owner.surfaceMode === "newtab";
            visible = anchoredNewTab || next === true;
            owner.workspaceVisible = visible;
            sticky = visible && nextSticky === true;
            context.els.overlay.hidden = !visible;
            context.els.overlay.inert = !visible;
            context.els.overlay.setAttribute("aria-hidden", String(!visible));
            context.els.overlay.classList.toggle("show", visible);
            context.els.overlay.classList.toggle("sticky-mode", sticky);
            context.host.style.pointerEvents = visible ? "auto" : "none";
            return true;
          }
          async function revealWithFade(nextSticky = true) {
            if (!setVisible(true, nextSticky)) return false;
            const context = shell.getContext();
            const overlay = context?.els?.overlay;
            if (!overlay) return false;
            overlay.classList.remove("show");
            await new Promise((resolve) => {
              const requestFrame = typeof windowRef.requestAnimationFrame === "function" ? windowRef.requestAnimationFrame.bind(windowRef) : (callback) => setTimeout(callback, 0);
              requestFrame(resolve);
            });
            if (!destroyed && visible) overlay.classList.add("show");
            return true;
          }
          async function refreshTabs() {
            const response = await tabActions.getAllTabs();
            if (response && !response.error) tabs = Array.isArray(response.tabs) ? response.tabs : [];
            reconcilePreviews();
            runtime?.update();
            return tabs;
          }
          async function activateRealTab(tabId) {
            const result = await tabActions.switchTab(tabId);
            if (result === false || result?.ok === false || result?.error) return result;
            if (owner.surfaceMode !== "newtab") setVisible(false, false);
            return result;
          }
          async function initialize() {
            try {
              const context = shell.retainFeature("workspace");
              if (!context) return false;
              retained = true;
              attachThemeListeners();
              await ensureStyles(context);
              await loadPreferences();
              if (destroyed) return false;
              const pendingType = String(pendingInitialIntent?.type || "");
              if (pendingType === "active-guidance-open") {
                await revealWithFade(true);
                earlyRevealedIntentType = pendingType;
              } else if (pendingType === "shortcut-press") {
                setVisible(true, false);
                earlyRevealedIntentType = pendingType;
              } else if (["toggle-command", "middle-click", "toggle-shortcut", "newtab-open"].includes(pendingType)) {
                setVisible(true, true);
                earlyRevealedIntentType = pendingType;
              }
              await refreshTabs();
              const previewWarmOperation = warmPreviewCache();
              runtime = v2Module.createV2WorkbenchRuntime({
                chrome: chromeApi,
                document: documentRef,
                window: windowRef,
                taskApi: taskApiModule.createV2TaskApi(tabActions),
                suggestionViewLogic: options.suggestionViewLogic,
                suggestionControllerModule: options.suggestionControllerModule,
                getRoot: () => shell.getContext()?.root || null,
                getTheme: () => theme,
                getTabs: () => tabs,
                getTabPreview: (tabId) => readPreview(tabId),
                requestTabPreview,
                activateTab: activateRealTab,
                closeTab: (tabId) => tabActions.closeTabs([tabId]),
                closeTabs: (tabIds) => tabActions.closeTabs(tabIds),
                closeGroup: (groupId) => tabActions.closeGroup(groupId),
                groupTabs: (tabIds, title, color) => tabActions.groupTabs(tabIds, title, color),
                moveTab: (tabId, index, windowId) => tabActions.moveTab(tabId, index, windowId),
                moveTabRelative: (tabId, target) => tabActions.moveTabRelative(tabId, target),
                addToGroup: (tabIds, groupId) => tabActions.addToGroup(tabIds, groupId),
                groupByDomain: (windowId) => tabActions.groupByDomain(windowId),
                ungroupAll: (windowId) => tabActions.ungroupAll(windowId),
                activateGroupFirst: (groupId) => {
                  const tab = tabs.filter((item) => item.groupId === groupId).sort((a, b) => a.index - b.index)[0];
                  return tab ? activateRealTab(tab.id) : false;
                },
                ungroupGroup: (groupId) => tabActions.ungroupTabs(tabs.filter((item) => item.groupId === groupId).map((item) => item.id)),
                ungroupTabs: (tabIds) => tabActions.ungroupTabs(tabIds),
                updateGroup: (groupId, title, color) => tabActions.updateGroup(groupId, title, color),
                openTab: (url, active) => tabActions.newTab(url, active),
                isDockSiteFixed,
                toggleDockSite,
                getTrash: () => tabActions.getTrash({ includeTasks: true }),
                restoreTrashItem: (id) => tabActions.restoreTrashItem(id),
                deleteTrashItem: (id, value) => tabActions.deleteTrashItem(id, value),
                addTaskToTrash: (...args) => tabActions.addTaskToTrash(...args),
                updateTaskTrashOperation: (...args) => tabActions.updateTaskTrashOperation(...args),
                getTaskTrashOperations: () => tabActions.getTaskTrashOperations(),
                refresh: refreshTabs,
                close: () => setVisible(false),
                toggleTheme,
                openSettings
              });
              await Promise.all([runtime.start(), previewWarmOperation]);
              detachWorkspacePorts = shell.attachWorkspacePorts({ overlayVisible: () => visible, renderTabs: () => runtime?.update(), updateCount: () => {
              }, closeAllMenus: () => {
              } });
              return true;
            } catch (error) {
              detachThemeListeners();
              detachWorkspacePorts?.();
              detachWorkspacePorts = null;
              runtime?.destroy?.();
              runtime = null;
              if (retained) shell.releaseFeature("workspace");
              retained = false;
              throw error;
            }
          }
          async function applyIntent(intent = {}, options2 = {}) {
            const type = String(intent.type || "");
            if (type === "newtab-open") {
              setVisible(true, true);
              await refreshTabs();
              return true;
            }
            if (type === "active-guidance-open") {
              if (options2.alreadyRevealed !== true) await revealWithFade(true);
              else setVisible(true, true);
              await refreshTabs();
              if (options2.previewAlreadyWarm !== true) await warmPreviewCache();
              runtime?.update();
              return true;
            }
            if (type === "tab-hidden") {
              setVisible(false, true);
              return true;
            }
            if (["toggle-command", "middle-click", "toggle-shortcut"].includes(type)) {
              const shouldShow = options2.alreadyRevealed === true ? true : !visible;
              setVisible(shouldShow, shouldShow);
              if (visible) {
                await refreshTabs();
                if (options2.previewAlreadyWarm !== true) await warmPreviewCache();
                runtime?.update();
              }
              return true;
            }
            if (type === "shortcut-press") {
              shortcutPressedAt = Number(intent.pressedAt) || Date.now();
              shortcutHoldThreshold = Math.max(0, Number(intent.holdThreshold) || 2e3);
              setVisible(true, false);
              await refreshTabs();
              if (options2.previewAlreadyWarm !== true) await warmPreviewCache();
              runtime?.update();
              return true;
            }
            if (type === "shortcut-release" && shortcutPressedAt != null) {
              const held = Math.max(0, (Number(intent.releasedAt) || Date.now()) - shortcutPressedAt);
              shortcutPressedAt = null;
              setVisible(held >= shortcutHoldThreshold, true);
              return true;
            }
            return true;
          }
          async function start(intent = {}) {
            if (destroyed) return false;
            if (runtime) return applyIntent(intent);
            const launching = !startPromise;
            if (!runtime) pendingInitialIntent = intent;
            if (launching) startPromise = initialize().catch((error) => {
              startPromise = null;
              pendingInitialIntent = null;
              throw error;
            });
            if (!await startPromise) return false;
            if (!launching) return runtime ? true : false;
            const effective = pendingInitialIntent;
            pendingInitialIntent = null;
            const effectiveType = String(effective?.type || "");
            const alreadyRevealed = Boolean(effectiveType && effectiveType === earlyRevealedIntentType);
            earlyRevealedIntentType = "";
            return applyIntent(effective, { previewAlreadyWarm: true, alreadyRevealed });
          }
          function destroy() {
            if (destroyed) return false;
            destroyed = true;
            visible = false;
            owner.workspaceVisible = false;
            previewRequestEpoch += 1;
            themeEpoch += 1;
            themeRevision += 1;
            chromeApi.runtime.onMessage?.removeListener?.(onTaskDataChanged);
            detachThemeListeners();
            detachWorkspacePorts?.();
            runtime?.destroy();
            tabActions.destroy?.();
            previews.clear();
            previewRequests.clear();
            if (retained) shell.releaseFeature("workspace");
            retained = false;
            return true;
          }
          return Object.freeze({ start, destroy, inspect: () => ({ destroyed, visible, sticky, retained, started: Boolean(runtime) }) });
        }
        return Object.freeze({ createWorkspaceFeatureInitializer });
      });
    }
  });

  // src/content/content-feature-registration.js
  var require_content_feature_registration = __commonJS({
    "src/content/content-feature-registration.js"(exports, module) {
      (function attachContentFeatureRegistration(root, factory) {
        const api = factory(root);
        if (typeof module === "object" && module.exports) module.exports = api;
        root.TfaContentFeatureRegistration = api;
      })(typeof globalThis === "object" ? globalThis : exports, function createContentFeatureRegistrationModule(root) {
        "use strict";
        function registerFeature(name, options = {}) {
          const identity = options.identity || root.TfaBuildIdentity || {};
          const host = options.host || root.__TFA_FEATURE_HOST__;
          const initializers = options.initializers || root.TfaContentFeatureInitializers;
          const initializer = initializers?.[name];
          if (!host?.registerFeature || !initializer?.start || !initializer?.destroy) return false;
          return host.registerFeature({
            name,
            fingerprint: String(identity.fingerprint || `legacy:${identity.version || "unknown"}`),
            start: (intent) => initializer.start(intent),
            destroy: () => initializer.destroy()
          });
        }
        return Object.freeze({ registerFeature });
      });
    }
  });

  // src/content/workspace-entry.js
  var require_workspace_entry = __commonJS({
    "src/content/workspace-entry.js"() {
      var import_version = __toESM(require_version());
      var import_browser_adapter = __toESM(require_browser_adapter());
      var import_i18n = __toESM(require_i18n());
      var import_v2_native_tab_group_model = __toESM(require_v2_native_tab_group_model());
      var import_v2_tab_awareness_logic = __toESM(require_v2_tab_awareness_logic());
      var import_v2_workbench_logic = __toESM(require_v2_workbench_logic());
      var import_v2_suggestion_view_logic = __toESM(require_v2_suggestion_view_logic());
      var import_overlay_template = __toESM(require_overlay_template());
      var import_v2_workbench_template = __toESM(require_v2_workbench_template());
      var import_v2_workbench_layout_preferences = __toESM(require_v2_workbench_layout_preferences());
      var import_v2_workbench_resizer = __toESM(require_v2_workbench_resizer());
      var import_v2_workbench_menu = __toESM(require_v2_workbench_menu());
      var import_v2_task_relation_menu = __toESM(require_v2_task_relation_menu());
      var import_v2_task_dialog = __toESM(require_v2_task_dialog());
      var import_v2_task_trash_coordinator = __toESM(require_v2_task_trash_coordinator());
      var import_v2_suggestion_controller = __toESM(require_v2_suggestion_controller());
      var import_v2_workbench_focus_runtime = __toESM(require_v2_workbench_focus_runtime());
      var import_v2_native_tab_group_view = __toESM(require_v2_native_tab_group_view());
      var import_v2_tab_awareness_view = __toESM(require_v2_tab_awareness_view());
      var import_v2_browser_tab_sort = __toESM(require_v2_browser_tab_sort());
      var import_v2_overflow_controls = __toESM(require_v2_overflow_controls());
      var import_v2_native_tab_command_runtime = __toESM(require_v2_native_tab_command_runtime());
      var import_v2_ai_adjustment_view = __toESM(require_v2_ai_adjustment_view());
      var import_v2_experimental_task_views = __toESM(require_v2_experimental_task_views());
      var import_v2_workbench_renderer = __toESM(require_v2_workbench_renderer());
      var import_v2_workbench_view = __toESM(require_v2_workbench_view());
      var import_v2_workbench_suggestion_runtime = __toESM(require_v2_workbench_suggestion_runtime());
      var import_v2_inbox_observation_refresh = __toESM(require_v2_inbox_observation_refresh());
      var import_v2_workbench_runtime = __toESM(require_v2_workbench_runtime());
      var import_tab_actions = __toESM(require_tab_actions());
      var import_v2_task_api = __toESM(require_v2_task_api());
      var import_content_feature_shared_shell = __toESM(require_content_feature_shared_shell());
      var import_workspace_feature_initializer = __toESM(require_workspace_feature_initializer());
      var import_content_feature_registration = __toESM(require_content_feature_registration());
      var owner = globalThis.__TFA_OWNER__;
      if (owner?.featureHost === true) {
        const initializers = globalThis.TfaContentFeatureInitializers || (globalThis.TfaContentFeatureInitializers = {});
        initializers.workspace = globalThis.TfaWorkspaceFeatureInitializer.createWorkspaceFeatureInitializer({
          window,
          document,
          chrome,
          owner,
          identity: globalThis.TfaBuildIdentity,
          overlayTemplate: globalThis.TfaOverlayTemplate,
          sharedShellModule: globalThis.TfaContentFeatureSharedShell,
          v2WorkbenchRuntime: globalThis.TfaV2WorkbenchRuntime,
          taskApiModule: globalThis.TfaV2TaskApi,
          tabActionsModule: globalThis.TfaTabActions,
          suggestionViewLogic: globalThis.TfaV2SuggestionViewLogic,
          suggestionControllerModule: globalThis.TfaV2SuggestionController,
          requestFeature: (name, intent) => globalThis.__TFA_FEATURE_HOST__.requestFeature(name, intent)
        });
      }
      globalThis.TfaContentFeatureRegistration.registerFeature("workspace");
    }
  });
  require_workspace_entry();
})();
